1020linux内核启动内核自解压分析.docx

上传人:b****3 文档编号:2831846 上传时间:2022-11-15 格式:DOCX 页数:41 大小:36.90KB
下载 相关 举报
1020linux内核启动内核自解压分析.docx_第1页
第1页 / 共41页
1020linux内核启动内核自解压分析.docx_第2页
第2页 / 共41页
1020linux内核启动内核自解压分析.docx_第3页
第3页 / 共41页
1020linux内核启动内核自解压分析.docx_第4页
第4页 / 共41页
1020linux内核启动内核自解压分析.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

1020linux内核启动内核自解压分析.docx

《1020linux内核启动内核自解压分析.docx》由会员分享,可在线阅读,更多相关《1020linux内核启动内核自解压分析.docx(41页珍藏版)》请在冰豆网上搜索。

1020linux内核启动内核自解压分析.docx

1020linux内核启动内核自解压分析

内核自解压过程分析

本章代码的主要工作是将zImage解压,并把解压后的内核拷贝的正确的执行位置。

在解压之前cpu有几项工作要完成:

1.将bootloard传入的参数保存起来

2.进入管理模式,并将中断关闭

3.判断各段代码指针是否有偏移,有偏移的话就要更改指针地址

4.清楚bass段,打开高速缓存,设置栈的开始地址和结束地址,大小为64k

5.接下来要判断解压后各段数据是否有重叠,具体做法是(比较解压后内核的开始地址(执行内核的首地址)是否比设置的栈的结束地址大,如果大则跳转到wont_overwrite,否则比较解压后内核的结束地址是否比Image的开始地址小,如果小则跳转到wont_overwrite。

Wont_overwrite的作用是设置参数解压内核、运行解压后的内核)如果有重叠的话,做一些工作(这些工作很简单在代码中能见到)然后解压内核,解压之后要重新搬移内核到正确的位置,在搬移过程中可能有解压内核和搬移内核的代码相重叠,所以在搬移之前要将这段代码搬移到一个安全的地址,然后可以开始内核的搬移,搬移完内核之后要刷新cache,之后关闭cache然后开始运行内核。

 

下面是内核自解压过程的完整代码和分析:

/*

*linux/arch/arm/boot/compressed/head.S

*

*Copyright(C)1996-2002RussellKing

*Copyright(C)2004HyokS.Choi(MPUsupport)

*

*Thisprogramisfreesoftware;youcanredistributeitand/ormodify

*itunderthetermsoftheGNUGeneralPublicLicenseversion2as

*publishedbytheFreeSoftwareFoundation.

*/

#include

/*

*Debuggingstuff

*

*Notethatthesemacrosmustnotcontainanycodewhichisnot

*100%relocatable(重定位).Anyattempttodosowillresultinacrash.

*Pleaseselectoneofthefollowingwhenturningondebugging.

*/

#ifdefDEBUG/*调试宏中间层*/

#ifdefined(CONFIG_DEBUG_ICEDCC)/*使用内部调试协处理器*/

#ifdefCONFIG_CPU_V6

.macroloadsp,rb

.endm

.macrowriteb,ch,rb

mcrp14,0,\ch,c0,c5,0

.endm

#elifdefined(CONFIG_CPU_XSCALE)

.macroloadsp,rb

.endm

.macrowriteb,ch,rb

mcrp14,0,\ch,c8,c0,0

.endm

#else

.macroloadsp,rb

.endm

.macrowriteb,ch,rb

mcrp14,0,\ch,c1,c0,0

.endm

#endif

#else

#include/*包含架构相关的调试宏的汇编文件调试宏-底层*/

.macrowriteb,ch,rb

senduart\ch,\rb

.endm

#ifdefined(CONFIG_ARCH_SA1100)

.macroloadsp,rb

mov\rb,#0x80000000@physicalbaseaddress

#ifdefCONFIG_DEBUG_LL_SER3

add\rb,\rb,#0x00050000@Ser3

#else

add\rb,\rb,#0x00010000@Ser1

#endif

.endm

#elifdefined(CONFIG_ARCH_S3C2410)

.macroloadsp,rb

mov\rb,#0x50000000

add\rb,\rb,#0x4000*CONFIG_S3C_LOWLEVEL_UART_PORT

.endm

#else

.macroloadsp,rb

addruart\rb

.endm

#endif

#endif

#endif

.macrokputc,val

movr0,\val

blputc

.endm

.macrokphex,val,len

movr0,\val

movr1,#\len

blphex

.endm

.macrodebug_reloc_start

#ifdefDEBUG

kputc#'\n'

kphexr6,8/*processorid*/

kputc#':

'

kphexr7,8/*architectureid*/

#ifdefCONFIG_CPU_CP15

kputc#':

'

mrcp15,0,r0,c1,c0

kphexr0,8/*controlreg*/

#endif

kputc#'\n'

kphexr5,8/*decompressedkernelstart*/

kputc#'-'

kphexr9,8/*decompressedkernelend*/

kputc#'>'

kphexr4,8/*kernelexecutionaddress*/

kputc#'\n'

#endif

.endm

.macrodebug_reloc_end

#ifdefDEBUG

kphexr5,8/*endofkernel*/

kputc#'\n'

movr0,r4

blmemdump/*dump256bytesatstartofkernel*/

#endif

.endm

.section".start",#alloc,#execinstr

/*

*sortoutdifferentcallingconventions清理不同的调用约定

*/

.align//默认以字节对齐

start:

.typestart,#function

.rept8

movr0,r0

.endr

b1f

.word0x016f2818@Magicnumbers(魔数)tohelptheloader

.wordstart@absoluteload/runzImageaddress(编译时确定)

.word_edata@zImageendaddress

1:

movr7,r1@savearchitectureID(此前有bootloard放入r1)

movr8,r2@saveatagspointer保存内核启动参数到地址r8(此前有bootloard放入r2)这一段的作用是将bootloard传入的参数保存起来。

#ifndef__ARM_ARCH_2__

/*下面这段代码的作用是进入管理模式,并将中断关闭。

*BootingfromAngel-needtoenterSVCmodeanddisable

*FIQs/IRQs(numericdefinitionsfromangelarm.hsource).

*Weonlydothisifwewereinusermodeonentry.

*/

mrsr2,cpsr@getcurrentmode获取当前模式

tstr2,#3@notuser?

判断是不是用户模式,不是则跳转

bnenot_angel

movr0,#0x17@angel_SWIreason_EnterSVC

swi0x123456@angel_SWI_ARM//调用软中断指令进入管理模式

not_angel:

mrsr2,cpsr@turnoffinterruptsto

orrr2,r2,#0xc0@preventangelfromrunning

msrcpsr_c,r2

#else

teqppc,#0x0c000003@turnoffinterrupts(此外bootloader已经设置模式为svc)

#endif

/*

*Notethatsomecacheflushingandotherstuffmay

*beneededhere-isthereanAngelSWIcallforthis?

*/

/*

*somearchitecturespecificcodecanbeinserted(插入)

*bythelinkerhere,butitshouldpreserver7,r8,andr9.(r7,r8,r9要保留,r7保存架构ID,r8保存内核启动参数地址)

*/

.text

/*

*此处确定解压后的内核映像的绝对地址(物理地址),保存于r4

*由于配置的不同可能有的结果

*

(1)定义了CONFIG_AUTO_ZRELADDR

*ZRELADDR是已解压内核最终存放的物理地址

*如果AUTO_ZRELADDR被选择了,这个地址将会在运行时确定:

*将当pc值和0xf8000000做与操作,

*并加上TEXT_OFFSET(内核最终存放的物理地址与内存起始的偏移)

*这里假定zImage被放在内存开始的128MB内

*

(2)没有定义CONFIG_AUTO_ZRELADDR

*直接使用zreladdr(此值位于arch/arm/mach-xxx/Makefile.boot文件确定)

*/

/*把LC0的数据依次存入r1,r2,r3,r4,r5,r6,ip,sp,LC0中存储的正是

*.wordLC0@r1

*.word__bss_start@r2

*.word_end@r3

*.word_load_addr@r4

*.word_start@r5

*.word_got_start@r6

*.word_got_end@ip

*.worduser_stack+40Array6@sp

*因为此时r0是LC0的地址,r1中存放的是初始地址,跟它相减计算

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1