3.1 说明
这个文件是arch/arm/kernel/head-armv.S,用汇编代码完成,是内核最先执行的一个文件。这一段汇编代码的主要作用,是检查cpu id,architecture number,初始化页表、cpu、bbs等操作,并跳到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 //r0=0,r12=0
mov r0, #F_BIT | I_BIT | MODE_SVC@ make sure svc mode//程序状态,禁止FIQ、IRQ,设定Supervisor模式。0b11010011
msr cpsr_c, r0 @ and all irqs disabled//置当前程序状态寄存器
bl __lookup_processor_type//跳转到判断cpu类型,查找运行的cpu的id值,和
//此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//r10:pointer to processor structure
//(__arm720_proc_info)
//r10+12:__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
//cp15寄存器1(ttb)=0xc0024000
mov r0, #0x 1f @ Domains 0, 1 = client
mcr p15, 0, r0, c3, c0 @ load domain access register
mrc p15, 0, r0, c1, c0 @ get control register//r0=0x70
bic r0, r0, #0x0e00 @ ..V. ..RS BLDP WCAM//bit[11:9]=0
r0=0x00000070
orr r0, r0, #0x2100 @ .... .... .111 .... (old) //r0=0x00002170
orr r0, r0, #0x003d @ ..1. ..01 ..11 1101 (new) //r0=0x0000217d
其中S LDPWC M位置1。
(详见cp15寄存器1说明)
mov pc, lr @ __ret (head-armv.S)
』
@ (return control reg)
.type __switch_data, %object
__switch_data: .long __mmap_switched
.long SYMBOL_NAME(__bss_start)
.long SYMBOL_NAME(_end)
.long SYMBOL_NAME(processor_id)
.long SYMBOL_NAME(__machine_arch_type)
.long SYMBOL_NAME(cr_alignment)
.long SYMBOL_NAME(init_task_union)+8192
.type __ret, %function
__ret: ldr lr, __switch_data
mcr p15, 0, r0, c1, c0//更新控制寄存器cp15寄存器1=0x0000217d
mov r0, r0
mov r0, r0
mov r0, r0
mov pc, lr//__switch_data
/*
* This code follows on after the page
* table switch and jump above.