- 1. 為vmware 添加新的硬盤
fdisk 用法就算了
mkfs -t ext3 -c /dev/sdb1 (我看就不用 -c 參數(shù)了吧, check bad block 就不用了, 俺的E4500真快阿,郁悶為啥叫sdx了呢)
df 看看
vim /etc/fstab 添加到系統(tǒng)fstab
/dev/sdb1 /cross ext3 default 1 2
(man fstab,mount) 不備份 fsck檢查順序
2. cross build principle
--------------------------------------------------------------------------------
1) 準(zhǔn)備source code (host:linux targe:arm-linux)
binutils-2.18 ftp://ftp.ntu.edu.tw/pub/gnu/gnu/binutils/binutils-2.18.tar.bz2
gcc-core-4.1.2 ftp://ftp.ntu.edu.tw/pub/gnu/gnu/gcc/gcc-4.1.2/gcc-core-4.1.2.tar.bz2
gcc-g++4.1.2 ftp://ftp.ntu.edu.tw/pub/gnu/gnu/gcc/gcc-4.1.2/gcc-g++-4.1.2.tar.bz2
glibc-2.6.1 ftp://ftp.ntu.edu.tw/pub/gnu//gnu/glibc/glibc-2.6.1.tar.gz
linux-2.6.24.4 http://www.cn.kernel.org/pub/linux/kernel/v2.6/linux-2.6.24.4.tar.bz2
--------------------------------------------------------------------------------
2) 定義環(huán)境變量 (然后解壓縮...)
export PREFIX=/cross/cross-arm cross gcc的bin會(huì)放到這個(gè)目錄
export TARGET=arm-linux arm 上的linux
cd /cross/src 假設(shè)你下載的gcc 和binutil在這個(gè)目錄(你當(dāng)然要解壓縮了)
mkdir build-binutils build-gcc build-glibc
--------------------------------------------------------------------------------
3) binutils (要分清host和target啊...)
cd /cross/src/build-binutils
../binutils-x.xx/configure --target=$TARGET --prefix=$PREFIX --disable-nls
make all
make install
--disable-nls :不要使用漢語吧, 用英語就行了. 這個(gè)選項(xiàng)讓gcc不輸出漢語的提示...
--------------------------------------------------------------------------------
4) bootstrap gcc
cd /cross/src/build-gcc
export PATH=$PATH:$PREFIX/bin
../gcc-x.x.x/configure --target=$TARGET --prefix=$PREFIX --disable-nls
--enable-languages=c --without-headers --disable-shared --disable-threads --disable-libmudflap --disable-libssp
make all-gcc
make install-gcc
-without-headers :這個(gè)選項(xiàng)使你編譯出的GCC不能使用標(biāo)準(zhǔn)庫.(host cpu和target cpu一樣的話,基本不用cross toolchain系統(tǒng)通過編譯選項(xiàng)也能實(shí)現(xiàn)這個(gè)功能).
--with-newlib 這只是個(gè)bug的work around,和newlib沒有關(guān)系的.
This is only necessary if you are compiling GCC <= 3.3.x. That version has a known bug that keeps --without-headers from working correctly. Additionally setting --with-newlib is a workaround for that bug.
--enable-languages :tell gcc需要哪些語言支持:font end, bootstrap gcc only surppot C
tells GCC not to compile all the other language frontends it supports, but only C。
--disable-shared : 沒有這個(gè)選項(xiàng),會(huì)有 crti.o: No such file: No such file or directory collect2: ld returned 1 exit status
--disable-thread : 沒有這個(gè)選項(xiàng)的話會(huì)有, posix_thread.h can't not found 的問題 .
--disable-libmudflap --disable-libssp :兩個(gè)邊界檢查使用的庫,有問題,禁止
http://www.mail-archive.com/gcc@gcc.gnu.org/msg31021.html 無libc的時(shí)候這幾個(gè)庫是不能編譯通過的 :ssp,mudflap,gomp
http://projects.linuxtogo.org/pipermail/openembedded-commits/2007-November/010465.html 這個(gè)線索是這個(gè)問題的補(bǔ)丁
還有官方的 bug :http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25035
--------------------------------------------------------------------------------
5) prepare linux kernel heads
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig 配置內(nèi)核,記著選arm哦
make ARCH=arm CROSS_COMPILE=arm-linux- 隨意運(yùn)行下,就能產(chǎn)生version.h autoconf.h
cd linux-2.4.21
cp -dR include/asm-arm $PREFIX/$TARGET/include/asm
cp -dR include/linux $PREFIX/$TARGET/include/linux
在$TARGET/PREFIX/目錄中建立下面的符號(hào)連接:
cd $PREFIX/$TARGET
ln -s include sys-linux 相當(dāng)于configure gcc --with-heads=
在$TARGET_PREFIX/目錄中建立下面的符號(hào)連接:
cd $PREFIX/$TARGET/include/asm
ln -s arch-s3c2410 arch 其實(shí)arch 已經(jīng)建立了 (make了下,建立好了)
ln -s proc-armv proc 這個(gè)版本沒proc這個(gè)連接了
--------------------------------------------------------------------------------
6) build glibc
搞了半天,原來glibc 2.6.1 是不支持arm的, 需要打上一系列的補(bǔ)丁
glibc-2.6.1-alpha_ioperm_fix-1.patch
glibc-2.6.1-cross_hacks-1.patch
glibc-2.6.1-hppa_nptl-1.patch
glibc-2.6.1-libgcc_eh-1.patch
glibc-2.6.1-localedef_segfault-1.patch
glibc-2.6.1-mawk_fix-1.patch
glibc-2.6.1-RTLD_SINGLE_THREAD_P-1.patch
glibc-2.6.1-sysdep_cancel-1.patch
推薦補(bǔ)丁下載地址 : http://ftp.osuosl.org/pub/clfs/conglomeration/glibc/
推薦文章: http://blog.chinaunix.net/u/26710/showart_394113.html
RTLD_SINGLE_THREAD_P 的fix(上面的patch已經(jīng)包含了,參考下):
http://sources.redhat.com/ml/libc-ports/2006-10/msg00070.html
用 patch -Np1 -i 猛打把,少了那個(gè)都編譯不過去 ,詳細(xì)步驟如下
tar xvf glibc-2.6.1.tar.bz2
cd glibc-2.6.1/
tar xvf ../glibc-ports-2.6.1.tar.bz2
mv -v glibc-ports-2.6.1 ports
patch -Np1 -i ../glibc-2.6.1-libgcc_eh-1.patch
patch -Np1 -i ../glibc-2.6.1-localedef_segfault-1.patch
patch -Np1 -i ../glibc-2.6.1-cross_hacks-1.patch
patch -Np1 -i ../glibc-2.6.1-RTLD_SINGLE_THREAD_P-1.patch
NPTL problem fix:
patch for glibc2.4: http://www.devfiles.jlime.com/parted/glibc/nptl-crosscompile.patch
The following lines need to be added to config.cache for Glibc to support NPTL:
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache
使用參數(shù)--cache-file=config.cache
還不行,需要把a(bǔ)sm-generic copy 到 $PREFIX/$TARGET/include .... (為啥經(jīng)驗(yàn)這么重要呢。。)
$ tar -xvzf glibc-2.2.3.tar.gz
$ tar -xzvf glibc-linuxthreads-2.2.3.tar.gz --directory=glibc-2.2.3
$ cd build-glibc
$ CC=arm-linux-gcc ../glibc-2.2.3/configure --host=$TARGET --prefix=/usr
--with-headers=$PREFIX/$TARGET/include --cache-file=config.cache
CC=arm-linux-gcc 把 CC 變量設(shè)成你剛編譯完的boostrap gcc, 用它來編譯你的glibc.
--host=$TARGET 告訴該鏈接庫在目標(biāo)系統(tǒng)上執(zhí)行, 而非在本地主機(jī).
--prefix="/usr" 告訴配置腳本在目標(biāo)板的根文件系統(tǒng)中g(shù)libc的位置.
--with-headers 告訴glibc 我們的linux 內(nèi)核頭文件的目錄位置.
--enable-add-ons 告訴配置腳本使用我們下載的附加包. 已經(jīng)將glibc-linuxthreads-2.2.3放入了glibc 源碼目錄中.
由于我們只添加了一個(gè)附加包, 這里--enable-add-ons等價(jià)于 --enable-add-ons=linuxthreads.
(如果使用glibc-2.1.x, 需要使用glibc-crypt附加包, 就得使用: --enable-add-ons= linuxthreads, crypt選項(xiàng)). (NPTL 了 )
$ make
$ make install_root=$PREFIX/$TARGET prefix="" install
install_root 指定了安裝鏈接庫組件的目錄, 將glibc安裝到與我們項(xiàng)目相關(guān)的目錄, 而非/usr目錄.如果不指定prefix="", 那么glibc會(huì)被安裝到$/PREFIX/$TARGET/usr/lib目錄中. 指定prefix使glibc被安裝到 $TARGET_PREFIX/lib目錄.
--------------------------------------------------------------------------------
7.)修改$PREFIX$TARGET/lib目錄中的libc.so
$ cd $PREFIX/$TARGET/lib
$ cat libc.so
libc.so的內(nèi)容:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a )
將/lib/目錄去掉, 既將"GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a )"改為: GROUP ( libc.so.6 libc_nonshared.a )
--------------------------------------------------------------------------------
8) completed GCC
cd build-4.1.2
../gcc-4.1.2/configure --target=arm-linux --prefix=/cross/cross-arm --enable-languages=c
make
make install
(出鬼的順利,不支持c++,gcc 相關(guān)補(bǔ)丁也沒有打, 湊合先用吧)
--------------------------------------------------------------------------------
9) simple check
arm-linux-gcc --print-libgcc-file-name
arm-linux-gcc -print-search-dirs
arm-linux-gcc -o test test.c
arm-linux-objdump -D test
--------------------------------------------------------------------------------
10 build kernel for arm
為了配置方便,copy 一個(gè)default config 到linux2.6.24.4 的根目錄. 然后就剪輯吧能去的都去掉.嘿嘿.
cp arch/arm/configs/s3c2410_defconfig .
mv s3c2410_defconfig .config
menuconfig:
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
zImage 出來了, download 到S3C2440 看看吧. 任意鍵進(jìn)入boot menu. 選2 downfrom uart,用DNW下載代碼,完成 選4,寫入nand flash. (不同系統(tǒng)不一樣,看monitor 咋寫了) 選boot os............. 操蛋,啥都沒看到,
只是在串口上看到monitor輸出如下:
Set boot params = root=/dev/ram init=/linuxrc initrd=0x00000000,0x00000000 console=ttyS1,115200 mem=65536K devfs=mount
Load Kernel...
Load Ramdisk...
遇到的問題請(qǐng)繼續(xù)看下一節(jié)...
--------------------------------------------------------------------------------
11 調(diào)整解壓縮參數(shù)
到底啥是重要的啊, 如果連個(gè)printf都不能用,運(yùn)氣未免太差. 參數(shù)中的ttyS1 (第10節(jié)的輸出),俺沒有注意到(么經(jīng)驗(yàn)啊). 于是上ADS 的AXD調(diào)試:
先連接上目標(biāo)板,然后選run, 這樣就可以reboot 系統(tǒng),選5, boot os, 然后用ADX stop,就會(huì)看到一段匯編了. 仔細(xì)查看發(fā)現(xiàn)arm 確實(shí)在運(yùn)行一段程序,經(jīng)過查詢system.map,發(fā)現(xiàn)是panic( 我猜想是root fs沒有...,但是沒有顯示內(nèi)容到我的串口啊,串口接在uart1上).
隨意看看那個(gè)2440 mon程序, linux的加載方式如下:
將zImage從nand flash copy到 0x3040 0000 然后就jump過去. 內(nèi)核參數(shù)放在0x3000 0100.
goto_start = 0x3040 0000;
(*goto_start)(0, 193);
不過對(duì)為啥不能啟動(dòng)還是沒有線索啊...
有幾個(gè)比較可疑的內(nèi)核配置選項(xiàng)可能引起問題比如
boot option->
compressed rom boot loader base address #<a>
default kernel command string #<b>
所以俺又試了幾個(gè)選項(xiàng), 把 #<a> 的地址改成0x3040 0000...... 不幸還是不可以, 因?yàn)闆]有信息出現(xiàn)也不知道運(yùn)行到了哪里,不過根據(jù)調(diào)試的結(jié)果,應(yīng)該是過了解壓縮階段的....
事后俺查上面兩個(gè)選項(xiàng)的含義( 就是按 ? 了), #<a> 是說ROM able 的zImage, 就是zImage直接在rom中運(yùn)行時(shí), 才有效所以犯了錯(cuò)誤啊. <b> 也不行, 因?yàn)槿绻麤]有辦法傳遞kernel 的command line時(shí)才有效, 而s32440下無效. 幫助里列舉有幾個(gè)平臺(tái)需要這個(gè)選項(xiàng).
先把參數(shù)地址為啥在0x3000 0100 和runaddr為啥在0x3040 0000跳過不談,為啥沒有任何信息? 連解壓內(nèi)核的信息都沒有? 看了幾遍config, 找到了如下的選項(xiàng):
system type->
[0] S3C UART to use for low-level messages
嘿嘿,進(jìn)去把0改成1, 看看arm的相關(guān)啟動(dòng)代碼,印證了通過這個(gè)選項(xiàng)選擇內(nèi)核解壓縮信息的輸出端口. 選成1, 再試,果然有內(nèi)核解壓縮信息打印出來,呵呵. 相關(guān)代碼在內(nèi)核的位置:
decompress_kernel ->
putstr("Uncompressing Linux...");
gunzip();
putstr(" done, booting the kernel. ");
-> include/asm-arm/plat-s3c
static void putc(int ch)
{
if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
.....
}
uart_rd(unsigned int reg)
{
volatile unsigned int *ptr;
ptr = (volatile unsigned int *)(reg + uart_base);
return *ptr;
}
#define uart_base S3C24XX_PA_UART + (0x4000*CONFIG_S3C_LOWLEVEL_UART_PORT)
--------------------------------------------------------------------------------
12. 內(nèi)核控制臺(tái)
就是命令行里的console參數(shù). 這里不打算討論console到底是啥, 僅指出,俺沒有看到內(nèi)核正常的啟動(dòng)信息和這個(gè)選項(xiàng)大大的相關(guān).我們分析下monitor給出的信息:
Set boot params = root=/dev/ram init=/linuxrc initrd=0x00000000,0x00000000 console=ttyS1,115200 mem=65536K devfs=mount
Load Kernel...
Load Ramdisk...
這里console設(shè)置成了 ttyS1, 而linux2.6.24.4 要求(不知道具體從啥時(shí)候開始,2.6?) 名字是ttySAC1,指定串口1. 看monitor的代碼就能知道了, monitor需要升級(jí)的. ...走了冤枉路了,明白了monitor和內(nèi)核這里的一點(diǎn)糾纏.
升級(jí)monitor之后... 嘿嘿,終于有東西了...呵呵
Uncompressing Linux...................................................... done
, booting the kernel.
Linux version 2.6.24.4 (root@localhost.localdomain) (gcc version 4.1.2) #7
Tue Apr 15 07:50:25 CST 2008
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
Machine: SMDK2410
ATAG_INITRD is deprecated; please update your bootloader.
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C244X: core 400.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz
S3C24XX Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: root=/dev/ram init=/linuxrc initrd=0x00000000,0x00000000
console=ttySAC1,115200 mem=65536K devfs=mount
irq: clearing pending ext status 000dff00
irq: clearing pending ext status 00001000
irq: clearing subpending status 000000ba
irq: clearing subpending status 00000092
PID hash table entries: 256 (order: 8, 1024 bytes)
timer tcon=00090000, tcnt a2c1, tcfg 00000200,00000000, usec 00001eb8
Console: colour dummy device 80x30
console [ttySAC1] enabled
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 63128KB available (1428K code, 223K data, 92K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
S3C2440: Initialising architecture
S3C2440: IRQ Support
S3C2440: Clock Support, DVS off
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
JFFS2 version 2.2. (NAND) 漏 2001-2006 Red Hat, Inc.
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing enabled
s3c2440-uart.0: s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2440
s3c2440-uart.1: s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2440
s3c2440-uart.2: s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2440
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
loop: module loaded
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=3, 30ns Twrph0=7 70ns, Twrph1=3 30ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-
bit)
Scanning device for bad blocks
Creating 8 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00004000 : "Boot Agent"
0x00000000-0x00200000 : "S3C2410 flash partition 1"
0x00400000-0x00800000 : "S3C2410 flash partition 2"
0x00800000-0x00a00000 : "S3C2410 flash partition 3"
0x00a00000-0x00e00000 : "S3C2410 flash partition 4"
0x00e00000-0x01800000 : "S3C2410 flash partition 5"
0x01800000-0x03000000 : "S3C2410 flash partition 6"
0x03000000-0x04000000 : "S3C2410 flash partition 7"
mice: PS/2 mouse device common for all mice
S3C24XX RTC, (c) 2004,2006 Simtec Electronics
s3c2440-i2c s3c2440-i2c: slave address 0x10
s3c2440-i2c s3c2440-i2c: bus frequency set to 390 KHz
s3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapter
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
List of all partitions:
1f00 16 mtdblock0 (driver?)
1f01 2048 mtdblock1 (driver?)
1f02 4096 mtdblock2 (driver?)
1f03 2048 mtdblock3 (driver?)
1f04 4096 mtdblock4 (driver?)
1f05 10240 mtdblock5 (driver?)
1f06 24576 mtdblock6 (driver?)
1f07 16384 mtdblock7 (driver?)
No filesystem could mount root, tried: cramfs romfs
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
--------------------------------------------------------------------------------
13. 內(nèi)核參數(shù)的傳遞方式
前邊說過monitor吧內(nèi)核參數(shù)放到了地址 0x3000 0100 這個(gè)地址. 這個(gè)道理何在呢. 先看內(nèi)核打印內(nèi)核命令行的地方: init/main.c
asmlinkage void __init start_kernel(void)
-->printk(KERN_NOTICE "Kernel command line: %s ", boot_command_line);
是個(gè)全局變量,搜索下,在arch/arm/kernel/setup.c:
void __init setup_arch(char **cmdline_p)
{
char *from = default_command_line; /*.config 中指定的命令行*/
...
mdesc = setup_machine(machine_arch_type); /*從上面串口輸出知道是 "Machine: SMDK2410", 由.config決定*/
/*里邊引用的lookup_machine_type 在arch/arm/kernel/head_common.S*/
......
if (__atags_pointer)
tags = phys_to_virt(__atags_pointer);
else if (mdesc->boot_params)
tags = phys_to_virt(mdesc->boot_params);
...
/*
* If we have the old style parameters, convert them to
* a tag list.
*/
if (tags->hdr.tag != ATAG_CORE)
convert_to_tag_list(tags); /*把boot loader傳遞的參數(shù), arch/arm/kernel/compat.c struct param_struct {
..} 轉(zhuǎn)換成tag list, 其中包括 ATAG_CMDLINE */
if (tags->hdr.tag != ATAG_CORE)
tags = (struct tag *)&init_tags;
if (mdesc->fixup) /*s3c2410 是NULL*/
mdesc->fixup(mdesc, tags, &from, &meminfo);
if (tags->hdr.tag == ATAG_CORE) {
if (meminfo.nr_banks != 0)
squash_mem_tags(tags);
parse_tags(tags); /*ATAG_CMDLINE 的parser 把相應(yīng)命令行copy 到default_command_line, 也在這個(gè)文件內(nèi)*/
}
....
memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(cmdline_p, from);
}
這里先忽略下mdesc是怎么被找到的,先直接搜索 mdesc的類型,可以找到 #define MACHINE_START(_type,_name) 這個(gè)宏,然后console的"SMDK2410"這個(gè)宏定義, 可以在arch/arm/mach-s3c2410下找到:
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
/* Maintainer: Jonas Dietsche */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = smdk2410_map_io,
.init_irq = s3c24xx_init_irq,
.init_machine = smdk2410_init,
.timer = &s3c24xx_timer,
MACHINE_END
#define S3C2410_SDRAM_PA (S3C2410_CS6)
#define S3C2410_CS6 (0x30000000)
這下子就知道內(nèi)核參數(shù)傳遞的方式了: (arm)
把 arch/arm/kernel/compat.c 中定義的struct param_struct { } 放到0x3000 0100 處即可....
至于去求證 monitor 的 runAddr 和參數(shù)地址, 請(qǐng)看 : (這個(gè)是monitor用到的參數(shù),決定了runAddrs)
BootParams boot_params = {
{"bootpara", 1}, //0=boot without parameters,1=boot with parameters
{"cpuclk", 2}, //0=200M, 1=300M, 2=400M, 3=440M
{"rundelay", 0}, //0 seconds
{"serial", 1}, //0=serial port 0, 1=serial port 1
{"baudrate", 115200},
{"machine", 193},
{"runAddr", 0x30400000},
{"rootfs", 0},
{"tty", 1},
{"initrdA", 0},
{"initrdL", 0},
{"memsize", 0x04000000},
{"devfs", 1},
{"ostore", 0}, //0=nand, 1=nor
{"userpara", sizeof(DEFAULT_USER_PARAMS)},
DEFAULT_USER_PARAMS
};
從這個(gè)參數(shù)加載linux的代碼在nand.c LoadRun .
--------------------------------------------------------------------------------
14. 內(nèi)核加載地址和start參數(shù)問題
從上面的分析, 知道內(nèi)核被加載到0x30400 0000處, 這個(gè)其實(shí)是zImage的加載地址, 就是說內(nèi)核解壓縮程序的運(yùn)行地址. 還有一個(gè)問題,我們的內(nèi)核一直是little endian 的. arm-linux-objdump下就知道.
一個(gè)問題是Big-endian的內(nèi)核如何run, 另一個(gè)是解壓縮程序的運(yùn)行地址是隨意的嗎?
從monitor看, 這個(gè)環(huán)境一直在little endian運(yùn)行... (big endian 實(shí)驗(yàn)也另作研究吧)
能否加載到任意合理地址(至少有ram吧,呵呵), 試驗(yàn)一下即可. 結(jié)果證明是可以的, 當(dāng)然應(yīng)該行,因?yàn)閦Image已經(jīng)支持PIC代碼,并且可以配置成在純ROM環(huán)境下運(yùn)行(那就得燒到到固定地址了).
研究下zImage都包含什么東西,這個(gè)先從arch/arm/boot/Makefile看看吧:
$(obj)/compressed/vmlinux: $(obj)/Image FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE #zImage 包含解壓縮頭的Image
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
.......
$(obj)/uImage: $(obj)/zImage FORCE # U-boot image
$(call if_changed,uimage)
@echo ' Image $@ is ready'
$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE 包含bootp目錄的image bootpImage, 如要initrd,這個(gè)平臺(tái)不支持,所以加載
$(Q)$(MAKE) $(build)=$(obj)/bootp $@ RamDisk 是monitor的事情了
@:
$(obj)/bootpImage: $(obj)/bootp/bootp FORCE #包含bootp目錄的image bootpImage
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
內(nèi)核解壓縮和PIC (position independent code)
arch/arm/boot/compressed/Makefile
#
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
ifeq ($(CONFIG_ZBOOT_ROM),y) #從boot ROM運(yùn)行時(shí)需要配置一個(gè)固定地址,還有BSS的地址
ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR := 0 #一般情況下,就是0, 是pic代碼加上'手工'重定位,加載到任意地址
ZBSSADDR := ALIGN(4)
endif
SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
#把vmlinux.lds.in 中TEXT_START換成配置的地址(主要針對(duì)ZBOOT_ROM)
targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c
head.o misc.o $(OBJS)
EXTRA_CFLAGS := -fpic -fno-builtin
EXTRA_AFLAGS :=
.............
# Don't allow any static data in misc.o, which
# would otherwise mess up our GOT table
CFLAGS_misc.o := -Dstatic=
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o
$(addprefix $(obj)/, $(OBJS)) FORCE
$(call if_changed,ld)
@:
$(obj)/piggy.gz: $(obj)/../Image FORCE #piggy.gz 是壓縮后的內(nèi)核,見piggy.S
$(call if_changed,gzip)
$(obj)/piggy.o: $(obj)/piggy.gz FORCE
CFLAGS_font.o := -Dstatic=
$(obj)/font.c: $(FONTC)
$(call cmd,shipped)
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
@sed "$(SEDFLAGS)" < $< > $@
$(obj)/misc.o: $(obj)/misc.c include/asm/arch/uncompress.h lib/inflate.c
解壓縮的pic技術(shù)以后再研究吧,挺多的.這里就是增強(qiáng)下信心吧. 知道可以加載到任意地址,呵呵. 下面看看decompress的入口函數(shù)start的參數(shù)問題:
arch/arm/boot/compressed/head.S
/*
* sort out different calling conventions
*/
.align
start:
.type start,#function
.rept 8
mov r0, r0
.endr
b 1f
.word 0x016f2818 &nb sp; @ Magic numbers to help the loader
.word start @ absolute load/run zImage address
.word _edata @ zImage end address
1: mov r7, r1 @ save architecture ID
mov r8, r2 @ save atags pointer
從這里看出, r1 存放的是architectureID, r2存放 atags 指針. 寄存器傳遞參數(shù), 加上沒有用的r0, 應(yīng)該是這樣一個(gè)函數(shù):
void start(0, archID, *atags)
其實(shí),在arch/arm/kernel/head.S中有關(guān)于參數(shù)的一段詳細(xì)的注釋,看看就明白了:
/*
* Kernel startup entry point.
* ---------------------------
*
* This is normally called from the decompressor code. The requirements
* are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
* r1 = machine nr, r2 = atags pointer.
*
* This code is mostly position independent, so if you link the kernel at
* 0xc0008000, you call this at __pa(0xc0008000).
*
* See linux/arch/arm/tools/mach-types for the complete list of machine
* numbers for r1.
*
* We're trying to keep crap to a minimum; DO NOT add any machine specific
* crap here - that's what the boot loader (or in extreme, well justified
* circumstances, zImage) is for.
*/
找到mach-type是:
s3c2440 ARCH_S3C2440 S3C2440 362
不過通過實(shí)驗(yàn), 我們的機(jī)器看來是SMDK兼容了,machine 參數(shù)必須傳遞193: SMDK2410 這個(gè)才行,而cpu類型則是自動(dòng)偵測(cè)的,呵呵.
對(duì)應(yīng)kernel的參數(shù)和decompressed一樣:
void (*theKernel)(int zero, int arch, uint params);
另:試了試big endian,發(fā)現(xiàn)現(xiàn)在linux kernel對(duì)s3c的系統(tǒng)還不支持big模式.make config也無此選項(xiàng).
--------------------------------------------------------------------------------
15. initrd : initial ram disk load process
讓我們從新審視所得到的內(nèi)核console的輸出(見上文),看看需要做的東西, 先來關(guān)注幾行的輸出信息,內(nèi)核相關(guān)代碼是:
start_kernel->rest_init->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);->
static int __init kernel_init(void * unused)
{
..........
/*
* check if there is an early userspace init. If yes, let it do all
* the work
*/
if (!ramdisk_execute_command) /*由內(nèi)核命令行參數(shù) rdinit= 來控制,我們沒有指定 (搜索就知道是rdinit=來控制了...)*/
ramdisk_execute_command = "/init";
if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
ramdisk_execute_command = NULL;
prepare_namespace();
}
.........
}
內(nèi)核中有各種__setup宏定義的內(nèi)核參數(shù), 其前面的字符串是內(nèi)核命令行, 其后的函數(shù)是這個(gè)命令行的處理函數(shù),相關(guān)的宏定義在init.h中.grep下,很快有結(jié)果. 詳細(xì)討論先放一放.
void __init prepare_namespace(void)
{
.............
if (saved_root_name[0]) {
root_device_name = saved_root_name; /*這個(gè)就是由 root=/dev/ram傳遞的內(nèi)核參數(shù),稍作搜索即知*/
if (!strncmp(root_device_name, "mtd", 3)) { /*我們當(dāng)然不是這個(gè)*/
.............
}
ROOT_DEV = name_to_dev_t(root_device_name); /*/dev/ram 解析出來的設(shè)備是 ROOT_DEV= root_RAM0(1,0)*/
if (strncmp(root_device_name, "/dev/", 5) == 0)
root_device_name += 5; /* root_dev_name = "ram" */
}
if (initrd_load()) /* CONFIG_BLK_DEV_INITRD 之后才能使用initrd,我們的.config是有的*/
goto out;
......
mount_root();
out:
sys_mount(".", "/", NULL, MS_MOVE, NULL); /* /root 如何成為根, 何以叫mount root,原來并不是加載 "/" */
sys_chroot(".");
security_sb_post_mountroot();
}
int __init initrd_load(void)
{
if (mount_initrd) { /*只有配置了內(nèi)核命令行: noinitrd才為0, 我們當(dāng)然沒有'自殺'了*/
create_dev("/dev/ram", Root_RAM0); /*創(chuàng)建設(shè)備先...*/
/*
* Load the initrd data into /dev/ram0. Execute it as initrd
* unless /dev/ram0 is supposed to be our actual root device,
* in that case the ram disk is just set up here, and gets
* mounted in the normal path.
*/
if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) { /*下面看看/initrd.image啥時(shí)候創(chuàng)建的*/
sys_unlink("/initrd.image");
handle_initrd();
return 1;
}
}
sys_unlink("/initrd.image");
return 0;
}
從我們配置的參數(shù)是Root_RAM0, void __init prepare_namespace(void)會(huì)調(diào)用mount_root:
void __init mount_root(void)
{
#ifdef CONFIG_ROOT_NFS
...
#endif
#ifdef CONFIG_BLK_DEV_FD
....
#endif
#ifdef CONFIG_BLOCK
create_dev("/dev/root", ROOT_DEV);
mount_block_root("/dev/root", root_mountflags); /*有默認(rèn)值 MS_RDONLY | MS_SILENT*/
#endif
}
void __init mount_block_root(char *name, int flags)
{
get_fs_names(fs_names); /*所有已經(jīng)安裝的文件系統(tǒng)的名字列表*/
retry:
for (p = fs_names; *p; p += strlen(p)+1) { /*p代表fs type, 這里name 是/dev/root,就是Root_RAM0*/
int err = do_mount_root(name, p, flags, root_mount_data); /*(dev,type,mntflags,(rootflags=,給具體文件系統(tǒng)的參數(shù)) )*/
.......
/*如果失敗了,下面的信息倒是沒有顯示出來....*/
printk("VFS: Cannot open root device "%s" or %s ",
root_device_name, b);
printk("Please append a correct "root=" boot option; here are the available partitions: ");
printk_all_partitions();
panic("VFS: Unable to mount root fs on %s", b);
}
printk("List of all partitions: ");
printk_all_partitions();
printk("No filesystem could mount root, tried: "); /*列出曾經(jīng)嘗試的文件系統(tǒng)類型*/
for (p = fs_names; *p; p += strlen(p)+1)
printk(" %s", p);
printk(" ");
.......
panic("VFS: Unable to mount root fs on %s", b); /*知名panic*/
...
}
好了上面的函數(shù)就是知名的panic. 這個(gè)過程就是將文件/initrd.image 拷貝到Root_RAM0設(shè)備內(nèi), 然后創(chuàng)建設(shè)備文件/dev/root(這個(gè)個(gè)文件就是為了fs的接口函數(shù)準(zhǔn)備的),然后將 /dev/root 安裝到/root, 升級(jí)/root到文件系統(tǒng)根目錄 '/'.
遇到這個(gè)panic從代碼上看,是do_mount_root在嘗試用各種文件系統(tǒng)來解析/dev/root后竭盡失敗.無奈之下,panic的.原因可就多了,比如config的時(shí)候沒有選上ramdisk支持(設(shè)備層), 或者ramdisk中的文件系統(tǒng)內(nèi)核不支持(文件系統(tǒng)層), 再或者initrd的加載出了問題(無論是boot loader 還是內(nèi)核創(chuàng)建"/initrd.image", 參數(shù)傳遞錯(cuò)誤也不成. 經(jīng)過仔細(xì)檢查,內(nèi)核配置和參數(shù)傳遞應(yīng)該沒有啥問題. 這里好多內(nèi)核的信息沒有打印出來,詳細(xì)的錯(cuò)誤也就被隱蔽了.
為了驗(yàn)證ramdisk是否正確加載, 在rd_load_image("/initrd.image") 里面加了不少調(diào)試信息,結(jié)果發(fā)現(xiàn), 根本沒有/initrd.image這個(gè)文件,在這個(gè)函數(shù)打開這個(gè)文件的時(shí)候出錯(cuò)了, 這證明這個(gè)文件創(chuàng)建失敗了. 原因也很多,不過還是先掃一眼這個(gè)文件在什么地方創(chuàng)建.一搜,在這個(gè)函數(shù)里呢:
static int __init populate_rootfs(void) 這是一個(gè)init函數(shù),內(nèi)核悄悄的運(yùn)行了他.... (運(yùn)行的地方好找,不提).
static int __init populate_rootfs(void)
{
... /*解壓縮先略過不看...*/
if (initrd_start) { /*這個(gè)就是內(nèi)核命令行傳遞進(jìn)來的值...., 汗...monitor里這個(gè)值是0, 顯然是不對(duì)的啊*/
/* ...創(chuàng)建 initrd.image 這個(gè)文件*/
fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700);
.......
}
好了一個(gè)問題出來了, 改吧, 去monitor的參數(shù)里修改一番,也犯了不少錯(cuò)誤:
1) 個(gè)就是initrd的初始地址不能為0...,
2) 再有就是有個(gè)地方出錯(cuò)比如我設(shè)置initrd初始地址0x1000(隨意值), 大小是0x1000(隨意值,不設(shè)置長(zhǎng)度monitor不加載ramdisk,只對(duì)此monitor有效). 這個(gè)地址有傻問題? 看看輸出:
Memory policy: ECC disabled, Data cache writeback
initrd (0x00000000 - 0x000003e8) extends beyond physical memory - disabling initrd
CPU S3C2440A (id 0x32440001)
這里又跳出個(gè)地方和initrd有關(guān), 位置在bootmem初始化中:(ft...)
arch/arm/mm/init.c
static int __init check_initrd(struct meminfo *mi)
{
.......
if (phys_initrd_size) {/*初傳遞的initrd start 和size都是0, 我ft.... */
for (i = 0; i < mi->nr_banks; i++) {
...........
}
if (initrd_node == -1) {
printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond "
"physical memory - disabling initrd ",
phys_initrd_start, end);
phys_initrd_start = phys_initrd_size = 0;
}
..........
}
沒有仔細(xì)探究這個(gè)bank是個(gè)什么意思(估計(jì)就是S3C2440 cpu里對(duì)內(nèi)存bank的劃分吧),但是這個(gè)警告信息提醒了我.超出物理內(nèi)存? 不一定是地址太大,呵呵,因?yàn)榘? ram物理地址并不是從0開始的,啟動(dòng)的時(shí)候是S3C2440 自己吧nand讀到了地址0開始的一段內(nèi)部ram中.....所以,吧initrd start地址和size設(shè)置成一個(gè)在RAM地址范圍內(nèi)的一段地址里. 重啟,這下,果然不同了........
出現(xiàn)的信息還是不能加載root文件系統(tǒng),但是initrd加載成功了, 即ramdisk已經(jīng)包含了initrd.image, "/initrd.image"文件也已經(jīng)創(chuàng)建成功了. 但是出現(xiàn)RAMDISK: image too big! (2078xx/4096) ,相關(guān)函數(shù)是
int __init rd_load_image(char *from) /*從/initrd.image 寫入/dev/ram設(shè)備*/
{
......
/*nblocks是從ramdisk image中根據(jù)文件系統(tǒng)magic猜測(cè)的block數(shù)(identify_ramdisk_image),
*rd_blocks是從/dev/ram設(shè)備中讀出的數(shù)值,ramdisk大小是4096K size ,1024 blocksize,可以配置
*/
if (nblocks > rd_blocks) { /*這個(gè)信息是發(fā)現(xiàn)加載的initrd image大小大于ram disk的大小,加載失敗*/
printk("RAMDISK: image too big! (%dKiB/%ldKiB) ",
nblocks, rd_blocks);
goto done;
}
....
}
另外,建議調(diào)試階段把kernel consolelog 設(shè)置成verbose,就是在setup_arch的前端,調(diào)用下面函數(shù):
console_verbose();
這樣一些提示性和continue性質(zhì)的信息能夠顯示出來方便調(diào)試.
這個(gè)原因是什么? 根據(jù)調(diào)試信息打印出來信息, identify_ramdisk_image:RAMDISK: cramfs filesystem found at block 0
顯然是發(fā)現(xiàn)了一個(gè)cramfs,但是不知到是什么原因. 呵呵,秘密是我還沒有燒一個(gè)initrd進(jìn)去呢,用的是現(xiàn)有的, 其大小和格式都是未知的.這樣當(dāng)然累了,要知道原因就太難(?), 所以要自己制作一個(gè)....
--------------------------------------------------------------------------------
16. 制作ramfs
為了測(cè)試,僅制作文件系統(tǒng)..步驟如下:
RDSIZE=1024
BLKSIZE=1024
# 為了測(cè)試,越小越好,創(chuàng)建一個(gè)1M 的ram disk,這樣下載快(現(xiàn)在我只有串口)
dd if=/dev/zero of=ramdisk.img bs=$BLKSIZE count=$RDSIZE
#在其上制作ext2文件系統(tǒng)
/sbin/mke2fs -F -m 0 -b $BLKSIZE ramdisk.img $RDSIZE
-F 強(qiáng)制運(yùn)行,不管是否是塊設(shè)備/或者已經(jīng)安裝
-m 0 設(shè)置預(yù)留塊數(shù)量的百分比, 我們可不能浪費(fèi),所以一個(gè)都不保留....呵呵.
-b 1024 一個(gè)block 1k
下載,運(yùn)行,呵呵又出錯(cuò)了:
try load ram disk /*這是自己加的調(diào)試信息*/
RAMDISK: ext2 filesystem found at block 0 /*我們制作的是ext2文件系統(tǒng),這里也認(rèn)出了*/
RAMDISK: Loading 4000KiB [1 disk] into ram disk... done. /*這里看出initrd真是加載成功了,到了ramdisk0中*/
load image ret 1 /*這是自己加的調(diào)試信息, mount失敗*/
原因很明顯,我們根本沒有編譯ext2文件系統(tǒng)支持, 重新配置編譯,運(yùn)行.呵呵根文件系統(tǒng)安裝真的成功了.不過,問題還沒有完:
VFS: Mounted root (ext2 filesystem).
Freeing init memory: 92K
Warning: unable to open an initial console.
Failed to execute /linuxrc. Attempting defaults...
Kernel panic - not syncing: No init found. Try passing init= option to kernel.
這個(gè)嘛,嘿嘿,我們的文件系統(tǒng)上啥都沒有, 得搞個(gè)什么東西上去才行啊.
--------------------------------------------------------------------------------
16.1 initrd "hello world"
也試了直接編譯busybox,可是看起來busybox啟動(dòng)了,但是沒有任何輸出.查busybox的說明,busybox建議自己用cross toolchain搞個(gè)hello world試試,看看你能不能運(yùn)行,不行的話就別搞busybox了,肯定不行啦.
故而,寫hello world一個(gè)(好久不hello world了):
arm-linux-gcc -static -o test test.c
arm-linux-objcopy -S test test_strip [這個(gè)去掉大部分沒有用的段,大大減小bin的大小]
然后用arm-linux-readelf -A test 看看. (aeabi) 在rootfs上(ramdisk.img)建立/dev和必要的設(shè)備文件:
mount -t ext2 ramdisk.img /mnt/initrd -o loop
mkdir dev
cp -a /dev/null dev
cp -a /dev/console dev
cp /cross/src/linux2.6.24.4/test_strip linuxrc [我們的hello world就是linuxrc,呵呵]
sync
umount /mnt/initrd
gzip -9 ramdisk.img
下載, 啟動(dòng).... 沒有看到我熟悉的hello world
VFS: Mounted root (ext2 filesystem).
Freeing init memory: 92K
selected clock c01adf24 (pclk) quot 26, calc 115740
google下,發(fā)現(xiàn)自己幾乎犯過了所有的毛病,先是內(nèi)核并不支持eabi串口無輸出,就編譯成支持eabi的內(nèi)核,結(jié)果一樣不幸.再google,發(fā)現(xiàn)float point emulation必須選一,我沒選,選上重來. 終float point終于解決了這個(gè)問題.內(nèi)核中只能使用浮點(diǎn)模擬,運(yùn)行大部分的 binaries 都需要浮點(diǎn)支持.
hello world終于搞定了. (經(jīng)測(cè)試,沒有eabi支持的內(nèi)核照樣可以hello world,以后再研究吧]
VFS: Mounted root (ext2 filesystem).
Freeing init memory: 92K
selected clock c01adf24 (pclk) quot 26, calc 115740
hello world [這就是我們期待的輸出...]
--------------------------------------------------------------------------------
16.2 busy box
先編譯一個(gè)busybox用用,到 http://www.busybox.net/downloads/ 下載的1.9.2玩玩.
配置的時(shí)候選上 don't use /usr,不然make install 就完蛋了
make ARCH=arm CROSS_COMPILE=arm-linux- allnoconfig
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig /*只要ash mount echo ls cat ps dmsg sysctl, static 連接*/
make ARCH=arm CFLAGS="-I/cross/cross-arm/arm-linux/sys-include/" CROSS_COMPILE=arm-linux-
make ARCH=arm CFLAGS="-I/cross/cross-arm/arm-linux/sys-include/" CROSS_COMPILE=arm-linux- install
(需要把a(bǔ)pplets.c的警告去掉, glibc靜態(tài)連接不好用,有bug,我們就試試,玩玩, 建議用ulibc,呵呵)然后就開始制作了:
# 把我們先前制作的ramdisk.img加載到臨時(shí)目錄
mount ramdisk.img /mnt/initrd -t ext2 -o loop=/dev/loop0
# busy box 為我們建立好了各種符號(hào)連接,copy即可
cp -rf /cross/src/busybox-1.9.2/_install/* .
我們的rootfs就有了 bin sbin 和linuxrc
# 然后在ramdisk上建立如下目錄
mkdir dev
# 創(chuàng)建相應(yīng)的設(shè)備文件
cp -a /dev/console dev
cp -a /dev/null dev
#cp -a /dev/ttyS0 dev #沒用s3c2410上串口設(shè)備是s3c2410_serial1
#cp -a /dev/ttyS1 dev #
# 解除安裝, 可以壓縮的(俺的很小,不壓縮也罷!)
umount /mnt/initrdgzip -9 ramdisk.img
#先搞這么多,先玩一把,下面是輸出,爽啊
FS: Mounted root (ext2 filesystem).
Freeing init memory: 92K
selected clock c01a9df0 (pclk) quot 26, calc 115740
selected clock c01a9df0 (pclk) quot 26, calc 115740
init started: BusyBox v1.9.2 (2008-04-18 22:44:50 CST)
selected clock c01a9df0 (pclk) quot 26, calc 115740
command='reboot' action=32 tty=''
command='umount -a -r' actselected clock c01a9df0 (pclk) quot 26, calc 115740ion=64 tty=''
command='init' action=128 tty=''
command='-/bin/sh' action=4 tty=''
command='-/bin/sh' action=4 tty='/dev/tty2'
command='-/bin/sh' action=4 tty='/dev/tty3'
command='-/bin/sh' action=4 tty='/dev/tty4'
command='/etc/init.d/rcS' action=1 tty=''
starting pid 720, tty '': '/etc/init.d/rcS'
Cannot run '/etc/init.d/rcS': No such file or directory
waiting for enter to start '/bin/sh'(pid 721, tty '')
Please press Enter to activate this console.
Can't open /dev/tty3: No such file or directory
Can't open /dev/tty4: No such file or directory
process '-/bin/sh' (pid 724) exited. Scheduling it for restart.
process '-/bin/sh' (pid 726) exited. Scheduling it for restart.
Can't open /dev/tty3: No such file or directory
Can't open /dev/tty4: No such file or directory(不斷重復(fù)中,看看需要做的東西還多著呢,不過ash已經(jīng)啟動(dòng)了...ls可以工作的..呵呵)
這個(gè)事情有人報(bào)告是個(gè)bug:
http://groups.google.com/group/linux.debian.bugs
關(guān)于這個(gè)問題的報(bào)告 既然如此,先升級(jí)的1.10.1看看, 測(cè)試結(jié)果:
1. applets.c的警告沒有了
2. make ARCH=arm CROSS_COMPILE=arm-linux- CFLAGS=-I/cross/cross-arm/arm-linux/sys-linux這次busybox選的東西比較多,弄了個(gè)2M的ramdisk, 壓縮后399k. ...
問題一樣地...,好了自己寫linuxrc吧.
--------------------------------------------------------------------------------
16.3 為busybox 配置腳本
1) 先簡(jiǎn)單看看各種文件系統(tǒng)的作用吧:
tmpfs :/dev/shm #share mem對(duì)應(yīng)的文件系統(tǒng)
devpts :/dev/pts #目前常見的 pseudo 終端(PTYs)實(shí)現(xiàn)方式
sysfs :/sys #sysfs 包含進(jìn)程相關(guān)的proc fs,設(shè)備相關(guān)的devfs以及為終端相關(guān)的devpty fs的信息,是當(dāng)前趨勢(shì),
由內(nèi)核內(nèi)的kobj形成,udev嚴(yán)重依賴于sysf,能夠在/dev目錄下產(chǎn)生系統(tǒng)真正存在的設(shè)備,而不是一鍋粥的方式
sysfs和udev配合,勢(shì)必要擊敗devfs+devfsd(?)
udev : # 需要/etc/udev/rules.d 目錄和一堆的配置規(guī)則
devfs :/dev #和devfsd配合使用, devfsd將會(huì)負(fù)責(zé)創(chuàng)建“舊類型”兼容性設(shè)備節(jié)點(diǎn);在注冊(cè)/注銷設(shè)備時(shí)執(zhí)行自動(dòng)化操作; 負(fù)責(zé)備份對(duì)根文件系統(tǒng)上某個(gè)目錄的設(shè)備許可權(quán)和所有權(quán)的更改,以及其它更多功能
proc :proc # proc文件系統(tǒng),不必多說
2) 簡(jiǎn)單的inuxrc:
#!/bin/she
cho echo "Open ARM AKAE www.linuxforum.net "
echo
mount -t proc /proc /proc
mount -t sysfs sysfs /sys
mount -t devpts devpts /dev/pts
echo "Start mdev..."
mdev -s /*mdev -s 把設(shè)備從sysfs 同步到/dev目錄,需要要/etc/mdev.conf*/
init /*傳遞給腳本inittab...*/
3) /etc/inittab
s3c2410_serial1::respawn:-/bin/sh #/*注意s3c2410上串口的設(shè)備名稱是/dev/s3c2410_serial[0..3]*/
4) /etc/mdev.conf
#空文件,有就行,用了在說吧
5) 啟動(dòng)信息
Open ARM www.linuxforum.net akae
Start mdev...
selected clock c0239b70 (pclk) quot 26, calc 115740
init started: Busyselected clock c0239b70 (pclk) quot 26, calc 115740
Box v1.10.1 (2008-04-19 15:27:01 CST)
command='-/bin/sh ' action=2 tty='/dev/s3c2410_serial1'
starting pid 229, tty '/dev/s3c2410_serial1': '-/bin/sh '
BusyBox v1.10.1 (2008-04-19 15:27:01 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
#
6) Trouble shoot
(1) /bin/sh: can't access tty; job control turned off
busybox 通過系統(tǒng)控制臺(tái)來做些工作, 如果我們的shell啟動(dòng)在 /dev/console (5,1)上, tty_io.c 函數(shù)open中noctty就被設(shè)置成1,導(dǎo)致這個(gè)問題,具體原因還不知道.總之要啟動(dòng)在一個(gè)真實(shí)的串口就沒有關(guān)系.
解決方法可以通過busybox的init指定shell的設(shè)備, 注意, S3C2410上, 串口1是s3c2410_serial1.終就是在etc/inittab中加入下面一句話就可以了:
s3c2410_serial1::respawn:-/bin/sh #/*注意s3c2410上串口的設(shè)備名稱是/dev/s3c2410_serial[0..3]*/
(2)busybox的init腳本問題 no tty3 tty4 之類
可以先啟動(dòng)mdev, (mdev -s), 然后運(yùn)行init就可以了.
就是讓/dev/tty0-4 都存在即可.... (具體原因未知)
(3) 加載mtdblock3 的jffs2文件系統(tǒng)出現(xiàn)下述信息:
jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0001001c: 0x3c04
建議:將此分區(qū)數(shù)據(jù)清除,更近一步,加載一個(gè)image到這個(gè)分區(qū).
(4)下載了新內(nèi)核,ramdisk找不到了
runaddr 和 ramdisk距離太近, 內(nèi)核解壓縮后覆蓋了ramdisk... ft
--------------------------------------------------------------------------------
16.4 busy box的init 和各種腳本的分工
看到上面的腳本...寫的不咋樣,甚至都不符合各種配置文件的具體分工,很不規(guī)整. 下面來研究一個(gè)比較規(guī)整的方案. 下面是google結(jié)果(看busybox init的代碼?,人生苦短,以后把)
1)在串口上啟動(dòng) shell
為了避開在busybox "job control"的那個(gè)問題, 把/dev/console 直接改成 s3c2410_serial1的設(shè)備號(hào),就是:
mknod -m 666 console c 204 65 #204, 64,65,66
然后直接用busybox _install目錄下的linuxrc,到busybox的一個(gè)軟連接,也是啟動(dòng)init.
2)busybox init的流程
簡(jiǎn)單說,就是執(zhí)行inittab里指定的命令.具體流程如下:
a)如果沒有/etc/inittab,則默認(rèn)執(zhí)行/etc/init.d/rcS (見下面說明)
b)執(zhí)行inittab中動(dòng)作類型為wait的命令
c)執(zhí)行inittab中動(dòng)作類型是once的命令
d)然后進(jìn)入等待和循環(huán)執(zhí)過程:
.如果一動(dòng)作為respawn類型的進(jìn)程退出了,就重新啟動(dòng)它.
.如果動(dòng)作為askfirst類型的程序退出了,也要重新啟動(dòng)它,但是先詢問用戶.
busybox的inittab的語法格式是: (examples/inittab)
id:runlevels:action:process
id: busybox 用id域指定程序運(yùn)行的控制臺(tái). 如果是串口控制臺(tái),id域
runlevels: busybox根本不使用它
action: 字段定義了該進(jìn)程應(yīng)該運(yùn)行在何種狀態(tài)下:
sysinit :boot time時(shí)執(zhí)行 (此運(yùn)行init的時(shí)候?)
respawn :init 監(jiān)視其啟動(dòng)的進(jìn)程,如果退出了,這種類型的進(jìn)程需要重新啟動(dòng)
askfirst:和respawn差不多,就是要按下回車鍵才運(yùn)行
wait : 要等待其運(yùn)行完成
once : 只運(yùn)行一次
ctrlaltdel : 這個(gè)組合鍵按下時(shí)啟動(dòng).
busybox init的默認(rèn)動(dòng)作:
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
如果/dev/console 不是串口終端則繼續(xù)運(yùn)行:
tty2::askfirst:/bin/sh
3) inittab
#在pc機(jī)上這個(gè)inittab本來是定義運(yùn)行級(jí)別來著,這里就簡(jiǎn)單這么寫吧
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh #我們把console換成了串口
4)etc/init.d/rcS
#!/bin/sh
echo
echo "Open ARM AKAE-www.linuxforum.net "
echo
mount -t proc /proc /proc
mount -t devpts devpts /dev/pts
echo "Start mdev..."
# read the busybox docs: mdev.txt, you need config your kernerl with hotplug surport
mount -t sysfs sysfs /sys
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
5)一個(gè)空的/etc/mdev.conf文件先對(duì)付著
6)/etc/fstab也沒有做
--------------------------------------------------------------------------------
17.內(nèi)核啟動(dòng)信息分析
Uncompressing Linux...................................................... done
, booting the kernel. [archarmootcompressedmisc.c: decompress_kernel()]
Linux version 2.6.24.4 (root@localhost.localdomain) (gcc version 4.1.2) #7
Tue Apr 15 07:50:25 CST 2008 [init/main.c :start_kernel]
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177 [start_kernel->setup_arch->setup_processor]
Machine: SMDK2410 [setup_arch->setup_machine]
Converting old-style param struct to taglist [setup_arch->convert_to_tag_list->..->build_tag_list]
ATAG_INITRD is deprecated; please update your bootloader. [setup_arch->parse_tags->parse_tag_initrd ]
Memory policy: ECC disabled, Data cache writeback [setup_arch->paging_init->build_mem_type_table]
On node 0 totalpages: 16384 [setup_arch->paging_init->bootmem_init_node->free_area_init_node-> calculate_node_totalpages]
DMA zone: 128 pages used for memmap [setup_arch->..->free_area_init_node->free_area_init_core]
DMA zone: 0 pages reserved
DMA zone: 16256 pages, LIFO batch:3
Normal zone: 0 pages used for memmap
Movable zone: 0 pages used for memmap
CPU S3C2440A (id 0x32440001) [setup_arch->paging_init->devicemaps_init->mdesc->smdk2410_map_io->s3c24xx_init_io]
S3C244X: core 400.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz [..smdk2410_map_io->cpu_ids->s3c244x_init_clocks]
S3C24XX Clocks, (c) 2004 Simtec Electronics [...s3c244x_init_clocks->s3c24xx_setup_clocks]
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on [...s3c244x_init_clocks->s3c2410_baseclk_add]
CPU0: D VIVT write-back cache [setup_arch->cpu_init->dump_cpu_info]
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256 [start_kernel->build_all_zonelists]
Kernel command line: root=/dev/ram init=/linuxrc initrd=0x30a00000,0x00100000 [start_kernel, print cmd line ]
console=ttySAC1,115200 mem=65536K devfs=mount
irq: clearing pending ext status 000dff00 [start_kernel->init_IRQ->init_arch_irq(mdesc->init_irq)->s3c24xx_init_irq]
irq: clearing pending ext status 00001000 [init_arch_irq 在arm體系下是一個(gè)函數(shù)指針,setup_arch初始化其為mdesc->init_irq]
irq: clearing subpending status 0000009a
irq: clearing subpending status 00000092
PID hash table entries: 256 (order: 8, 1024 bytes) [start_kernel->pidhash_init]
timer tcon=00090000, tcnt a2c1, tcfg 00000200,00000000, usec 00001eb8 [start_kernel->time_init->system_timer.init->
s3c2410_timer_init->s3c2410_timer_setup]
[setup_arch中初始化全局函數(shù)指針 system_timer = mdesc->timer ,既s3c24xx_timer, arch/arm/plat-s3c24xx/timer.c]
Console: colour dummy device 80x30 [start_kernel->console_init-> via lds __con_initcall_start ->vt:con_init]
selected clock c0239b70 (pclk) quot 26, calc 115740 [console_initcall(s3c24xx_serial_initconsole)->register_console->console.setup->
s3c24xx_serial_console.setup(s3c24xx_serial_console_setup)->uart_set_options->s3c24xx_serial_set_termios->s3c24xx_serial_getclk]console [ttySAC1] enabled [console_initcall(s3c24xx_serial_initconsole)->register_console]
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes) [start_kernel->vfs_caches_init_early]
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total [start_kernel->mem_init]
Memory: 61440KB available (2060K code, 248K data, 108K init)
Calibrating delay loop... 199.47 BogoMIPS (lpj=498688) [start_kernel->calibrate_delay]
Mount-cache hash table entries: 512 &n bsp; [start_kernel-> vfs_caches_init->mnt_init]
CPU: Testing write buffer coherency: ok [start_kernel->check_bugs->check_writebuffer_bugs]
net_namespace: 64 bytes [start_kernel->rest_init->kernel_init->do_basic_setup->pure_initcall(net_ns_init)]
NET: Registered protocol family 16 [core_initcall(netlink_proto_init)->sock_register]
S3C2440: Initialising architecture [arch_initcall(s3c_arch_init)->(cpu->init())->cpu_ids->s3c2410_init]
S3C2440: IRQ Support [arch_initcall(s3c2440_irq_init)->sysdev_driver_register->drv.add()->s3c2440_irq_add]
S3C2440: Clock Support, DVS off [arch_initcall(s3c24xx_clk_driver)->s3c2440_clk_driver.s3c2440_clk_add]
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics [arch_initcall(s3c2410_dma_drvinit)->sysdev_driver_register->
DMA channel 0 at c4800000, irq 33 c2410_dma_driver.s3c2410_dma_add->s3c2410_dma_init->s3c24xx_dma_init]
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
usbcore: registered new interface driver usbfs [subsys_initcall(usb_init)->usb_register(&usbfs_driver)->usb_register_driver]
usbcore: registered new interface driver hub [subsys_initcall(usb_init)->usb_hub_init(&hub_driver)->usb_register_driver]
usbcore: registered new device driver usb [subsys_initcall(usb_init)->usb_register_device_driver(&usb_generic_driver)]
NET: Registered protocol family 2 [fs_initcall(inet_init)->sock_register]
IP route cache hash table entries: 1024 (order: 0, 4096 bytes) [fs_initcall(inet_init)->ip_init->ip_rt_init ]
TCP established hash table entries: 2048 (order: 2, 16384 bytes) [fs_initcall(inet_init)->ip_init->tcp_init]
TCP bind hash table entries: 2048 (order: 1, 8192 bytes) [fs_initcall(inet_init)->ip_init->tcp_init]
TCP: Hash tables configured (established 2048 bind 2048) [fs_initcall(inet_init)->ip_init->tcp_init]
TCP reno registered [fs_initcall(inet_init)->ip_init->tcp_init->tcp_register_congestion_control]
checking if image is initramfs...<5>it isn't (no cpio magic); looks like an initrd [rootfs_initcall(populate_rootfs)]
Freeing initrd memory: 1024K [rootfs_initcall(populate_rootfs)->free_initrd->free_initrd_mem->free_area]
NetWinder Floating Point Emulator V0.97 (extended precision) [module_init(fpe_init);]
JFFS2 version 2.2. (NAND) 漏 2001-2006 Red Hat, Inc. [module_init(init_jffs2_fs);]
io scheduler noop registered [module_init(noop_init)->elv_register]
io scheduler anticipatory registered (default) [module_init(as_init)->elv_register]
io scheduler deadline registered [module_init(deadline_init)->elv_register]
io scheduler cfq registered [module_init(cfq_init)->elv_register]
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing enabled [ module_init(serial8250_init)]
s3c2440-uart.0: s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2440 [module_init(s3c24xx_serial_modinit)->s3c2440_serial_init->
s3c2440-uart.1: s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2440 s3c2440_serial_probe->uart_add_one_port->
s3c2440-uart.2: s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2440 uart_configure_port->uart_report_port]
RAMDISK driver initialized: 2 RAM disks of 4096K size 1024 blocksize [module_init(rd_init);]
loop: module loaded [module_init(loop_init);]
S3C24XX NAND Driver, (c) 2004 Simtec Electronics [module_init(s3c2410_nand_init);]
s3c2440-nand s3c2440-nand: Tacls=3, 30ns Twrph0=7 70ns, Twrph1=3 30ns [s3c2440_nand_probes->3c2410_nand_inithw]
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit) [ form above...->nand_scan_ident nand_get_flash_type]
Scanning device for bad blocks [s3c24xx_nand_probe->nand_scan ->nand_scan_tail->chip->scan_bbt:..->create_bbt]
Creating 4 MTD partitions on "NAND 64MiB 3,3V 8-bit": [s3c2410_nand_add_partition->add_mtd_partitions]
0x00000000-0x00030000 : "Boot Agent"
0x00030000-0x00200000 : "kernel"
0x00200000-0x02000000 : "ramfs"
0x02000000-0x04000000 : "extfs"
ohci_hcd: 2006 August 04 USB 1.1 'Open' Host Controller (OHCI) Driver
ohci_hcd: block sizes: ed 64 td 64
s3c2410-ohci s3c2410-ohci: s3c2410_start_hc:
s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
s3c2410-ohci s3c2410-ohci: created debug files
s3c2410-ohci s3c2410-ohci: OHCI controller state
s3c2410-ohci s3c2410-ohci: OHCI 1.0, NO legacy support registers
s3c2410-ohci s3c2410-ohci: control 0x083 HCFS=operational CBSR=3
s3c2410-ohci s3c2410-ohci: cmdstatus 0x00000 SOC=0
s3c2410-ohci s3c2410-ohci: intrstatus 0x00000004 SF
s3c2410-ohci s3c2410-ohci: intrenable 0x8000005a MIE RHSC UE RD WDH
s3c2410-ohci s3c2410-ohci: hcca frame #001e
s3c2410-ohci s3c2410-ohci: roothub.a 02001202 POTPGT=2 NOCP NPS NDP=2(2)
s3c2410-ohci s3c2410-ohci: roothub.b 00000000 PPCM=0000 DR=0000
s3c2410-ohci s3c2410-ohci: roothub.status 00008000 DRWE
s3c2410-ohci s3c2410-ohci: roothub.portstatus [0] 0x00000100 PPS
s3c2410-ohci s3c2410-ohci: roothub.portstatus [1] 0x00000100 PPSu
sb usb1: default language 0x0409
usb usb1: uevent
usb usb1: usb_probe_device
usb usb1: configuration #1 chosen from 1 choice
usb usb1: adding 1-0:1.0 (config #1, interface 0)
usb 1-0:1.0: uevent
hub 1-0:1.0: usb_probe_interface
hub 1-0:1.0: usb_probe_interface - got id
hub 1-0:1.0: USB hub found
s3c2410-ohci s3c2410-ohci: s3c2410_hub_control(c3c2b400,0xa006,0x2900,0x0000,c3c19a84,000f)
hub 1-0:1.0: 2 ports detected
hub 1-0:1.0: standalone hub
hub 1-0:1.0: no power switching (usb 1.0)
hub 1-0:1.0: no over-current protection
hub 1-0:1.0: power on to power good time: 4ms
s3c2410-ohci s3c2410-ohci: s3c2410_hub_control(c3c2b400,0xa000,0x0000,0x0000,c3c19a40,0004)
hub 1-0:1.0: local power source is good
hub 1-0:1.0: trying to enable port power on non-switchable hub
s3c2410-ohci s3c2410-ohci: s3c2410_hub_control(c3c2b400,0x2303,0x0008,0x0001,c3c19a40,0000)
s3c2410-ohci s3c2410-ohci: s3c2410_hub_control(c3c2b400,0x2303,0x0008,0x0002,c3c19a40,0000)
hub 1-0:1.0: state 7 ports 2 chg 0000 evt 0000
usb usb1: new device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: S3C24XX OHCI
usb usb1: Manufacturer: Linux 2.6.24.4 ohci_hcd
usb usb1: SerialNumber: s3c24xx
s3c2410_udc: debugfs dir creation failed -19
s3c2410-ohci s3c2410-ohci: s3c2410_hub_control(c3c2b400,0xa300,0x0000,0x0001,c3c6fe30,0004)
s3c2410-ohci s3c2410-ohci: s3c2410_hub_control(c3c2b400,0xa300,0x0000,0x0002,c3c6fe30,0004)
mice: PS/2 mouse device common for all mice [module_init(mousedev_init);]
S3C24XX RTC, (c) 2004,2006 Simtec Electronics [module_init(s3c_rtc_init);]
s3c2440-i2c s3c2440-i2c: slave address 0x10 [s3c2440_i2c_driver.s3c24xx_i2c_probe->s3c24xx_i2c_init]
s3c2440-i2c s3c2440-i2c: bus frequency set to 390 KHz [同上]
s3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapter [s3c2440_i2c_driver.s3c24xx_i2c_probe]
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics [module_init(watchdog_init);]
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
TCP cubic registered [module_init(cubictcp_register)->tcp_register_congestion_control]
drivers/rtc/hctosys.c: unable to open rtc device (rtc0) [late_initcall(rtc_hctosys)]
RAMDISK: Compressed image found at block 0 [kernel_init->prepare_namespace->initrd_load->rd_load_image->identify_ramdisk_image]
VFS: Mounted root (ext2 filesystem). [kernel_init->prepare_namespace->mount_root->mount_block_root->do_mount_root]
Freeing init memory: 108K
selected clock c0239b70 (pclk) quot 26, calc 115740 /*以下內(nèi)容為busybox產(chǎn)生*/
selected clock c0239b70 (pclk) quot 26, calc 115740
init started: BusyBox v1.10.1 (2008-04-19 15:27:01 CST)
selected clock c0239b70 (pclk) quot 26, calc 115740
starting pid 225, tty '': '/etc/init.d/rcS'
Open ARM AKAE-www.linuxforum.net
Start mdev...
mount: mounting sysfs on /sys failed: Device or resource busy
selected clock c0239b70 (pclk) quot 26, calc 115740
starting pid 236, tty '/dev/console': '-/bin/sh '
BusyBox v1.10.1 (2008-04-19 15:27:01 CST) built-in shell (msh)
Enter 'help' for a list of built-in commands.
--------------------------------------------------------------------------------
18 .Uart devices register and driver select
1.machine和cpu的檢測(cè)與uart設(shè)備名的設(shè)置
CPU S3C2440A (id 0x32440001) [setup_arch->paging_init->devicemaps_init->mdesc->smdk2410_map_io->s3c24xx_init_io]
mdesc是SMDK2410,smdk2410_map_io->s3c24xx_init_io根據(jù)cpuid設(shè)置arm/plat-s3c24xx的全局變量cpu.然后mdk2410_map_io
調(diào)用s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));通過(cpu->init_uarts)(cfg, no);注冊(cè)cpu特的定的uart資源. cpu_ids在arch/arm/plat-s3c24xx/cpu.c中,其中2440a的uart初始化函數(shù)是:
void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
}
void __init s3c24xx_init_uartdevs(char *name,
struct s3c24xx_uart_resources *res,
struct s3c2410_uartcfg *cfg, int no)
{
struct platform_device *platdev;
struct s3c2410_uartcfg *cfgptr = uart_cfgs;
struct s3c24xx_uart_resources *resp;
int uart;
memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
platdev = s3c24xx_uart_src[cfgptr->hwport];
resp = res + cfgptr->hwport;
s3c24xx_uart_devs[uart] = platdev; /*uart的platform設(shè)備*/
platdev->name = name; /*platform 設(shè)備名稱初始化為 "s3c2440-uart" */
platdev->resource = resp->resources;
platdev->num_resources = resp->nr_resources;
platdev->dev.platform_data = cfgptr;
}
nr_uarts = no;
}
然后arch_initcall(s3c_arch_init);-> platform_add_devices(s3c24xx_uart_devs, nr_uarts);注冊(cè)設(shè)備到
platform_bus_type.
2.console 設(shè)備初始化
selected clock c0239b70 (pclk) quot 26, calc 115740 [console_initcall(s3c24xx_serial_initconsole)->register_console->console.setup->s3
S3C2440 從cross-tools到 linux2.6.24.4
更新時(shí)間: 2008-09-09 09:07:09來源: 粵嵌教育瀏覽量:2150
粵嵌動(dòng)態(tài)
推薦閱讀
- ·北京朝歌數(shù)碼科技股份有限公司專場(chǎng)招聘
- ·深圳研賽自動(dòng)化設(shè)備公司專場(chǎng)招聘(長(zhǎng)沙校區(qū))
- ·深圳市興禾自動(dòng)化股份有限公司專場(chǎng)招聘(長(zhǎng)沙校區(qū))
- ·中山市弘億實(shí)業(yè)有限公司專場(chǎng)招聘會(huì)
- ·東莞市德聲實(shí)業(yè)有限公司專場(chǎng)招聘
- ·深圳華創(chuàng)智聯(lián)電子有限公司專場(chǎng)招聘
- ·廣州2512全網(wǎng)運(yùn)營(yíng)就業(yè)班
- ·廣州2511嵌入式開發(fā)就業(yè)班
- ·深圳市領(lǐng)世達(dá)科技有限公司專場(chǎng)招聘
- ·廣州2510嵌入式開發(fā)就業(yè)班