标签:__ head 01 dtb machine 内核 bootloader id
uboot把设备树文件传给内核,内核怎么处理这些设备树文件呢?需要从内核的第一个执行文件head.s开始分析。
bootloader启动内核时,会设置r0,r1,r2三个寄存器,
r0一般设置为0;
r1一般设置为machine id (在使用设备树时该参数没有被使用);
r2一般设置ATAGS或DTB的开始地址
machine_id有什么作用呢?
一个内核比如说uImage可以支持多种单板:
smdk2410
smdk2440
jz2440
...
这些板子稍有差别,比如说smdk2410和smdk2440,虽然cpu大部分是兼容的,但是它们之间也有略微的差异。再比如说,smdk2440和jz2440可能使用的晶振都不一样。因此对每种单板来说,它里面应该有不同的初始化函数。
每种单板在内核中都有一个machine_desc结构体(机器描述结构体):
在该结构体中有初始化函数init,nr
怎么告诉内核现在是在哪种单板上运行呢?
此时就需要从uboot中传一些参数给内核,uboot是我们自己写的,它有办法知道内核在什么板子上运行。
把machine_id传给内核,内核启动的时候根据machine_id来比较machine_desc结构体中的nr,如果相等,那么调用对应的init函数
以前没有用设备树时,需要bootloader给内核传入一个machine_id,现在使用设备树,这个machine_id就不需要设置了
以前uboot向内核传参时,需要在内存中构造一系列的atag,可以把ATAGs的首地址传给内核,内核会从ATAGS里面得到那些参数。
bootloader给内核传递的参数时有2种方法:
ATAGS 或 DTB
内核中head.s所做的工作:
a. __lookup_processor_type : 使用汇编指令读取CPU ID, 根据该ID找到对应的proc_info_list结构体(里面含有这类CPU的初始化函数、信息)
b. __vet_atags : 判断是否存在可用的ATAGS或DTB
c. __create_page_tables : 创建页表, 即创建虚拟地址和物理地址的映射关系
d. __enable_mmu : 使能MMU, 以后就要使用虚拟地址了
e. __mmap_switched : 上述函数里将会调用__mmap_switched
f. 把bootloader传入的r2参数, 保存到变量__atags_pointer中
g. 调用C函数start_kernel
head.S/head-common.S :
把bootloader传来的r1值, 赋给了C变量: __machine_arch_type
把bootloader传来的r2值, 赋给了C变量: __atags_pointer // dtb首地址
标签:__,head,01,dtb,machine,内核,bootloader,id 来源: https://www.cnblogs.com/-glb/p/12347102.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。