移动笔记本 https://bbs.21ic.com/?179679 [收藏] [复制] [RSS]

日志

Arm linux 启动分析

已有 1912 次阅读2005-10-9 16:02 |个人分类:技术-linux|系统分类:ARM

Arm linux 启动分析(1)


1.概述:


在内核运行之前需要系统引导程序(Bootloader)完成加载内核和一些辅助性的工作,然后跳转到内核代码的起始地址并执行。本文先分析了Bootloader的初始化工作,接着从内核镜像的起始地址进行分析。整个arm linux内核的启动可分为三个阶段:第一阶段主要是进行cpu和体系结构的检查、cpu本身的初始化以及页表的建立等;第二阶段主要是对系统中的一些基础设施进行初始化;最后则是更高层次的初始化,如根设备和外部设备的初始化。


第一阶段的初始化是从内核入口(ENTRY(stext))开始到start_kernel前结束。这一阶段的代码在/arch/arm/head_armv.S中。


2.Bootloader


2.1简介


       本处介绍主要来自内核源代码下的Documentation/arm/Booting文件,适合于arm linux 2.4.18-rmk6及以上版本。


       Bootloader主要作用是初始化一些必要的设备,然后调用内核,同时传递参数给内核。主要完成如下工作:


1.  建立和初始化RAM


2.  初始化一个串口。


3.  检测机器的系统结构。


4.  建立内核的tagged list


5.  调用内核镜像。


2.2功能详细介绍


       1.建立和初始化RAM


              要求:必须


              功能:探测所有的RAM位置和大小,并对RAM进行初始化。


       2.初始化一个串口。


              要求:可选,建议


功能:Bootloader应该初始化并启动一个串口。这可以让内核的串口驱动自动探测哪个串口作为内核的控制台。另外也可以通过给内核传递“console=”参数完成此工作。


       3.检测机器的系统结构。


              要求:必须


功能:Bootloader应该通过某种方法探测机器类型,最后传递给内核一个MACH_TYPE_xxx值,这些值参看linux/arch/arm/tools/mach-types


4.建立内核的tagged list


              要求:必须


功能:Bootloader必须创建和初始化内核的tagged list。一个合法的tagged list开始于ATAG_CORE 并结束于ATAG_NONEATAG_CORE tag可以为空。一个空的ATAG_CORE tagsize字段设为“2(0x00000002)ATAG_NONE size字段必须设为“0”。tagged list可以有任意多的tagBootloader必须至少传递系统内存的大小和位置,以及根文件系统的位置,一个最小化的tagged list应该像如下:


              +-----------+


base -> | ATAG_CORE |  |


        +-----------+  |


        | ATAG_MEM  |  | increasing address


        +-----------+  |


        | ATAG_NONE |  |


        +-----------+  v


tagged list应该放在内核解压时和initrd”bootp”程序都不会覆盖的内存区域。建议放在RAM的起始的16K大小的地方。


5.调用内核镜像。


              要求:必须


功能:可以从flash调用内核,也可以从系统RAM中调用内核。对于后者需要注意,内核使用内核镜像以下的16K内存作为页表,建议把内核起始放在RAM32K处。无论是哪种方法,如下条件必须满足:


- CPU register settings


  r0 = 0,


  r1 = machine type number discovered in (3) above.


  r2 = physical address of tagged list in system RAM.


- CPU mode


  All forms of interrupts must be disabled (IRQs and FIQs)


  The CPU must be in SVC mode.  (A special exception exists for Angel)


- Caches, MMUs


  The MMU must be off.


  Instruction cache may be on or off.


  Data cache must be off.


- The boot loader is expected to call the kernel image by jumping


  directly to the first instruction of the kernel image.


2.3 Skyeye相应说明


    因为Skyeye暂时没有Bootloader,所以以上一些设置必须由Skyeye在初始化的时候自己来完成,如r1的设置等。


3.Head_armv.S分析


3.1 说明


    这个文件是arch/arm/kernel/head-armv.S,用汇编代码完成,是内核最先执行的一个文件。这一段汇编代码的主要作用,是检查cpu idarchitecture number,初始化页表、cpubbs等操作,并跳到start_kernel函数。它在执行前,处理器的状态应满足:


l        r0      - should be 0


l        r1      - unique architecture number


l        MMU     - off


l        I-cache - on or off


l        D-cache – off


3.2 流程


 


3.3 代码详细注释


    (略去一些条件编译的代码)


-------------------------------------------------------------------------------------------------------------------


/*


 * We place the page tables 16K below TEXTADDR.  Therefore, we must make sure


 * that TEXTADDR is correctly set.  Currently, we expect the least significant


 * "short" to be 0x8000, but we could probably relax this restriction to


 * TEXTADDR > PAGE_OFFSET + 0x4000


 *


 * Note that swapper_pg_dir is the virtual address of the page tables, and


 * pgtbl gives us a position-independent reference to these tables.  We can


 * do this because stext == TEXTADDR


 *


 * swapper_pg_dir, pgtbl and krnladr are all closely related.


 */


#if (TEXTADDR & 0xffff) != 0x8000


#error TEXTADDR must start at 0xXXXX8000


#endif


 


              .globl      SYMBOL_NAME(swapper_pg_dir)


              .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000


 


              .macro    pgtbl, reg, rambase


              adr   \reg, stext


              sub  \reg, \reg, #0x4000


              .endm


 


/*


 * Since the page table is closely related to the kernel start address, we


 * can convert the page table base address to the base address of the section


 * containing both.


 */


              .macro    krnladr, rd, pgtable, rambase


              bic   \rd, \pgtable, #0x000ff000


              .endm


 


/*


 *  Kernel startup entry point.


 *


 * The rules are:


 *  r0      - should be 0


 *  r1      - unique architecture number


 *  MMU     - off


 *  I-cache - on or off


 *  D-cache - off


 *


 * See linux/arch/arm/tools/mach-types for the complete list of numbers


 * for r1.


 */


              .section ".text.init",#alloc,#execinstr


              .type       stext, #function


ENTRY(stext)  //内核入口点


              mov r12, r0  //r00r120


mov r0, #F_BIT | I_BIT | MODE_SVC@ make sure svc mode//程序状态,禁止FIQIRQ,设定Supervisor模式。0b11010011


              msr  cpsr_c, r0                    @ and all irqs disabled//置当前程序状态寄存器


              bl     __lookup_processor_type//跳转到判断cpu类型,查找运行的cpuid值,和


//linux编译支持的id值,是否有相等


              teq   r10, #0                         @ invalid processor?//没有则跳到__error


              moveq     r0, #'p'                  @ yes, error 'p'


              beq  __error


              bl     __lookup_architecture_type//跳转到判断体系类型,看r1寄存器的


//architecture number值是否支持。


              teq   r7, #0                           @ invalid architecture? //不支持,跳到出错


              moveq     r0, #'a'                  @ yes, error 'a'


              beq  __error


              bl     __create_page_tables//创建核心页表


              adr   lr, __ret                 @ return address//lr=0xc0028054


              add  pc, r10, #12      @ initialise processor//r10pointer to processor structure


                                                                             //__arm720_proc_info)


                                                                             //r1012__arm720_setup;见


//__arm720_proc_info(proc-arm720.S


__arm720_setup: mov  r0, #0


                   mcr   p15, 0, r0, c7, c7, 0            @ invalidate caches


                   mcr   p15, 0, r0, c8, c7, 0            @ flush TLB (v4)


                   mcr   p15, 0, r4, c2, c0                 @ load page table pointer



路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)