×
单片机 > 单片机程序设计 > 详情

ARMv7:Linux Kernel引导

发布时间:2024-05-20 发布时间:
|

1.如果内核镜像是压缩的,需要解压缩,引导的第一步是从解压缩开始:archarmbootcompressedhead.S


2.解压缩之后,内核镜像已经存在于ARM中了,下面开始运行,内核开始运行是从/arch/arm/kernel/head.S开始的,入口代码为:

1

2

3

4

5

6

7

8

.arm

__HEAD

ENTRY(stext)

THUMB(adrr9,BSYM(1f))@KernelisalwaysenteredinARM.

THUMB(bxr9)@IfthisisaThumb-2kernel,

THUMB(.thumb)@switchtoThumbnow.

THUMB(1:)

这是由/arch/arm/kernel/vmlinux.lds.S决定的。告诉我们入口点为stext.

1

2

OUTPUT_ARCH(arm)

ENTRY(stext)

3.顺序执行head.S的代码。

1

2

3

4

5

6

7

8

ldrr13,=__switch_data@addresstojumptoafter

@mmuhasbeenenabled

adrlr,BSYM(1f)@return(PIC)address

movr8,r4@setTTBR1toswapper_pg_dir

ARM(addpc,r10,#PROCINFO_INITFUNC)

THUMB(addr12,r10,#PROCINFO_INITFUNC)

THUMB(movpc,r12)

1:b__enable_mmu

代码line1将__switch_data的地址赋给r13,在__enable_mmu(代码line8)执行成功后跳转到__switch_data执行。


因为是.arm环境,所以执行代码ARM(addpc,r10,#PROCINFO_INITFUNC),即跳转到__cpu_flush执行。

1

2

3

4

/arch/arm/kernel/head.S

mrcp15,0,r9,c0,c0@getprocessorid

bl__lookup_processor_type@r5=procinfor9=cpuid

movsr10,r5@invalidprocessor(r5=0)?

r10中保存的是proc_info结构体的startaddress.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

archarmincludeasmProcinfo.h

structproc_info_list{

unsignedintcpu_val;

unsignedintcpu_mask;

unsignedlong__cpu_mm_mmu_flags;/*usedbyhead.S*/

unsignedlong__cpu_io_mmu_flags;/*usedbyhead.S*/

unsignedlong__cpu_flush;/*usedbyhead.S*/

constchar*arch_name;

constchar*elf_name;

unsignedintelf_hwcap;

constchar*cpu_name;

structprocessor*proc;

structcpu_tlb_fns*tlb;

structcpu_user_fns*user;

structcpu_cache_fns*cache;

};

1

2

include/generated/asm-offsets.h

#definePROCINFO_INITFUNC16

4.__cpu_flush

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

arch/arm/mm/proc-v7.S

__v7_ca9mp_proc_info:

.long0x410fc090

.long0xff0ffff0

__v7_proc__v7_ca9mp_setup

.macro__v7_procinitfunc,mm_mmuflags=0,io_mmuflags=0,hwcaps=0

ALT_SMP(.longPMD_TYPE_SECT|PMD_SECT_AP_WRITE|PMD_SECT_AP_READ|

PMD_SECT_AF|PMD_FLAGS_SMP|mm_mmuflags)

ALT_UP(.longPMD_TYPE_SECT|PMD_SECT_AP_WRITE|PMD_SECT_AP_READ|

PMD_SECT_AF|PMD_FLAGS_UP|mm_mmuflags)

.longPMD_TYPE_SECT|PMD_SECT_AP_WRITE|

PMD_SECT_AP_READ|PMD_SECT_AF|io_mmuflags

W(b)initfunc

__v7_ca5mp_setup:

__v7_ca9mp_setup:

movr10,#(1<

b1f

__v7_ca7mp_setup:

__v7_ca15mp_setup:

movr10,#0

不同架构的CPU,针对的文件不同,对于ARMV7架构的cpu而言,对应的为proc-v7.S。从code中可以看出,其对应俄proc_info为__v7_ca9mp_proc_info,所以偏移16后,就是执行跳转代码b1f。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

__CPUINIT

/*

*__v7_setup

*

*InitialiseTLB,Caches,andMMUstatereadytoswitchtheMMU

*on.Returninr0thenewCP15C1controlregistersetting.

*

*ThisshouldbeabletocoverallARMv7cores.

*

*Itisassumedthat:

*-cachetyperegisterisimplemented

*/

__v7_ca5mp_setup:

__v7_ca9mp_setup:

movr10,#(1<

b1f

__v7_ca7mp_setup:

__v7_ca15mp_setup:

movr10,#0

1:

#ifdefCONFIG_SMP

ALT_SMP(mrcp15,0,r0,c1,c0,1)

ALT_UP(movr0,#(1<

tstr0,#(1<

orreqr0,r0,#(1<

orreqr0,r0,r10@EnableCPU-specificSMPbits

mcreqp15,0,r0,c1,c0,1

#endif

__v7_setup:

5.__v7_setup->__enable_mmu->__turn_mmu_on

1

2

3

4

5

6

7

8

__turn_mmu_on:

movr0,r0

mcrp15,0,r0,c1,c0,0@writecontrolreg

mrcp15,0,r3,c0,c0,0@readidreg

movr3,r3

movr3,r3

movpc,r13

ENDPROC(__turn_mmu_on)

r13保存的是__switch_data的地址,movpc,r13跳转到__switch_data.


6.__mmap_switched

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

.type__switch_data,%object

__switch_data:

.long__mmap_switched

.long__data_loc@r4

.long_data@r5

.long__bss_start@r6

.long _end @ r7

[1] [2]
ARMv7LinuxKernel内核镜像

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈AVR中定时器几种工作模式