在测试过程中,可以通过at91rm9200内置的bootloader程序加载loader程序以及u-boot程序,然后通过强大的u-boot功能可以通过网络或者串口加载启动所需的linux kernel以及文件系统。当程序调试成功之后,需要将程序固化到Flash存储介质中,或者也可以采用网络启动的方法。最终不管采用本地Flash启动还是远程网络启动,其设计思想是保持一致的,下面对本地Flash(通常指Nor Flash)启动方法进行说明。
提起本地Flash启动,实际上存在很多种方法,如果将Linux程序直接固化到Flash的头部,也是可以启动的,但是Linux程序需要设置好启动命令等参数,需要知道文件系统在什么位置,文件系统的挂载点是什么等参数,这些参数的设置在make menuconfig->boot options中进行设置。当然一个更加通用的方法是u-boot引导操作系统,Linux的启动命令通过环境变量进行设置。
采用u-boot引导Linux首先需要将u-boot程序固化到flash中,通常这也有两种方法,一种是u-boot程序直接固化到flash的头部,系统复位之后直接运行u-boot程序,然后u-boot程序自拷贝到对应的内存位置,提供相应服务;另一种方法是通过boot程序引导u-boot,并且将u-boot程序拷贝到具体内存位置,然后将CPU交给u-boot,提供相应服务。第二种方法可以将u-boot程序进行压缩处理,占用相对较小的Flash存储空间,所以通常都采用第二种方法,即通过boot程序引导u-boot。
u-boot程序有两种工作状态,一种为自动引导模式;一种为用户操作模式。如果用户没有定义bootcmd环境变量,那么直接进入用户操作模式;如果定义了bootcmd,那么u-boot将直接运行bootcmd,但是在运行bootcmd时会等待bootdelay时间,bootdelay也是一个环境变量,由用户设置。说到这里,我们应该知道环境变量的重要性了,u-boot会根据这些环境变量进行操作系统自启动,操作系统的位置参数、文件系统的位置参数、u-boot与操作系统之间的交互参数都可以存储在环境变量中。所以,在自启动模式下,需要设置好u-boot的环境变量,我设置的环境变量参考如下:
baudrate=115200 /* 串口通信的波特率 */
/* Linux的启动命令参数 */
bootargs=root=/dev/ram rw initrd="0x21100000",<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />4M init="/linuxrc" console="ttyS0",115200
/* 文件系统的拷贝命令,从Flash拷贝到内存 */
fs=cp.b 0x10200000 0x21100000 0x2fffff
/* 操作系统的拷贝命令,从Flash拷贝到内存 */
kernel=cp.b 0x10100000 0x21000000 0xfffff
ethaddr=01:02:03:04:05:06
serverip=10.10.21.253
ipaddr=10.10.21.252
/* 启动命令 */
bootcmd=run boot
/* 具体的启动操作 */
boot=run kernel;run fs;bootm 0x21000000
/* 自启动时的延迟参数 */
bootdelay=5
stdin=serial
stdout=serial
stderr=serial
从上述环境变量的定义中,我们知道u-boot启动之后调用run boot命令,run boot命令分为三大步骤:首先run kernel,将Linux kernel从flash中拷贝到内存,当然也可以通过网络tftp到内存;然后run fs,将文件系统从flash中拷贝到内存;最后通过bootm启动linux kernel。从这个地方我们可以看出,通过这种方法不仅可以从Flash中启动Linux,也可以从Nand Flash、网络服务器中启动Linux Kernel,这种方法是通用的。
从Flash中启动Linux,还有一点需要注意,Flash需要进行合理的分区,环境变量中的具体地址与Flash的分区息息相关。下图是我采用的Flash(采用Intel的E28F128芯片)分区方法:
用户377235 2013-5-13 08:45
用户150547 2009-1-3 17:23
用户147174 2008-12-29 18:19