arm linux head.s,ARM Linux启动分析headarmv.S内幕

ARM Linux启动分析headarmv.S内幕

来源:华强电子网

作者:华仔

浏览:211

时间:2016-08-10 14:18

标签:

摘要:

__create_page_tables: pgtbl r4, r5 @ page table address /* Clear the 16K level 1 swapper page table */ mov r0, r4 mov r3, #0 add r2, r0, #0x40001: str r3, [r0], #4 str r3, [r0], #4 str r3, [r0],

__create_page_tables:

pgtbl r4, r5 @ page table address

/* Clear the 16K level 1 swapper page table */

mov r0, r4

mov r3, #0

add r2, r0, #0x4000

1: str r3, [r0], #4

str r3, [r0], #4

str r3, [r0], #4

str r3, [r0], #4

teq r0, r2

bne 1b

/*

* Create identity mapping for first MB of kernel to

* cater for the MMU enable.This identity mapping

* will be removed by paging_init()

*/

krnladrr2, r4, r5 @ start of kernel

add r3, r8, r2 @ flags + kernel base

str r3, [r4, r2, lsr #18] @ identity mapping

/*

* Now setup the pagetables for our kernel direct

* mapped region.We round TEXTADDR down to the

* nearest megabyte boundary.

*/

add r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel

bic r2, r3, #0x00f00000

str r2, [r0] @ PAGE_OFFSET + 0MB

add r0, r0, #(TEXTADDR & 0x00f00000) >> 18

str r3, [r0], #4 @ KERNEL + 0MB

add r3, r3, #1 << 20

str r3, [r0], #4 @ KERNEL + 1MB

add r3, r3, #1 << 20

str r3, [r0], #4 @ KERNEL + 2MB

add r3, r3, #1 << 20

str r3, [r0], #4 @ KERNEL + 3MB

/*

* Ensure that the first section of RAM is present.

* we assume that:

*1. the RAM is aligned to a 32MB boundary

*2. the kernel is executing in the same 32MB chunk

* as the start of RAM.

*/

bic r0, r0, #0x01f00000 >> 18 @ round down

and r2, r5, #0xfe000000 @ round down

add r3, r8, r2 @ flags + rambase

str r3, [r0]

bic r8, r8, #0x0c @ turn off cacheable

@ and bufferable bits

代码创建页表目录。首先清空从0xA0004000开始的16K页表项。然后,为了可以访问从0xA0000000开始的内核的1M空间,将该地址对应的页表项赋值。接着映射从TEXTADDR开始的4M的虚拟地址空间,这需要4个页表项。最后,由于SDRAM开始的第一MB的空间存放有启动时的一些参数,所以也需要映射。在这里,该映射和前面的虚拟地址的映射在地址上是相等的。

在创建页表目录完成后,代码通过前面主程序的最后一句addpc, r10, #12跳转到实际的CPU的设置子程序__xscale_setup。

__xscale_setup:

mov r0, #F_BIT|I_BIT|SVC_MODE

msr cpsr_c, r0

mcr p15, 0, ip, c7, c7, 0@ invalidate I, D caches & BTB

mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer

mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs

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

mov r0, #0x1f @ Domains 0, 1 = client

mcr p15, 0, r0, c3, c0, 0@ load domain access register

mov r0, #1 @ Allow user space to access

mcr p15, 0, r0, c15, c1, 0 @ ... CP 0 only.

#if CACHE_WRITE_THROUGH

mov r0, #0x20

#else

Mov r0, #0x00

#endif

mcr p15, 0, r0, c1, c1, 0 @ set auxiliary control reg

mrc p15, 0, r0, c1, c0, 0 @ get control register

bic r0, r0, #0x0200 @ ......R.........

bic r0, r0, #0x0082 @ ........B.....A.

orr r0, r0, #0x0005 @ .............C.M

orr r0, r0, #0x3900 @ ..VIZ..S........

#ifdef CONFIG_XSCALE_CACHE_ERRATA

bic r0, r0, #0x0004 @ see cpu_xscale_proc_init

#endif

mov pc, lr

主要是操作协处理器,设置页表目录项基地址,对CACHE和BUFFER的控制位进行一些操作。具体大家可以看看介绍ARM编程的书。

.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

mov r0, r0

mov r0, r0

mov r0, r0

mov pc, lr

.align 5

__mmap_switched:

adr r3, __switch_data + 4

ldmia r3, {r4, r5, r6, r7, r8, sp}@ r2 = compat

@ sp = stack pointer

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

1: cmp r4, r5

strcc fp, [r4],#4

bcc 1b

str r9, [r6] @ Save processor ID

str r1, [r7] @ Save machine type

#ifdef CONFIG_ALIGNMENT_TRAP

orr r0, r0, #2 @ ...........A.

#endif

bic r2, r0, #2 @ Clear 'A' bit

stmia r8, {r0, r2} @ Save control register values

bSYMBOL_NAME(start_kernel)

最后这段代码的作用主要是在进入C函数前先做一些变量的初始化和保存工作。首先清空BSS区域,然后保存处理器ID和机器类型到各自变量地址,接着保存cr_alignment,最后跳转到init/main.c中的start_kernel函数运行。

以上介绍的是head-armv.S文件的主要内容和功能,它是linux运行的第一个文件,具有非常重要的意义。很好的阅读该文件,对于我们理解ARM处理器的工作方式有很大的帮助。同时,在许多linux系统的移植工作中,往往需要对该文件透彻的理解。

分享到:

eb16ac850798d72e084e2c3ed33ff707.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值