首页 > 技术文章 > linux内核启动汇编部分详解

genshu123 2019-07-20 07:40 原文

参考文档: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 

 

推荐阅读