UBOOT引导Linux内核及向内核传递参数的方式
一直以来没有想过有什么好的办法通过寄存器向内核传递参数,直到今天读UBOOT的实现方式。 在UBOOT中,引导内核最常用的方法是bootm命令,bootm命令可以引导“UBOOT格式”的内核。先花点时间了解一下什么是“UBOOT格式”的内核吧:用UBOOT自带的mkimage命令生成的内核称为"UBOOT"格式的内核。以下面这条命令为例: mkimage -n "Kernel 2.4.18" -A arm -O linux -T kernel -C none -a 30007fc0 -e 30008000 -d 4020.bin vmlinux-2.4.18.img 其中与内核引导最密切的是-e 30008000,也就是内核的入口地址。其它参数可以参考帮助信息。其它UBOOT格式的内核与原来相比,只是进行(可选)了压缩,并在前面加了一个0x40大小的头。这个头里放了内核的位置(0x30007fc0)和入口地址(0x30008000)和其它信息。 bootm命令执行时,先对头部信息等进行校验,然后把头信息放到一个结构里面。最后根据内核类型调用相应的启动函数。对于Linux而言就是do_bootm_linux,在启动函数里面,有这么一个操作:theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);,这是最关键的一个操作,将内核的入口地址0x30008000赋给了theKernel,在启动函数的最后,使用theKernel (0, bd->bi_arch_number, bd->bi_boot_params);启动内核。 根据传参规范,三个变量分别用r0,r1,r2传给内核,这样就巧妙地利用了函数指针进行了参数传递,实在是精妙!上面讲完了内核的引导及传参,需要引起注意的就是在使用mkimage命令生成内核时,-e后面的地址要比-a后面的地址偏移0x40,原因很简单,就不在细说了。
先后排除了几个问题,总算将ZY版的Linux2.4.18引导起来了。 引导使用的是bootm命令,原来不成功是因为bootargs没有设好,Linux已经正常启动,串口却没有输出。反复试验,把能排除的原因都排除之后,才发现是bootargs不对。由于对Linux启动不了解,浪费了不少时间...
如果ZY看到这篇帖子,看一下这个问题:为什么串口输出那么多waiting? 我印象中是在等时钟滴答的时候才会有,是不是UBOOT中使用了Timer0,你在使用Timer0的时候没有对它进行复位? Linux version 2.4.18-rmk7 (root@localhost.localdomain) (gcc version 2.95.3 20010315 (release)) #28 Thu Apr 24 11:15:47 CST 2008 CPU: ARM ARM720T revision 2 Machine: SEP3221 BASED Kernel command line: root=/dev/ram0 console=tty0 console=ttyS0,9600 init=/linuxrc Console: colour dummy device 80x30 Calibrating delay loop... waiting...waiting...waiting...waiting...waiting...waiting...waiting...waiting...waiting...waiting...waiting...waiting...waiting...waiting...waiting...waiting...
(以下省略N千个waiting...)
26.16 BogoMIPS Memory: 8MB = 8MB total Memory: 4672KB available (1008K code, 224K data, 68K init) POSIX conformance testing by UNIFIX ttyS00 at 0xe0005000 (irq = 24) is a 16450 NET4 RAMDISK: Couldn't find valid RAM disk image starting at 0. Freeing initrd memory: 2048K Kernel panic: VFS: Unable to mount root fs on 01:00
为了避免上面出现的情况,在int cleanup_before_linux (void)函数中,添加以下代码: T1CR = 0x0; T1LCR = 0x0; 达到复位Timer0的目的,果然再次用bootm命令引导Linux的时候没有再出现这么多的waiting...。
PS:Linux镜像是在使用bootm命令之前通过ICE下载到0x30007fc0地址的,将来可以烧写到Flash中,由程序搬运到将位置。由于Norflash只有2M,不能完整地放下UBOOT、Linux内核及文件系统,下面的重点可能是NandFlash的驱动...
U-Boot 1.1.4 (Aug 2 2008 - 11:03:41)
U-Boot code: 30700000 -> 30717F2C BSS: -> 3071C320
IRQ Stack: 306deb74
FIQ Stack: 306dfb74
RAM Configuration:
Bank #0: 30000000 8 MB
Flash: 2 MB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 5 4 3 2 1 0
SEP4020=>bootm
## Booting image at 30007fc0 ...
Image Name: Kernel 2.4.18
Created: 2008-08-01 13:40:42 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1164515 Bytes = 1.1 MB
Load Address: 30007fc0
Entry Point: 30008000
Verifying Checksum ... OK
XIP Kernel Image ... OK
Starting kernel ...
booting linux from 0x30008000Linux version 2.4.18-rmk7 (root@localhost.localdomain) (gcc version 2.95.3 20010315 (release)) #28 Thu Apr 24 11:15:47 CST 2008 CPU: ARM ARM720T revision 2 Machine: SEP3221 BASED Kernel command line: root=/dev/ram0 console=tty0 console=ttyS0,9600 init=/linuxrc Console: colour dummy device 80x30 Calibrating delay loop... waiting...waiting...waiting...waiting...waiting...26.16 BogoMIPS Memory: 8MB = 8MB total Memory: 4672KB available (1008K code, 224K data, 68K init) POSIX conformance testing by UNIFIX ttyS00 at 0xe0005000 (irq = 24) is a 16450 NET4 RAMDISK: Couldn't find valid RAM disk image starting at 0. Freeing initrd memory: 2048K Kernel panic: VFS: Unable to mount root fs on 01:00
引导RAMFS方法
如果使用UBOOT引导内核,同时希望将文件系统一并引导,bootm命令后面需要跟两个参数,第一个参数是内核所在的地址,第二个参数是文件系统所在的位置,如bootm 30007fc0 30300000 上面说的引导文件系统是利用了bootloader向内核标准传参方法,如果已经在内核将诸如机器号,文件系统地址等全部写死的话,则不需要进行上述操作,只需将PC切换到内核所在地址就可以了.
关于bootload向内核传递参数

浙公网安备 33010602011771号