把安裝和使用的部份"引用"一下....
到時候,也來裝一下...安裝方法很簡單,把下載的plugin放進「~/.vim/plugin/」。想要打開旁邊的小視窗,只要下「:TlistToggle」就行了。
或著你可以把下面兩行放進 「~/.vimrc」
nnoremap <> <> :TlistToggle<>
nnoremap <> <> :wincmd p<>vim在開檔的時候就會自動載入兩者,只要按F12就可以打開/關閉 taglist,按下F9就可以在兩個視窗之間跳動。
奇怪的是chip對Video,OSD和PIP都只有各一個對應的scaler,幹嘛不直接用Surface來帶替ModuleID。還要轉一次..
但是在修改前,要先down eth0。
ifconfig eth0 hw ether 00:21:23:34:04:05
2/4Mbit Flash ROM
North bridge : Marvel MV64420-BDM1C133
PC2700 SODIMM slot,
Support DDR 266 module, 128MB/256MB/512/MB,
512 MB total memory capacity.
Front Side
Auto-sensing dual voltage support, AC100-240V
45W, 2Pin, DC 12V, 5A
180 X 145 X 37mm
0.65kg
3C, CB, CE, FCC, TUV, UL, BSMI
一些歐美硬體愛好者在論壇對CeBIT參展的Municator討論代表了國人同樣的疑問:這個問題。.... 大概在中國,只要加上"民族情感"東西,都能賣得很好吧?
“我現在花費179美元就可以購買一套基於AMD的系統,為什麼要買149美元的Municator?”——龍芯架構和Linux作業系統的相對封閉性,都是大眾消費者所顧慮的。
每次都rebuild有點蠢,應該要看看是否有depency...
toolchain :
CCACHE_TARGET = ccache/ccache
BINUTILS_TARGET = bin/ld
GCC_TARGET = bin/arm-elf-gcc
UCLIBC_TARGET = libc.a,crt0.o, crt1.o, crti.o, crtn.o, gcrt1.o, libcrypt.a, libm.a, libnsl.a, libpthread.a, libthread.a, libresolv.a, libutil.a.
STLPORT_TARGET = libstdc++.a , .header_installed
BOOTPARM_TARGET = bin/bootparm
GENROMFS_TARGET = bin/genromfs
GENEXT2FS_TARGET = bin/genext2fs
GDB_TARGET = bin/arm-elf-gdb
CC=$(HOSTCC) CC_FOR_HOST=$(HOSTCC) CXX_FOR_HOST=$(HOSTCC) $(CCACHE_SRC_DIR)/configure --host=$(GNU_HOST_NAME) --prefix=$(STAGING_DIR) --exec-prefix=$(STAGING_DIR) -v;).然後建link :
$(MAKE) -C $(CCACHE_DIR) all
mkdir -p $(@D)ccache好像是能減少build的時間,ref Debian Wiki的說明:
mkdir -p $(CCACHE_DIR)
cp -f $< $@ ln -sf ccache $(@D)/$(TARGET)-gcc ln -sf ccache $(@D)/$(TARGET)-g++ ln -sf ccache $(@D)/gcc ln -sf ccache $(@D)/g++ ln -sf ccache $(@D)/cc
arm-elf-gcc:
ccache 會 cache C/C++ compiler pre-processor 的輸出, 在編譯時自動判斷是否要重新編譯。如果原始碼沒有很好的 make dependency, 導致您每次都要用類似make clean; make的方式重新編譯整個 source tree 的話, ccache 能大幅縮短編譯所需的時間。
$(MAKE) -C $(GCC_BUILD_DIR) -w install-gcc LANGUAGES="$(TARGET_LANGUAGES)"...所以重點在gcc的Makefile..和spec.path.
rm -rf $(TARGET_DIR)/info $(TARGET_DIR)/man $(TARGET_DIR)/share/doc $(TARGET_DIR)/share/locale
# patch gcc spec file
$(SOURCE_DIR)/patch-kernel.sh $(TARGET_DIR)/lib $(SOURCE_DIR) post-gcc-2.95.3-spec.patch
mv $(TARGET_DIR)/bin/cpp $(TARGET_DIR)/bin/$(TARGET_CROSS)cpp
spec的command只有三種: include,include_noerr, rename。%command : 執行command
*spec_name : 建立,刪除,修改 spec_name指定的spec字串
suffix :建立/修改suffix 規則
CC=$(HOSTCC) $(GCC_DIR)/configure --target=$(GNU_TARGET_NAME) --host=$(GNU_HOST_NAME) --build=$(GNU_HOST_NAME) --prefix=$(STAGING_DIR) --exec-prefix=$(STAGING_DIR) --bindir=$(STAGING_DIR)/bin --sbindir=$(STAGING_DIR)/sbin --sysconfdir=$(STAGING_DIR)/etc --datadir=$(STAGING_DIR)/share --includedir=$(STAGING_DIR)/include --libdir=$(STAGING_DIR)/lib --localstatedir=$(STAGING_DIR)/var --mandir=$(STAGING_DIR)/man --infodir=$(STAGING_DIR)/info --with-local-prefix=$(STAGING_DIR)/usr/local --oldincludedir=$(STAGING_DIR)/include --enable-languages=c,c++ --with-gnu-as -with-gnu-ld --enable-multilib --with-gxx-include-dir=$(STAGING_DIR)/include/stlport $(EXTRA_GCC_CONFIG_OPTIONS))uclibc的build 動作..
$(UCLIBC_DIR)/.configured: $(UCLIBC_DIR)/.patched $(LINUX_DIR)/.configuredmake:
sed -e 's,@KERNEL_SOURCE@,"$(LINUX_DIR)",' < $(ACTUAL_CONFIG_DIR)/uClibc-$(UCLIBC_VERSION).config \ > $(UCLIBC_DIR)/.config
$(MAKE) $(MFLAGS) -C $(UCLIBC_DIR) oldconfig
$(MAKE) $(MFLAGS) -C $(UCLIBC_DIR) headers install_dev;
cp -R $(UCLIBC_DIR)/_install/include/* $(STAGING_DIR)/$(TARGET)/include
$(uclibc_arch_libs): $(UCLIBC_DIR)/.configured .staging_dir_made $(GCC_TARGET)其中MFLAGS :
$(MAKE) $(MFLAGS) -C $(UCLIBC_DIR) clean
$(MAKE) $(MFLAGS) ARCH_CFLAGS="$(UCLIBC_ARCH_CFLAGS)" -C $(UCLIBC_DIR)
$(MAKE) $(MFLAGS) -C $(UCLIBC_DIR) install
cp $(patsubst %, $(UCLIBC_DIR)/_install/lib/%, $(uclibc_libs)) $(@D)
MFLAGS := TARGET_ARCH=$(ARCH) CROSS=$(TARGET_CROSS).
因為常常要將test stream file copy到VM裡,用linux exports nfs 很麻煩,test stream file size 又很大,所以想直接從Windows nfs server exports ,,,Windows 裝Cygwin 再裝nfs server。
但是NFS server for Windows 好像都不是Free的,
然後就找到這個...
/usr/bin/nfs-server-config會問一些問題,要run nfs server for seperate user,如果是Win2000系統,為了避免麻煩,回答no (也就是說,不用用seperate account 來run),如果是XP的話,就一定要(回答yes)。接著就會安裝一些daemon ... 然後 create /etc/nfs/server.map 。
在我的系統裝時,出現問題:編輯/etc/hosts.allow,把 client 的ip加入,如:line 223 : UID is readonly variable查了一下nfs-server-config 的223行,發現是UID =$(id -u)但是用#echo $UID看了一下,UID已經是環境變數了,不需要再設定一次,所以把這一行comment掉。再run一次nfs-server-config (daemon不用再裝),就OK了 (/etc/nfs/server.map create OK)。
nfsd: 148.150.62.152如果要allow 一個range :
nfsd: 148.150.0.0/255.255.0.0Edit /etc/exports (這部份就跟 linux一樣了):
/pub 148.150.62.0/255.255.255.0(ro,no_root_squash)其實exports檔裡面有很多sample.
對micro-kernel 系統而言,有可能會造成system crach 的東西,都在kernelspace以外。以MINIX3為例,除了clock外,所有的driver都是存在userspace。看完後,覺得還是一樣,programmer常常面對"follow architecure,走遠路?還是走已知的捷徑?"的抉擇。
所以當一個有bug的driver當機時,影響的只是一個driver。kernel 依然可以正常運行。
當你把那個driver的bug解除後,可以再啟動那個driver,系統恢復正常。
也就是說,在driver down到restart 之間,kernel都還是正常的。同樣的,你也可以抽換/升級任意的driver,不需要restart system。
當然,在microkernel 中也可能有bug,導致kernel crash,以MINIX 3為例,他的kernel 有大約3800 行的code,有bug存在的空間。
然而Andy Tanebaum 和他的MINIX 3team認為這樣的大小還是很有可能可以做到bug-free,讓他更接近一個可以永久運行的系統。
和 linux 2.6 的程式大小比起來(約600萬行)。MINIX 3 的kernel 應該更容易做到bug-free。
microkernel的另一個好處是簡潔,系統所有的driver,filesystem,unction ,,都是分離,在自己所屬的userspace中執行,所以各部系統可以做得相當local化。也就是可以做得比較簡傑。這樣也比較容易維護(對個別driver, function 而言)。
這樣在local level上,microkernel 比較容易維護,但是以global 來看,就比較麻煩了。
以Global的觀點來看,microkernel比較複雜,同時也代表microkernel的overhead比較多。
因為各個function,driver都是各自獨立的,他們之間要溝通比較不容易,所以合作起來需要比較多的手續。
這也就是Linux當初認為microkernel比較不合適的原因。因為在90年代,computer的能力不強,常常需要可慮一些可以增進performance的方法。
#sudo apt-get install qemu至於VM檔,sshlog的blog也有說明,不過很長,這個大概是參考build好的VM檔建立的吧:
#qemu-img create -f vmdk WindowsXPPro.vmdk 2G Formating ‘WindowsXPPro.vmdk’, fmt=vmdk, size=2097152 kB
WindowsXPPro.vmx #!/usr/bin/vmware
config.version = “8″
virtualHW.version = “3″
ide0:0.present = “TRUE”
ide0:0.filename = “WindowsXPPro.vmdk”
memsize = “192″
MemAllowAutoScaleDown = “FALSE”
ide1:0.present = “TRUE”
ide1:0.fileName = “WindowsXPPro.iso”
ide1:0.deviceType = “cdrom-image”
ide1:0.autodetect = “TRUE”
floppy0.fileType = “file”
floppy0.fileName = “cdboot1.img”
floppy0.startConnected = “True”
ethernet0.present = “TRUE”
usb.present = “TRUE”
sound.present = “TRUE”
sound.virtualDev = “es1371″
displayName = “Windows XP Pro”
guestOS = “winxppro”
nvram = “WindowsXPPro.nvram”
MemTrimRate = “-1″
ide0:0.redo = “”
ethernet0.addressType = “generated”
uuid.location = “56 4d 15 5e 2f a8 0a dd-21 1a c2 83 2f 44 d3 40″
uuid.bios = “56 4d 15 5e 2f a8 0a dd-21 1a c2 83 2f 44 d3 40″
ethernet0.generatedAddress = “00:0c:29:44:d3:40″
ethernet0.generatedAddressOffset = “0″
tools.syncTime = “TRUE”
ide1:0.startConnected = “TRUE”
uuid.action = “create”
checkpoint.vmState = “WindowsXPPro.vmss”
tools.remindInstall = “TRUE”
存取pci configuration register的方法是用<linux/pci.h>中提供(protype)的function :
#define PCI_VENDOR_ID 0x00 /* 16 bits */
#define PCI_DEVICE_ID 0x02 /* 16 bits */
#define PCI_COMMAND 0x04 /* 16 bits */
#define PCI_STATUS 0x06 /* 16 bits */
#define PCI_REVISION_ID 0x08 /* Revision ID */
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE 0x0a /* Device class */
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
#define PCI_BIST 0x0f /* 8 bits */
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
#define PCI_CARDBUS_CIS 0x28
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
#define PCI_SUBSYSTEM_ID 0x2e
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
/* 0x35-0x3b are reserved */
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
#define PCI_MIN_GNT 0x3e /* 8 bits */
#define PCI_MAX_LAT 0x3f /* 8 bits */
由於pci 使用little endian,這幾個多byte r/w function 會依照host machine的nature自動轉換。
int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val);
int pci_read_config_word(struct pci_dev *dev, int where, u16 *val);
int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val);
int pci_write_config_byte(struct pci_dev *dev, int where, u8 val);
int pci_write_config_word(struct pci_dev *dev, int where, u16 val);
int pci_write_config_dword(struct pci_dev *dev, int where, u32 val);
0000:00:11.0 Ethernet controller: Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE] (rev 10)所以他的configuration data在 /proc/bus/pci/00/11.0。
$ cat /proc/bus/pci/00/11.0 | od對應上面<linux/pci.h>的address定義,可以知道內容。
0000000 010042 020000 000007 001200 000020 001000 040000 000000
0000020 010201 000000 000000 000000 000000 000000 000000 000000
0000040 000000 000000 000000 000000 000000 000000 010042 020000
0000060 000000 000000 000000 000000 000000 000000 000412 177406
0000100
PCI: bus0: Fast back to back transfers disabled找..
PCI: Configured XX as a PCI slave with 128MB PCI memory
PCI: Each Region size is 16384KB
PCI: Reserved memory from 0x10080000 to 0x12080000 for DMA and mapped to 0x12000000
#grep -i 'as a pci slave' * -r在 arch/armnommu/mach-xx/pci_xx.c : void xx_pci_init(void *sysdata)
struct hw_pci xx_pci = {reference 這個 xx_pci的大概是 arch/armnommu/kernel/bios32.c : void __init pcbios_init(void)
init : xx_pci_init,
setup_resources : NULL,
swizzle : no_swizzle,
map_irq : xx_pci_map_irq,
mem_offset : MEMORY_BASE_PCI_MEMORY,
io_offset : MEMORY_BASE_PCI_CONFIG,
};
ifeq ($(LOADERONRAM), y)
$(LD) --gc-section -e t_stage0 -Ttext 0x90000404 -o $@ $(T_STAGE0_OBJS)
else
$(LD) --gc-section -e t_stage0 -Ttext 0xA0000400 -o $@ $(T_STAGE0_OBJS)
endif
開啟了Eponmy blog 的post notification。所以一個晚上,就post了90幾篇。
所以一旦有post,就會mail到Gmail,但是這一封notification竟然又符合Gmail的filter,
所以又forward給eponmy。eponmy又post,又notify。
這是程式馬的tag..在試試 > <...
int kunzip(char *zaddr, char *loadaddr, unsigned int heapaddr)
{
ulg orig_crc, crc;
int i;
outcnt=0;
inptr=0;
inbuf=zaddr;
window=loadaddr;
// heap in SDRAM
// heap_base= loadaddr + 0x200000;
heap_base = (char *) heapaddr;
// max_heap_top=heap_base;
heap_top=heap_base;
updcrc(NULL,0);
inptr+=10;
while(*(inbuf+inptr)) inptr++;
inptr++;
uart_printf("Inptr = 0x%08x(%d)\n", inptr, inptr);
uart_puts("Inflating....\n");
i=inflate();
uart_printf("Outcnt = 0x%08x(%d)\n", outcnt, outcnt);
uart_printf("Final Inptr = 0x%08x(%d)\n", inptr, inptr);
orig_crc = get_unaligned_long(inbuf+inptr);
// orig_len = *(ulg *)(buf+4);
uart_printf("Original CRC = 0x%08lx\n", orig_crc);
// if(outcnt!=599388){
// int ki;
crc=updcrc(window,outcnt);
uart_printf("Computed CRC = 0x%08lx\n", crc);
if (orig_crc != crc) {
// Kaboom !!
uart_puts("Ckecksum mismatched!!\n");
return -1;
}
Hello !!!OK啦。
LINUX_CONFIG_ROOTFS="initrd"在config/kernel-config-initrd ..大概會用這個作kernel defaultconfig file吧。
CONFIG_ROOTFS_INITRD=y
CMDLINE="root=/dev/ram0 rw"應該是make linux-config時,block device的"RAM disk data block compiled in"這個 option吧。
BLK_DEV_RAM=y
BLK_DEV_RAM_SIZE=4096
BLK_DEV_INITRD=y
BLK_DEV_RAMDISK_DATA=y
#BLK_DEV_BLKMEM
dep_bool 'RAM disk data block compiled in' CONFIG_BLK_DEV_RAMDISK_DATA所以好像有兩種initrd使用的方式:
#ifdef CONFIG_BLK_DEV_INITRD__ramdisk_data, __ramdisk_data_end 這兩個 label 定義在
// let the kernel know where the initrd exists
#ifdef CONFIG_SD_INITRD_EMBED
{
initrd_start = (unsigned long) &__ramdisk_data;
initrd_end = (unsigned long) &__ramdisk_data_end - (unsigned long) &__ramdisk_data;
}
#else
initrd_start = CONFIG_SD_INITRD_START;
initrd_end = CONFIG_SD_INITRD_START + CONFIG_SD_INITRD_SIZE;
#endif
#endif
SECTIONS.可以看到在link時,會將INITRDIMAGE link進來。依照image的size決定__ramdisk_data, __ramdisk_data_end.
{
. = TEXTADDR;
.init : { /* Init code and data */
_stext = .;
__略__
__ramdisk_data = .;
INITRDIMAGE
__ramdisk_data_end = .;
. = ALIGN(4096);
__init_end = .;
}
static int __init root_dev_setup(char *line)name_to_kdev_t( )就是把 device name string轉為 device MAJ/MIN number。
{
int i;
char ch;
ROOT_DEV = name_to_kdev_t(line);
memset (root_device_name, 0, sizeof root_device_name);
if (strncmp (line, "/dev/", 5) == 0) line += 5;
for (i = 0; i < sizeof root_device_name - 1; ++i)
{
ch = line[i];
if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
root_device_name[i] = ch;
}
return 1;
}
do_basic_setup( ); 由cmdline找到root的MAJ/MIN number.
prepare_namespace( );
若是用romfs,因為無法kernel要直接mount,所以不能壓縮。順便說明一下bootloader的動作:
uuencode file x > /dev/ttyS0將file經過uuencode後傳到serial port上,但是/dev/ttyS0有permission。