linux内核启动汇编部分详解
参考文档:https://blog.csdn.net/haoge921026/article/details/46785995
总体来说汇编部分做了三件事:校验,设置页表和开mmu,设置栈和一些全局变量
具体内容如下:
1. 设置cpu为svc模式,禁止总中断
2. 读取ARM协处理器cp15的c0寄存器获得CPU ID
CPU ID格式如下:
---------------------------------------------------------------------
厂商编号 | 产品子编号 | ARM 体系版本号 | 产品主编号 |处理器版本号 |
---------------------------------------------------------------------
查手册: cotex_a8_r3p2_trm.pdf 3.2.2节可以获得如下信息
厂商编号 [31:24] : 0x41 表示ARM公司
产品子编号 [23:20] : 0x3
ARM体系版本号 [19:16] : 0x1->ARMv4, ...,0xF ->ARMv7
产品主编号 [15: 4] : 0xc08->CortexA8
处理器版本号 [ 3: 0] : 0x2
3. 查找cpuid对应的procinfo结构体,没找到则打印出错信息,进入死循环
4. 查找开发板对应的machinfo结构体,开发板的ID由uboot通过r1传入,未找到则打印出错信息进入死循环
5. 检查atag的首个tag是否为ATAG_CORE,大小是否正确,指针由r2传入,不正确则让r2为0(uboot传入的地址为0x3000 0100)
6. 在0x30004000~0x30008000的16k空间创建段式映射页表,将300映射到300,将内核代码的链接地址进行映射(及c00~内核结束映射到
300~结束),将串口的虚拟地址(FE0)映射到串口物理地址(E29)用于串口打印信息
7. 调用procinfo结构体的__v7_setup函数用于清除cache,设置cp15一些控制位,将页表基地址写入了cp15的c2寄存器
8. 调用__enable_mmu设置cp15域访问(c3),地址转换表基地址(c2),开mmu(c1)
9. 进入__mmap_switched清bss,设置栈和全局变量:
sp=&init_thread_union + THREAD_START_SP
processor_id = cpu_id
__machine_arch_type = machine_id
__atags_pointer = atags_pointer
将控制信息(c1)保存到cr_alignment (打印出来是10c53c7f)
10. 跳转start_kernel