arm-linux启动过程(2)
来源:互联网 发布:php入门到精通源码 编辑:程序博客网 时间:2024/05/07 23:41
5. 为kernel建立临时页表
前面提及到,kernel里面的所有符号在链接时,都使用了虚拟地址值。在完成基本的初始化后,kernel代码将跳到第一个C语言函数start_kernl来执行,在哪个时候,这些虚拟地址必须能够对它所存放在真正内存位置,否则运行将为出错。为此,CPU必须开启MMU,但在开启MMU前,必须为虚拟地址到物理地址的映射建立相应的面表。在开启MMU后,kernel指并不马上将PC值指向start_kernl,而是要做一些C语言运行期的设置,如堆栈,重定义等工作后才跳到start_kernel去执行。在此过程中,PC值还是物理地址,因此还需要为这段内存空间建立va=pa的内存映射关系。当然,本函数建立的所有页表都会在将来paging_init销毁再重建,这是临时过度性的映射关系和页表。
在介绍__create_table_pages前,先认识一个macropgtbl,它将KERNL_RAM_PADDR –0x4000的值赋给rd寄存器,从下面的使用中可以看它,该值是页表在物理内存的基础,也即页表放在kernel开始地址下的16K的地方。
-
-
- .macro
pgtbl, rd -
-
ldr \rd, =(KERNEL_RAM_PADDR - 0x4000) -
- .endm
-
- __create_page_tables:
-
-
pgtbl r4 @ page table address -
-
-
-
mov r0, r4 -
mov r3, #0 -
add r6, r0, #0x4000 -
- 1:
str r3, [r0], #4 -
str r3, [r0], #4 -
str r3, [r0], #4 -
str r3, [r0], #4 -
teq r0, r6 -
bne 1b -
-
-
-
-
ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags -
-
-
-
-
-
str r3, [r4, r6, lsl #2] @ identity mapping -
-
-
-
-
-
-
-
-
-
str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]! -
-
-
-
ldr r6, =(KERNEL_END - 1) -
-
-
-
add r0, r0, #4 -
-
-
-
add r6, r4, r6, lsr #18 - 1:
cmp r0, r6 -
-
-
add r3, r3, #1 << 20 -
strls r3, [r0], #4 -
bls 1b -
-
#ifdef CONFIG_XIP_KERNEL -
- #endif
-
-
-
add r0, r4, #PAGE_OFFSET >> 18 -
orr r6, r7, #(PHYS_OFFSET & 0xff000000) -
.if (PHYS_OFFSET & 0x00f00000) -
orr r6, r6, #(PHYS_OFFSET & 0x00f00000) -
.endif -
str r6, [r0] -
- #ifdef
CONFIG_DEBUG_LL -
- #if
defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS) -
- #endif
-
- #ifdef
CONFIG_ARCH_RPC -
- #endif
-
- #endif
-
-
mov pc, lr - ENDPROC(__create_page_tables)
一口气将__create_pages_table分析完,但里涉及的代码还是需要细细品读。尤其是右移20位和18位两个地方与页表目录项的地址关系比较复杂。执行完该函数后,虚拟内存和物理内存的映射关系如下图所示:
6. 开启MMU
看完页表的建立,想必开启MMU的代码也是小菜一碟吧。此函数的主要功能是将页表的基址加到cp15中的面表指针寄存器,同时设置域访问(domainaccess)寄存器。
-
- __enable_mmu:
-
- #ifdef
CONFIG_ALIGNMENT_TRAP -
orr r0, r0, #CR_A - #else
-
bic r0, r0, #CR_A - #endif
-
- #ifdef
CONFIG_CPU_DCACHE_DISABLE -
bic r0, r0, #CR_C - #endif
-
- #ifdef
CONFIG_CPU_BPREDICT_DISABLE -
bic r0, r0, #CR_Z - #endif
-
- #ifdef
CONFIG_CPU_ICACHE_DISABLE -
bic r0, r0, #CR_I - #endif
-
-
-
-
mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ -
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ -
domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \ -
domain_val(DOMAIN_IO, DOMAIN_CLIENT)) -
mcr p15, 0, r5, c3, c0, 0 @ load domain access register -
mcr p15, 0, r4, c2, c0, 0 @ load page table pointer -
b __turn_mmu_on - ENDPROC(__enable_mmu)
-
-
-
-
.align 5 - __turn_mmu_on:
-
mov r0, r0 -
-
-
-
mcr p15, 0, r0, c1, c0, 0 @ write control reg -
mrc p15, 0, r3, c0, c0, 0 @ read id reg -
-
-
mov r3, r3 -
mov r3, r3 -
-
-
-
mov pc, r13 - ENDPROC(__turn_mmu_on)
7.__mmap_switched函数
__mmap_switched函数专用来设置C语言的执行环境,比如重定位工作,堆栈,以及BSS段的清零。
__switch_data变量先定义了一系里面处量的数据,如重定位和数据段的地址,BSS段的地址,pocessor_id和__mach_arch_type变量的地址等。
-
.type __switch_data, %object - __switch_data:
-
.long __mmap_switched -
.long __data_loc @ r4 -
.long _data @ r5 -
.long __bss_start @ r6 -
.long _end @ r7 -
.long processor_id @ r4 -
.long __machine_arch_type @ r5 -
.long __atags_pointer @ r6 -
.long cr_alignment @ r7 -
.long init_thread_union + THREAD_START_SP @ sp -
-
- __mmap_switched:
-
adr r3, __switch_data + 4 -
-
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 -
-
-
-
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 - ENDPROC(__mmap_switched)
全文完, by linyt
- arm-linux启动过程(2)
- arm-linux启动过程(2)
- arm-linux启动过程
- arm linux 启动过程
- arm-linux启动过程
- arm-linux启动过程
- ARM Linux 启动过程
- arm-linux启动过程
- arm-linux启动过程
- ARM Linux启动过程
- ARM Linux启动过程
- arm-linux启动过程
- arm 嵌入式LINUX启动过程(2)
- arm 嵌入式LINUX启动过程(2)[转]
- 详解 ARM Linux启动过程分析(2)
- ARM Linux启动过程分析
- ARM Linux启动过程分析
- ARM Linux启动过程学习
- arm linux中一些重要的宏及地…
- arm linux中一些重要的宏及地…
- arm-linux启动过程(1)
- arm-linux启动过程(1)
- arm-linux启动过程(2)
- arm-linux启动过程(2)
- Arm linux启动分析(1)
- Arm linux启动分析(1)
- Arm linux启动分析(2)
- Arm linux启动分析(2)
- Arm linux启动分析(3)
- Arm linux启动分析(3)
- Arm linux启动分析(4)
- Arm linux启动分析(4)