嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(六)
呵呵,相信此时的你拨云见日,茅塞顿开了吧!这个入口地址就是0x30008000,这也正是为什么u-boot一定要使用uImage的格式来启动内核的原因之一。注意:这里有个kernel入口地址0x30008000,在上面还提到一个u-boot参数链表在内存中的地址0x30000100,试想如果这里指定的kernel入口地址覆盖了参数链表的地址会怎么样?
好了,把上面每个步骤从下往上看就可以知道u-boot参数项在u-boot端的传递的整个流程了,那么,接下来再分析u-boot参数项在kernel端是怎样接收的。
kernel启动的流程如下图所示:
在文件arch/arm/boot/compressed/head.S中,start是zImage的起始点,部分代码如下:
start:
wont_overwrite: ...... call_kernel: ...... |
首先,将u-boot传递过来的r1(机器码)、r2(参数链表在内在中的物理地址)分别保存到ARM寄存器r7、r8中,再将r7作为参数传递给解压函数decompress_kernel(),在这个解压函数中再将r7传递给全局变量__machine_arch_type,然后在跳转到vmlinux入口之前再将r7、r8还原到r1、r2中。
在arch/arm/kernel/head.S文件中,内核vmlinux入口的部分代码如下:
ENTRY(stext) ...... |
首先从ARM特殊寄存器(CP15)中获得ARM内核的类型,从处理器内核描述符(proc_info_list)表(__proc_info_begin—__proc_info_end)中查询有无此ARM 内核的类型,如果无就出错退出。处理器内核描述符定义在include/asm-arm/procinfo.h中,具体的函数实现在 arch/arm/mm/proc-xxx.S中,在编译连接过程中将各种处理器内核描述符组合成表。接着从机器描述(machine_desc)表(__mach_info_begin—__mach_info_end)中查询有无r1寄存器指定的机器码,如果没有就出错退出,所以这也说明了为什么在u-boot中指定的机器码一定要与内核中指定的一致,否则内核就无法启动。机器编号mach_type_xxx在arch/arm/tools/mach-types文件中说明,每个机器描述符中包括一个唯一的机器编号,机器描述符的定义在 include/asm-arm/mach/arch.h中,具体实现在arch/arm/mach-xxxx文件夹中,在编译连接过程中将基于同一种处理器的不同机器描述符组合成表。例如,S3C2440处理器的机器码为1008的机器描述符如下所示:
MACHINE_START(SMDK2440, |
最后就打开MMU,并跳转到 init/main.c的start_kernel()初始化系统。函数start_kernel()的部分代码如下:
asmlinkage |
函数setup_arch在arch/arm/kernel/setup.c中实现,部分代码如下:
void |
setup_processor()函数从处理器内核描述符表中找到匹配的描述符,并初始化一些处理器
变量。setup_machine()用机器编号(在解压函数decompress_kernel 中被赋值)作为参数返回机器描述符。从机器描述符中获得内核参数的物理地址,赋值给tags 变量。然后调用parse_tags()函数分析内核参数链表,把各个参数值传递给全局变量。这样内核就收到了u-boot传递的参数。
Linuxu-boot244 相关文章:
- 嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(四)(11-20)
- 嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(五)(11-20)
- 嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(一)(11-20)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)