您的位置:首页 > 其它

From kernel startup entry point to start_kernel (2)

2013-07-15 18:24 477 查看

1. The whole process

crash> dis stext

0xc0008000 <stext>: msr CPSR_c, #211 ; 0xd3

0xc0008004 <stext+4>: mrc 15, 0, r9, cr0, cr0, {0}

0xc0008008 <stext+8>: bl 0xc044c880 <__lookup_processor_type>

0xc000800c <stext+12>: movs r10, r5

0xc0008010 <stext+16>: beq 0xc044c8c4 <__error>

0xc0008014 <stext+20>: add r3, pc, #44 ; 0x2c

0xc0008018 <stext+24>: ldm r3, {r4, r8}

0xc000801c <stext+28>: sub r4, r3, r4

0xc0008020 <stext+32>: add r8, r8, r4

0xc0008024 <stext+36>: bl 0xc0008110 <__vet_atags>

0xc0008028 <stext+40>: bl 0xc058d000 <__fixup_smp>

0xc000802c <stext+44>: bl 0xc0008050 <__create_page_tables>

0xc0008030 <stext+48>: ldr sp, [pc, #12] ; 0xc0008044

0xc0008034 <stext+52>: add lr, pc, #4

0xc0008038 <stext+56>: mov r8, r4

0xc000803c <stext+60>: add pc, r10, #16

0xc0008040 <stext+64>: b 0xc044c854 <__enable_mmu>

mrc p15, 0, r9, c0, c0 @ get processor id

bl __lookup_processor_type @ r5=procinfo r9=cpuid

2. __lookup_processor_type

/*

* Read processor ID register (CP#15, CR0), and look up in the linker-built

* supported processor list. Note that we can't use the absolute addresses

* for the __proc_info lists since we aren't running with the MMU on

* (and therefore, we are not in the correct address space). We have to

* calculate the offset.

*

* r9 = cpuid

* Returns:

* r3, r4, r6 corrupted

* r5 = proc_info pointer in physical address space

* r9 = cpuid (preserved)

*/

crash> dis __lookup_processor_type

/*此时pc的内容是物理地址,而不是这里显示的标号 0xc044c880【该值是静态编译生成的,不是运行是决定的】

*而PC时运行时决定的。

*r3的内容也是物理地址,间接寻址把内容load 到r4,5,6

*r4的内容是当前地址的虚拟地址, r3是当前地址的物理地址

*/

0xc044c880 <__lookup_processor_type>: add r3, pc, #48 ; 0x30

0xc044c884 <__lookup_processor_type+4>: ldm r3, {r4, r5, r6}

/*mean: r3-r4 not r4-r3

*convert virt addresses to physical address space

*/

0xc044c888 <__lookup_processor_type+8>: sub r3, r3, r4

0xc044c88c <__lookup_processor_type+12>: add r5, r5, r3

0xc044c890 <__lookup_processor_type+16>: add r6, r6, r3

0xc044c894 <__lookup_processor_type+20>: ldm r5, {r3, r4}

0xc044c898 <__lookup_processor_type+24>: and r4, r4, r9

0xc044c89c <__lookup_processor_type+28>: teq r3, r4

0xc044c8a0 <__lookup_processor_type+32>: beq 0xc044c8b4 <__lookup_processor_type+52>

0xc044c8a4 <__lookup_processor_type+36>: add r5, r5, #52 ; 0x34

0xc044c8a8 <__lookup_processor_type+40>: cmp r5, r6

0xc044c8ac <__lookup_processor_type+44>: bcc 0xc044c894 <__lookup_processor_type+20>

0xc044c8b0 <__lookup_processor_type+48>: mov r5, #0

0xc044c8b4 <__lookup_processor_type+52>: mov pc, lr

/*具体细节不再关注,这个代码的意思是:

*1】此时是物理地址,而不是这些的虚拟地址,如果寻址此时只能使用PC寻址;

*2】此函数的输入值r5 = proc_info pointer in physical address space

*3】此函数的返回值r9 = cpuid

*4】至于,cpuid和proc_info的对应关系,不再关注。

*/

3. __vet_atags

r2 = atags or dtb pointer.

/* Determine validity of the r2 atags pointer. The heuristic requires

* that the pointer be aligned, in the first 16k of physical RAM and

* that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE

* is selected, then it will also accept a dtb pointer. Future revisions

* of this function may be more lenient with the physical address and

* may also be able to move the ATAGS block if necessary.

*

* Returns:

* r2 either valid atags pointer, valid dtb pointer, or zero

* r5, r6 corrupted

* 该函数只是判断r2的有效性,并没有做其他处理

*/

crash> dis __vet_atags

0xc0008110 <__vet_atags>: tst r2, #3

0xc0008114 <__vet_atags+4>: bne 0xc000813c <__vet_atags+44>

0xc0008118 <__vet_atags+8>: ldr r5, [r2]

0xc000811c <__vet_atags+12>: cmp r5, #5

0xc0008120 <__vet_atags+16>: cmpne r5, #2

0xc0008124 <__vet_atags+20>: bne 0xc000813c <__vet_atags+44>

0xc0008128 <__vet_atags+24>: ldr r5, [r2, #4]

0xc000812c <__vet_atags+28>: ldr r6, [pc, #16] ; 0xc0008144

0xc0008130 <__vet_atags+32>: cmp r5, r6

0xc0008134 <__vet_atags+36>: bne 0xc000813c <__vet_atags+44>

0xc0008138 <__vet_atags+40>: mov pc, lr

0xc000813c <__vet_atags+44>: mov r2, #0

0xc0008140 <__vet_atags+48>: mov pc, lr

4. __fixup_smp

/*

*what about the __fixup_smp??

*/

__fixup_smp:

and r3, r9, #0x000f0000 @ architecture version

teq r3, #0x000f0000 @ CPU ID supported?

bne __fixup_smp_on_up @ no, assume UP

bic r3, r9, #0x00ff0000

bic r3, r3, #0x0000000f @ mask 0xff00fff0

mov r4, #0x41000000

orr r4, r4, #0x0000b000

orr r4, r4, #0x00000020 @ val 0x4100b020

teq r3, r4 @ ARM 11MPCore?

moveq pc, lr @ yes, assume SMP

mrc p15, 0, r0, c0, c0, 5 @ read MPIDR

and r0, r0, #0xc0000000 @ multiprocessing extensions and

teq r0, #0x80000000 @ not part of a uniprocessor system?

moveq pc, lr @ yes, assume SMP

5. __create_page_tables

/*

* Setup the initial page tables. We only setup the barest

* amount which are required to get the kernel running, which

* generally means mapping in the kernel code.

*

* r8 = phys_offset, r9 = cpuid, r10 = procinfo

*

* Returns:

* r0, r3, r5-r7 corrupted

* r4 = physical page table address

*/

crash> dis __create_page_tables

/*

* make the region of [phys_offset+0x4000, phys_offset+0x4000+0x4000] clean

* Clear the swapper page table

*/

0xc0008050 <__create_page_tables>: add r4, r8, #16384 ; 0x4000

0xc0008054 <__create_page_tables+0x4>: mov r0, r4

0xc0008058 <__create_page_tables+0x8>: mov r3, #0

0xc000805c <__create_page_tables+0xc>: add r6, r0, #16384 ; 0x4000

0xc0008060 <__create_page_tables+0x10>: str r3, [r0], #4

0xc0008064 <__create_page_tables+0x14>: str r3, [r0], #4

0xc0008068 <__create_page_tables+0x18>: str r3, [r0], #4

0xc000806c <__create_page_tables+0x1c>: str r3, [r0], #4

0xc0008070 <__create_page_tables+0x20>: teq r0, r6

0xc0008074 <__create_page_tables+0x24>: bne 0xc0008060 <__create_page_tables+16>

5.1 Create identity mapping to cater for __enable_mmu

/* r10 = procinfo, mm_mmuflags

*/

0xc0008078 <__create_page_tables+0x28>: ldr r7, [r10, #8]

/*

* Create identity mapping to cater for __enable_mmu.

* This identity mapping will be removed by paging_init().

*/

0xc000807c <__create_page_tables+0x2c>: add r0, pc, #128 ; 0x80

0xc0008080 <__create_page_tables+0x30>: ldm r0, {r3, r5, r6}

0xc0008084 <__create_page_tables+0x34>: sub r0, r0, r3

0xc0008088 <__create_page_tables+0x38>: add r5, r5, r0

0xc000808c <__create_page_tables+0x3c>: add r6, r6, r0

/*

*r5,r6寄存器的内容分别是代码__turn_mmu_on的开始,结束地址

*r5,r6寄存器的内容右移20位:SECTION_SHIFT

*/

0xc0008090 <__create_page_tables+0x40>: lsr r5, r5, #20

0xc0008094 <__create_page_tables+0x44>: lsr r6, r6, #20

/*

*r5右移20位后,再左移20位,然后和procinfo中的mm_mmuflags逻辑或操作

*把r3的内容存放在位置PHY_OFFSET + address >> 20 << 20 << 2

*物理地址的来源当前PC和相对地址,它的内容的前20位在 pte中;

*怎样得到个表项那?虚拟地址的高12位再左移2位,这14位形成index和18位的基地址,形成表项的虚拟地址

*注意每个表项占2*2=4个字节,每个pte也是用4个字节描述;14形成的index: 2的14次幂就是16K:0x4000

*#define PG_DIR_SIZE 0x4000

*#define PMD_ORDER 2

*/

0xc0008098 <__create_page_tables+0x48>: orr r3, r7, r5, lsl #20

0xc000809c <__create_page_tables+0x4c>: str r3, [r4, r5, lsl #2]

0xc00080a0 <__create_page_tables+0x50>: cmp r5, r6

0xc00080a4 <__create_page_tables+0x54>: addcc r5, r5, #1

0xc00080a8 <__create_page_tables+0x58>: bcc 0xc0008098 <__create_page_tables+72>

5.2 setup the pagetables for our kernel direct mapped region

/*

* Now setup the pagetables for our kernel direct

* mapped region.

*/

0xc00080ac <__create_page_tables+0x5c>: mov r3, pc

0xc00080b0 <__create_page_tables+0x60>: lsr r3, r3, #20

0xc00080b4 <__create_page_tables+0x64>: orr r3, r7, r3, lsl #20

0xc00080b8 <__create_page_tables+0x68>: add r0, r4, #12288 ; 0x3000

0xc00080bc <__create_page_tables+0x6c>: str r3, [r0, #0]!

0xc00080c0 <__create_page_tables+0x70>: ldr r6, [pc, #56] ; 0xc0008100

0xc00080c4 <__create_page_tables+0x74>: add r0, r0, #4

0xc00080c8 <__create_page_tables+0x78>: add r6, r4, r6, lsr #18

0xc00080cc <__create_page_tables+0x7c>: cmp r0, r6

0xc00080d0 <__create_page_tables+0x80>: add r3, r3, #1048576 ; 0x100000

0xc00080d4 <__create_page_tables+0x84>: strls r3, [r0], #4

0xc00080d8 <__create_page_tables+0x88>: bls 0xc00080cc <__create_page_tables+124>

5.3 map boot params address

/*

* Then map boot params address in r2 or the first 1MB (2MB with LPAE)

* of ram if boot params address is not specified.

*/

0xc00080dc <__create_page_tables+0x8c>: lsr r0, r2, #20

0xc00080e0 <__create_page_tables+0x90>: lsls r0, r0, #20

0xc00080e4 <__create_page_tables+0x94>: moveq r0, r8

0xc00080e8 <__create_page_tables+0x98>: sub r3, r0, r8

0xc00080ec <__create_page_tables+0x9c>: add r3, r3, #-1073741824 ; 0xc0000000

0xc00080f0 <__create_page_tables+0xa0>: add r3, r4, r3, lsr #18

0xc00080f4 <__create_page_tables+0xa4>: orr r6, r7, r0

0xc00080f8 <__create_page_tables+0xa8>: str r6, [r3]

0xc00080fc <__create_page_tables+0xac>: mov pc, lr

__turn_mmu_on_loc:

.long .

.long __turn_mmu_on

.long __turn_mmu_on_end

6 __enable_mmu

/*

* Setup common bits before finally enabling the MMU. Essentially

* this is just loading the page table pointer and domain access

* registers.

*

* r0 = cp#15 control register

* r1 = machine ID

* r2 = atags or dtb pointer

* r4 = page table pointer

* r9 = processor ID

* r13 = *virtual* address to jump to upon completion

*/

crash> dis __enable_mmu

0xc044c854 <__enable_mmu>: bic r0, r0, #2

0xc044c858 <__enable_mmu+0x4>: mov r5, #21

/*

*@ load domain access register, load page table pointer

*/

0xc044c85c <__enable_mmu+0x8>: mcr 15, 0, r5, cr3, cr0, {0}

0xc044c860 <__enable_mmu+0xc>: mcr 15, 0, r4, cr2, cr0, {0}

0xc044c864 <__enable_mmu+0x10>: b 0xc0452870 <__turn_mmu_on>

7__turn_mmu_on

/*

* Enable the MMU. This completely changes the structure of the visible

* memory space. You will not be able to trace execution through this.

* If you have an enquiry about this, *please* check the linux-arm-kernel

* mailing list archives BEFORE sending another post to the list.

*

* r0 = cp#15 control register

* r1 = machine ID

* r2 = atags or dtb pointer

* r9 = processor ID

* r13 = *virtual* address to jump to upon completion

*

* other registers depend on the function called upon completion

*/

crash> dis __turn_mmu_on

0xc0452870 <__idmap_text_start>: nop ; (mov r0, r0)

0xc0452874 <__turn_mmu_on+0x4>: isb sy

0xc0452878 <__turn_mmu_on+0x8>: mcr 15, 0, r0, cr1, cr0, {0}

0xc045287c <__turn_mmu_on+0xc>: mrc 15, 0, r3, cr0, cr0, {0}

0xc0452880 <__turn_mmu_on+0x10>: isb sy

0xc0452884 <__turn_mmu_on+0x14>: mov r3, r3

0xc0452888 <__turn_mmu_on+0x18>: mov r3, sp

0xc045288c <__turn_mmu_on+0x1c>: mov pc, r3

8 __mmap_switched

/*

* The following fragment of code is executed with the MMU on in MMU mode,

* and uses absolute addresses; this is not position independent.

*

* r0 = cp#15 control register

* r1 = machine ID

* r2 = atags/dtb pointer

* r9 = processor ID

*/

__INIT

__mmap_switched:

adr r3, __mmap_switched_data

ldmia r3!, {r4, r5, r6, r7}

cmp r4, r5 @ Copy data segment if needed

1: cmpne r5, r6

ldrne fp, [r4], #4

strne fp, [r5], #4

bne 1b

mov fp, #0 @ Clear BSS (and zero fp)

1: cmp r6, r7

strcc fp, [r6],#4

bcc 1b

ARM( ldmia r3, {r4, r5, r6, r7, sp})

str r9, [r4] @ Save processor ID

str r1, [r5] @ Save machine type

str r2, [r6] @ Save atags pointer

bic r4, r0, #CR_A @ Clear 'A' bit

stmia r7, {r0, r4} @ Save control register values

b start_kernel
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: