uboot中执行theKernel函数后,kernel正式启动。如下函数,我们发现有3个参数。
1. 参数 0;
2. 参数machid;
如下code 中获取machid, gd是个全局变量.
2.1 bi_arch_number是board_info中的一个元素,含义是:开发板的机器码。所谓机器码就是uboot给这个开发板定义的一个唯一编号。
2.2 机器码的主要作用就是在uboot和linux内核之间进行比对和适配. uboot中配置的这个机器码,会作为uboot给linux内核的传参的一部分传给linux内核,内核启动过程中会比对这个接收到的机器码,和自己本身的机器码相对比,如果相等就启动,如果不相等就不启动.
2.3 linux做了个设置:给每个开发板做个唯一编号(机器码),然后在uboot、linux内核中都有一个软件维护的机器码编号。然后开发板、uboot、linux三者去比对机器码,如果机器码对上了就启动,否则就不启动(因为软件认为我和这个硬件不适配)。
3. 参数 bd->bi_boot_params;
3.1 即gd->bd->bi_boot_params
bd_info中另一个主要元素,bi_boot_params表示uboot给linux kernel启动时的传参的参数所在DDR内存地址。
根据以上code可以知道在下x210中gd->bd->bi_boot_params等于 0x3000 0100, 这个内存地址就被分配用来做内核传参了.
uboot给linux内核传参的时候是这么传的:uboot事先将准备好的传参(字符串,就是bootargs)放在内存的一个地址处(就是bi_boot_params),然后uboot就启动了内核(uboot在启动内核时真正是通过寄存器r0 r1 r2来直接传递参数的,其中有一个寄存器中就是bi_boot_params)。内核启动后从寄存器r2中读取bi_boot_params就知道了uboot给我传递的参数到底在内存的哪里。然后自己去内存的那个地方去找bootargs。
3.2 传递参数详解:a list of tagged entries
tag list方式传参,
- struct tag,tag是一个数据结构,在uboot和linux kernel中都有定义tag数据机构,而且定义是一样的。
- tag_header中有这个tag的size和类型编码,kernel拿到一个tag后先分析tag_header得到tag的类型和大小,然后将tag中剩余部分当作一个tag_xxx来处理。
- tag_start与tag_end。kernel接收到的传参是若干个tag构成的,这些tag由tag_start起始,到tag_end结束.
bootargs举例:
bootargs=console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3
console=ttySAC2,115200 控制台使用串口2,波特率115200.
root=/dev/mmcblk0p2 rw 根文件系统在SD卡端口0设备(iNand)第2分区,根文件系统是可读可写的
init=/linuxrc linux的进程1(init进程)的路径
rootfstype=ext3 根文件系统的类型是ext3
内存配置举例:
如何在uboot运行中得知uboot的DDR配置信息?uboot中有一个命令叫bdinfo,这个命令可以打印出gd->bd中记录的所有硬件相关的全局变量的值,因此可以得知DDR的配置信息。
DRAM bank = 0x00000000
-> start = 0x30000000
-> size = 0x10000000
DRAM bank = 0x00000001
-> start = 0x40000000
-> size = 0x10000000
4. 根文件系统(root=)和进程1(init=)
4.1 根文件系统的作用:
根文件系统提供根目录。
进程1存放在根文件系统中
内核启动最后会去装载根文件系统。
总结:根文件系统为操作系统启动提供了很多必备的资源:根目录、进程1. 根文件系统在bootargs 中用root= 来指定根文件系统在哪里的。一般格式是:root=/dev/xxx
(如果是nandflash,则root=/dev/mtdblock2,
如果是inand/sd, 则root=/dev/mmcblk0p2,表示mmc0的第2个分区)
**遗留问题: 存储介质中的分区表uboot怎么告诉kernel呢 **?
如果是nfs的rootfs,则root=/dev/nfs (网络文件系统)
一套linux体系,只有内核本身是不能工作的,必须要rootfs(上的etc目录下的配置文件、/bin /sbin等目录下的shell命令,还有/lib目录下的库文件等•••)相配合才能工作. 几乎可以认为:发行版=内核+rootfs
4.2 进程1-liunxrc
/linuxrc是一个可执行的应用程序
/linuxrc执行时引出用户界面, 进程1(init进程,也就是/linuxrc)是其他所有应用程序进程的祖宗进程
/linuxrc负责系统启动后的配置(/etc)
/linuxrc在嵌入式linux中一般就是busybox
busybox这个程序开发出来就是为了在嵌入式环境下构建rootfs使用的,也就是说他就是专门开发的init进程应用程序. busybox为当前系统提供了一整套的shell命令程序集。譬如vi、cd、mkdir、ls等.