[ZLG-ARM] u-boot学习报告(上)

[复制链接]
 楼主| armqt 发表于 2009-7-9 13:31 | 显示全部楼层 |阅读模式
1.<br />u-boot简介1.1.<br />概述U-Boot,全称Universal&nbsp;Boot&nbsp;Loader,是遵循GPL条款的开放源码项目,从FADSROM、8xxROM、PPCBOOT逐步发展演化而来,其源码目录、编译形式与Linux内核很相似。事实上,不少U-Boot源码就是相应Linux内核源程序的简化,尤其是一些设备的驱动程序,从UBoot源码的注释中能体现这一点。但是U-Boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD、VxWorks、QNX、RTEMS、ARTOS、LynxOS嵌入式操作系统。其目前要支持的目标操作系统包括OpenBSD、NetBSD、FreeBSD、4.4BSD、Linux、SVR4、Esix、Solaris、Irix、SCO、Dell、NCR、VxWorks、LynxOS、pSOS、QNX、RTEMS和ARTOS。这是U-Boot中Universal的一层含义。另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、Nios、xScale等诸多常用系列的处理器。这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。其它系列的处理器和操作系统基本是在2002年11月PPCBOOT改名为U-Boot后逐步扩充的。从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人,德国DENX软件工程中心的Wolfgang&nbsp;Denk(以下简称W.D)本人精湛的专业水平和持着不懈的努力。当前,U-Boot项目在他的领军下,众多有志于开放源码Bootloader移植工作的嵌入式开发人员,正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多嵌入式操作系统的装载与引导。<br />1.2.<br />U-Boot主要目录结构<br />board——目标板相关文件,主要包含SDRAM、Flash驱动;&nbsp;<br />common——独立于处理器体系结构的通用代码,如&nbsp;内存大小探测与故障检测;&nbsp;<br />cpu——与处理器相关的文件,如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;&nbsp;<br />driver——通用设备驱动,如CFI&nbsp;Flash驱动(目前对Intel&nbsp;Flash支持较好)&nbsp;<br />doc——U-Boot的说明文档;&nbsp;<br />examples——可在U-Boot下运行的示例程序;如&nbsp;&nbsp;helloworld.c,timer.c;&nbsp;<br />include——U-Boot头文件,configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;&nbsp;<br />lib_xxx——处理器体系相关的文件,如lib—ppc,lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件;&nbsp;<br />net——与网络功能相关的文件目录,如bootp、nfs、tftp;&nbsp;<br />post——上电自检文件目录,尚有待于进一步完善;&nbsp;<br />rtc——RTC驱动程序;&nbsp;<br />tools——用于创建U-Boot&nbsp;S-RECORD和BIN镜像文件的工具。&nbsp;<br />1.3.<br />U-Boot支持的主要功能U-Boot可支持的主要功能如表1所列。<br />表格&nbsp;1<br />系统引导<br />&nbsp;支持NFS挂载、RAMDISK(压缩或非压缩)形式的根文件系统&nbsp;<br />&nbsp;<br />支持NTS挂载,从Flash中引导压缩或非压缩系统内核<br />&nbsp;<br />基本辅助功能<br />&nbsp;强大的操作系统接口功能,可灵活设置、传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,尤其对Linux支持最为强劲&nbsp;<br />&nbsp;<br />支持目标板环境参数的多种存储方式,如Flash、NVRAIvl、EEPROM&nbsp;&nbsp;<br />&nbsp;<br />CRC32校验,可校验Flash中内核、RAMDISK镜像文件是否完好<br />&nbsp;<br />设备驱动<br />&nbsp;串口、SDRAM、Flash、以太网、LCD、NVRA/vl、EEPROM、键盘、JSB、PCMCIA、PCI、RTC等驱动支持&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;<br />上电自检功能<br />&nbsp;SDRAM、Flash大小自动检测;SDRAM故障检测:CPLy型号<br />&nbsp;<br />特殊功能<br />&nbsp;xⅢ内核引导&nbsp;<br />&nbsp;<br /><br />2.<br />u-boot启动过程2.1.<br />启动模式Boot&nbsp;loader启动模式通常有两种:启动加载模式和下载模式。u-boot作为boot&nbsp;loader的一种也不例外。<br />启动加载模式:整个系统启动过程是自主的,完全没有人的干预。<br />下载模式:linux内核在加载时有开发人员控制,通过串口或者网络进行加载的方式。<br />对于普通用户来说,一般都用在启动加载模式,但是对于开发人员来数,则需要运行在下载模式下,因为开发过程中需要经常更新镜像。为了达到两者兼顾的目的,通常,采用两种模式相结合的方式。复位后,boot&nbsp;loader&nbsp;首先进行初始化工作,结束后不是立刻加载linux镜像,而是等待一段时间,如果用户有键盘输入,就进入下载模式,否则进入启动加载模式。<br />2.2.<br />启动的阶段u-boot启动分为两个阶段。第一阶段主要针对与CPU体系结构和存储设备密切相关部分作一些必要的初始化工作,是一些依赖于CPU结构的代码,为了增加效率以及涉及到处理器的设置,只能采用汇编语言编写。第二阶段主要针对目标板一级的一些初始化工作并且提供一些驱动的支持,用c语言实现。<br /><br /><br />2.3.<br />启动代码分析首先我们整体上浏览下u-boot启动代码的流程图。<br /><br /><br /><br /><br />relocate<br /><br />&nbsp;<br /><br />Stack_setup<br /><br />&nbsp;<br />Start_armboot()<br /><br />&nbsp;<br />Init_sequence[]<br /><br />……<br />Getenv()<br /><br />&nbsp;<br />Cpu_init_crit<br /><br />&nbsp;<br />Main_loop()<br /><br />&nbsp;<br />Lowelevel_init.S<br /><br />&nbsp;<br />Reset<br /><br /><br />&nbsp;<br /><br />下面详细分析各个阶段中代码的具体工作。<br />1.&nbsp;Start.S<br />源码位置:cpu/arm920t/start.S<br />运行位置:Flash<br />描述:一个可执行的映像有且只有一个全局入口。这个入口点为处理器复位取第一条指令的位置。U-boot映像的入口就是start.S。这个可以通过&nbsp;board/smdk2410/u-boot.lds连接脚本文件决定。<br /><br />.globl&nbsp;_start<br />_start:<br />b<br />reset<br />//复位向量<br /><br />ldr<br />pc,&nbsp;_undefined_instruction<br /><br />ldr<br />pc,&nbsp;_software_interrupt<br /><br />ldr<br />pc,&nbsp;_prefetch_abort<br /><br />ldr<br />pc,&nbsp;_data_abort<br /><br />ldr<br />pc,&nbsp;_not_used<br /><br />ldr<br />pc,&nbsp;_irq<br /><br />ldr<br />pc,&nbsp;_fiq<br /><br />_undefined_instruction:<br />.word&nbsp;undefined_instruction<br />_software_interrupt:<br />.word&nbsp;software_interrupt<br />_prefetch_abort:<br />.word&nbsp;prefetch_abort<br />_data_abort:<br />.word&nbsp;data_abort<br />_not_used:<br /><br />.word&nbsp;not_used<br />_irq:<br />.word&nbsp;irq<br />//中断向量<br />_fiq:<br />.word&nbsp;fiq<br /><br />//快速中断向量<br /><br /><br /><br />_TEXT_BASE:<br /><br />.word<br />TEXT_BASE<br /><br />.globl&nbsp;_armboot_start<br />_armboot_start:<br /><br />.word&nbsp;_start<br /><br />/*<br /><br />*&nbsp;These&nbsp;are&nbsp;defined&nbsp;in&nbsp;the&nbsp;board-specific&nbsp;linker&nbsp;script.<br /><br />*/<br />.globl&nbsp;_bss_start<br />_bss_start:<br /><br />.word&nbsp;__bss_start<br /><br />.globl&nbsp;_bss_end<br />_bss_end:<br /><br />.word&nbsp;_end<br /><br />#ifdef&nbsp;CONFIG_USE_IRQ<br />/*&nbsp;IRQ&nbsp;stack&nbsp;memory&nbsp;(calculated&nbsp;at&nbsp;run-time)&nbsp;*/<br />.globl&nbsp;IRQ_STACK_START<br />IRQ_STACK_START:<br /><br />.word<br />0x0badc0de<br /><br />/*&nbsp;IRQ&nbsp;stack&nbsp;memory&nbsp;(calculated&nbsp;at&nbsp;run-time)&nbsp;*/<br />.globl&nbsp;FIQ_STACK_START<br />FIQ_STACK_START:<br /><br />.word&nbsp;0x0badc0de<br />#endif<br /><br /><br />/*<br /><br />*&nbsp;the&nbsp;actual&nbsp;reset&nbsp;code<br /><br />*/<br /><br />reset:<br />//复位启动子程序<br /><br />/*&nbsp;设置CPU<br />为SVC32模式<br />*/<br /><br />mrs<br />r0,cpsr<br /><br />bic<br />r0,r0,#0x1f<br /><br />orr<br />r0,r0,#0xd3<br /><br />msr<br />cpsr,r0<br /><br />/*&nbsp;关闭看门狗&nbsp;*/<br />#if&nbsp;defined(CONFIG_S3C2400)<br />#&nbsp;define&nbsp;pWTCON<br />0x15300000<br />#&nbsp;define&nbsp;INTMSK<br />0x14400008<br />/*&nbsp;Interupt-Controller&nbsp;base&nbsp;addresses&nbsp;*/<br />#&nbsp;define&nbsp;CLKDIVN<br />0x14800014<br />/*&nbsp;clock&nbsp;divisor&nbsp;register&nbsp;*/<br />#elif&nbsp;defined(CONFIG_S3C2410)<br />#&nbsp;define&nbsp;pWTCON<br />0x53000000<br />#&nbsp;define&nbsp;INTMSK<br />0x4A000008<br />/*&nbsp;Interupt-Controller&nbsp;base&nbsp;addresses&nbsp;*/<br />#&nbsp;define&nbsp;INTSUBMSK<br />0x4A00001C<br />#&nbsp;define&nbsp;CLKDIVN<br />0x4C000014<br />/*&nbsp;clock&nbsp;divisor&nbsp;register&nbsp;*/<br />#endif<br /><br />#if&nbsp;defined(CONFIG_S3C2400)&nbsp;||&nbsp;defined(CONFIG_S3C2410)<br /><br />ldr<br />r0,&nbsp;=pWTCON<br /><br />mov<br />r1,&nbsp;#0x0<br /><br />str<br />r1,&nbsp;[r0]<br /><br /><br />/*<br /><br /><br />*&nbsp;mask&nbsp;all&nbsp;IRQs&nbsp;by&nbsp;setting&nbsp;all&nbsp;bits&nbsp;in&nbsp;the&nbsp;INTMR&nbsp;-&nbsp;default<br /><br /><br />*/<br /><br />mov<br />r1,&nbsp;#0xffffffff<br /><br />ldr<br />r0,&nbsp;=INTMSK<br /><br />str<br />r1,&nbsp;[r0]<br />#&nbsp;if&nbsp;defined(CONFIG_S3C2410)<br /><br />ldr<br />r1,&nbsp;=0x3ff<br /><br />ldr<br />r0,&nbsp;=INTSUBMSK<br /><br />str<br />r1,&nbsp;[r0]<br />#&nbsp;endif<br /><br /><br />/*&nbsp;FCLK:HCLKCLK&nbsp;=&nbsp;1:2:4&nbsp;*/<br /><br />/*&nbsp;default&nbsp;FCLK&nbsp;is&nbsp;120&nbsp;MHz&nbsp;!&nbsp;*/<br /><br />ldr<br />r0,&nbsp;=CLKDIVN<br /><br />mov<br />r1,&nbsp;#3<br /><br />str<br />r1,&nbsp;[r0]<br />#endif<br />/*&nbsp;CONFIG_S3C2400&nbsp;||&nbsp;CONFIG_S3C2410&nbsp;*/<br /><br /><br />/*<br />关键的初始化代码在系统重启是执行,而在热复位也就是直接从RAM中启动不执行<br /><br />*/<br />#ifndef&nbsp;CONFIG_SKIP_LOWLEVEL_INIT<br /><br />bl<br />cpu_init_crit<br />#endif<br /><br />#ifndef&nbsp;CONFIG_SKIP_RELOCATE_UBOOT<br />relocate:<br />/*&nbsp;把u-boot重新定位到RAM<br /><br />*/<br /><br />adr<br />r0,&nbsp;_start<br /><br />/*&nbsp;把代码的当前位置也就是需要复制代码的起始地址放到r0&nbsp;*/<br /><br />ldr<br />r1,&nbsp;_TEXT_BASE<br />/*&nbsp;测试启动从Flash还是RAM&nbsp;*/<br /><br />cmp<br />r0,&nbsp;r1<br />/*&nbsp;比较r0和r1,调试的时候也就是都是从RAM启动*/<br />beq<br />stack_setup<br />/*的情况下,不需要重定位,跳过重定位代码&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />ldr<br />r2,&nbsp;_armboot_start<br />/*准备重新定位代码,得到_armboot_start的位置*/<br /><br />ldr<br />r3,&nbsp;_bss_start<br />/*得到_bss_start的位置*/<br /><br />sub<br />r2,&nbsp;r3,&nbsp;r2<br /><br />/*r2为arm_boot的大小<br />*/<br /><br />add<br />r2,&nbsp;r0,&nbsp;r2<br /><br />/*&nbsp;r2得到需要复制代码的末尾地址&nbsp;*/<br /><br />copy_loop:<br />/*&nbsp;重新定位代码,也就是执行从代码从flash到RAM的拷贝工作*/<br /><br />ldmia<br />r0!,&nbsp;{r3-r10}<br />/*&nbsp;copy&nbsp;from&nbsp;source&nbsp;address&nbsp;[r0]<br />*/<br /><br />stmia<br />r1!,&nbsp;{r3-r10}<br />/*&nbsp;copy&nbsp;to<br />target&nbsp;address&nbsp;[r1]<br />*/<br /><br />cmp<br />r0,&nbsp;r2<br />/*&nbsp;until&nbsp;source&nbsp;end&nbsp;addreee&nbsp;[r2]<br />*/<br /><br />ble<br />copy_loop<br />#endif<br />/*&nbsp;CONFIG_SKIP_RELOCATE_UBOOT&nbsp;*/<br /><br /><br />/*&nbsp;初始化堆栈<br />*/<br />stack_setup:<br /><br />ldr<br />r0,&nbsp;_TEXT_BASE<br />/*&nbsp;上面128KiB是重定位后的u-boot<br />*/<br /><br />sub<br />r0,&nbsp;r0,&nbsp;#CFG_MALLOC_LEN<br /><br />/*向下是内存分配空间<br />*/<br /><br />sub<br />r0,&nbsp;r0,&nbsp;#CFG_GBL_DATA_SIZE&nbsp;<br />/*然后是bdinfo结构体地址空间<br />*/<br />#ifdef&nbsp;CONFIG_USE_IRQ<br /><br />sub<br />r0,&nbsp;r0,&nbsp;#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)<br />#endif<br /><br />sub<br />sp,&nbsp;r0,&nbsp;#12<br />/*&nbsp;为abort-stack预留3个字<br />*/<br /><br />clear_bss:<br /><br />ldr<br />r0,&nbsp;_bss_start<br />/*&nbsp;找到bss&nbsp;段起始地址<br />*/<br /><br />ldr<br />r1,&nbsp;_bss_end<br />/*&nbsp;bss段的末尾地址<br />*/<br /><br />mov&nbsp;<br />r2,&nbsp;#0x00000000<br />/*&nbsp;清零<br />*/<br /><br />clbss_l:str<br />r2,&nbsp;[r0]<br />/*&nbsp;bss段地址空间循环清零<br />*/<br /><br />add<br />r0,&nbsp;r0,&nbsp;#4<br /><br />cmp<br />r0,&nbsp;r1<br /><br />ble<br />clbss_l<br /><br />/*&nbsp;跳转到start_armboot函数入口,&nbsp;_start_armboot字保存函数的入口地址&nbsp;*/<br /><br />ldr<br />pc,&nbsp;_start_armboot<br /><br />_start_armboot:<br />.word&nbsp;start_armboot<br /><br /><br />#ifndef&nbsp;CONFIG_SKIP_LOWLEVEL_INIT<br />cpu_init_crit:<br />/*关键的初始化程序&nbsp;*/<br /><br />/*<br /><br /><br />初始化CACHE<br /><br /><br />*/<br /><br />mov<br />r0,&nbsp;#0<br /><br />mcr<br />p15,&nbsp;0,&nbsp;r0,&nbsp;c7,&nbsp;c7,&nbsp;0<br />/*&nbsp;flush&nbsp;v3/v4&nbsp;cache&nbsp;*/<br /><br />mcr<br />p15,&nbsp;0,&nbsp;r0,&nbsp;c8,&nbsp;c7,&nbsp;0<br />/*&nbsp;flush&nbsp;v4&nbsp;TLB&nbsp;*/<br /><br /><br />/*<br /><br /><br />*&nbsp;关闭MMU&nbsp;和&nbsp;CACHE<br /><br /><br />*/<br /><br />mrc<br />p15,&nbsp;0,&nbsp;r0,&nbsp;c1,&nbsp;c0,&nbsp;0<br /><br />bic<br />r0,&nbsp;r0,&nbsp;#0x00002300<br />@&nbsp;clear&nbsp;bits&nbsp;13,&nbsp;9:8&nbsp;(--V-&nbsp;--RS)<br /><br />bic<br />r0,&nbsp;r0,&nbsp;#0x00000087<br />@&nbsp;clear&nbsp;bits&nbsp;7,&nbsp;2:0&nbsp;(B---&nbsp;-CAM)<br /><br />orr<br />r0,&nbsp;r0,&nbsp;#0x00000002<br />@&nbsp;set&nbsp;bit&nbsp;2&nbsp;(A)&nbsp;Align<br /><br />orr<br />r0,&nbsp;r0,&nbsp;#0x00001000<br />@&nbsp;set&nbsp;bit&nbsp;12&nbsp;(I)&nbsp;I-Cache<br /><br />mcr<br />p15,&nbsp;0,&nbsp;r0,&nbsp;c1,&nbsp;c0,&nbsp;0<br /><br /><br />/*<br /><br /><br />*&nbsp;before&nbsp;relocating,&nbsp;we&nbsp;have&nbsp;to&nbsp;setup&nbsp;RAM&nbsp;timing<br /><br /><br />*&nbsp;because&nbsp;memory&nbsp;timing&nbsp;is&nbsp;board-dependend,&nbsp;you&nbsp;will<br /><br /><br />*&nbsp;find&nbsp;a&nbsp;lowlevel_init.S&nbsp;in&nbsp;your&nbsp;board&nbsp;directory.<br /><br /><br />*/<br /><br />mov<br />ip,&nbsp;lr<br /><br />bl<br />lowlevel_init<br /><br />mov<br />lr,&nbsp;ip<br /><br />mov<br />pc,&nbsp;lr<br />#endif&nbsp;/*&nbsp;CONFIG_SKIP_LOWLEVEL_INIT&nbsp;*/<br /><br />/*<br /><br />*************************************************************************<br /><br />*<br /><br />*&nbsp;中断向量<br /><br />*<br /><br />*************************************************************************<br /><br />*/<br /><br />@<br />@&nbsp;IRQ&nbsp;stack&nbsp;frame.<br />@<br />#define&nbsp;S_FRAME_SIZE<br />72<br /><br />#define&nbsp;S_OLD_R0<br />68<br />#define&nbsp;S_PSR<br />64<br />#define&nbsp;S_PC<br />60<br />#define&nbsp;S_LR<br />56<br />#define&nbsp;S_SP<br />52<br /><br />#define&nbsp;S_IP<br />48<br />#define&nbsp;S_FP<br />44<br />#define&nbsp;S_R10<br />40<br />#define&nbsp;S_R9<br />36<br />#define&nbsp;S_R8<br />32<br />#define&nbsp;S_R7<br />28<br />#define&nbsp;S_R6<br />24<br />#define&nbsp;S_R5<br />20<br />#define&nbsp;S_R4<br />16<br />#define&nbsp;S_R3<br />12<br />#define&nbsp;S_R2<br />8<br />#define&nbsp;S_R1<br />4<br />#define&nbsp;S_R0<br />0<br /><br />#define&nbsp;MODE_SVC&nbsp;0x13<br />#define&nbsp;I_BIT<br />0x80<br /><br />/*<br /><br />*&nbsp;use&nbsp;bad_save_user_regs&nbsp;for&nbsp;abort/prefetch/undef/swi&nbsp;...<br /><br />*&nbsp;use&nbsp;irq_save_user_regs&nbsp;/&nbsp;irq_restore_user_regs&nbsp;for&nbsp;IRQ/FIQ&nbsp;handling<br /><br />*/<br /><br /><br />.macro<br />bad_save_user_regs<br /><br />sub<br />sp,&nbsp;sp,&nbsp;#S_FRAME_SIZE<br /><br />stmia<br />sp,&nbsp;{r0&nbsp;-&nbsp;r12}<br />@&nbsp;Calling&nbsp;r0-r12<br /><br />ldr<br />r2,&nbsp;_armboot_start<br /><br />sub<br />r2,&nbsp;r2,&nbsp;#(CONFIG_STACKSIZE+CFG_MALLOC_LEN)<br /><br />sub<br />r2,&nbsp;r2,&nbsp;#(CFG_GBL_DATA_SIZE+8)<br />@&nbsp;set&nbsp;base&nbsp;2&nbsp;words&nbsp;into&nbsp;abort&nbsp;stack<br /><br />ldmia<br />r2,&nbsp;{r2&nbsp;-&nbsp;r3}<br />@&nbsp;get&nbsp;pc,&nbsp;cpsr<br /><br />add<br />r0,&nbsp;sp,&nbsp;#S_FRAME_SIZE<br />@&nbsp;restore&nbsp;sp_SVC<br /><br /><br />add<br />r5,&nbsp;sp,&nbsp;#S_SP<br /><br />mov<br />r1,&nbsp;lr<br /><br />stmia<br />r5,&nbsp;{r0&nbsp;-&nbsp;r3}<br />@&nbsp;save&nbsp;sp_SVC,&nbsp;lr_SVC,&nbsp;pc,&nbsp;cpsr<br /><br />mov<br />r0,&nbsp;sp<br /><br />.endm<br /><br /><br />.macro<br />irq_save_user_regs<br /><br />sub<br />sp,&nbsp;sp,&nbsp;#S_FRAME_SIZE<br /><br />stmia<br />sp,&nbsp;{r0&nbsp;-&nbsp;r12}<br />@&nbsp;Calling&nbsp;r0-r12<br /><br />add<br />r8,&nbsp;sp,&nbsp;#S_PC<br /><br />stmdb<br />r8,&nbsp;{sp,&nbsp;lr}^<br />@&nbsp;Calling&nbsp;SP,&nbsp;LR<br /><br />str<br />lr,&nbsp;[r8,&nbsp;#0]<br />@&nbsp;Save&nbsp;calling&nbsp;PC<br /><br />mrs<br />r6,&nbsp;spsr<br /><br />str<br />r6,&nbsp;[r8,&nbsp;#4]<br />@&nbsp;Save&nbsp;CPSR<br /><br />str<br />r0,&nbsp;[r8,&nbsp;#8]<br />@&nbsp;Save&nbsp;OLD_R0<br /><br />mov<br />r0,&nbsp;sp<br /><br />.endm<br /><br /><br />.macro<br />irq_restore_user_regs<br /><br />ldmia<br />sp,&nbsp;{r0&nbsp;-&nbsp;lr}^<br />@&nbsp;Calling&nbsp;r0&nbsp;-&nbsp;lr<br /><br />mov<br />r0,&nbsp;r0<br /><br />ldr<br />lr,&nbsp;[sp,&nbsp;#S_PC]<br />@&nbsp;Get&nbsp;PC<br /><br />add<br />sp,&nbsp;sp,&nbsp;#S_FRAME_SIZE<br /><br />subs<br />pc,&nbsp;lr,&nbsp;#4<br />@&nbsp;return&nbsp;&&nbsp;move&nbsp;spsr_svc&nbsp;into&nbsp;cpsr<br /><br />.endm<br /><br /><br />.macro&nbsp;get_bad_stack<br /><br />ldr<br />r13,&nbsp;_armboot_start<br />@&nbsp;setup&nbsp;our&nbsp;mode&nbsp;stack<br /><br />sub<br />r13,&nbsp;r13,&nbsp;#(CONFIG_STACKSIZE+CFG_MALLOC_LEN)<br /><br />sub<br />r13,&nbsp;r13,&nbsp;#(CFG_GBL_DATA_SIZE+8)&nbsp;@&nbsp;reserved&nbsp;a&nbsp;couple&nbsp;spots&nbsp;in&nbsp;abort&nbsp;stack<br /><br /><br />str<br />lr,&nbsp;[r13]<br />@&nbsp;save&nbsp;caller&nbsp;lr&nbsp;/&nbsp;spsr<br /><br />mrs<br />lr,&nbsp;spsr<br /><br />str<br />lr,&nbsp;[r13,&nbsp;#4]<br /><br /><br />mov<br />r13,&nbsp;#MODE_SVC<br />@&nbsp;prepare&nbsp;SVC-Mode<br /><br />@&nbsp;msr<br />spsr_c,&nbsp;r13<br /><br />msr<br />spsr,&nbsp;r13<br /><br />mov<br />lr,&nbsp;pc<br /><br />movs<br />pc,&nbsp;lr<br /><br />.endm<br /><br /><br />.macro&nbsp;get_irq_stack<br />@&nbsp;setup&nbsp;IRQ&nbsp;stack<br /><br />ldr<br />sp,&nbsp;IRQ_STACK_START<br /><br />.endm<br /><br /><br />.macro&nbsp;get_fiq_stack<br />@&nbsp;setup&nbsp;FIQ&nbsp;stack<br /><br />ldr<br />sp,&nbsp;FIQ_STACK_START<br /><br />.endm<br /><br />/*<br /><br />*异常向量<br /><br />*/<br /><br />.align<br />5<br />undefined_instruction:<br /><br />get_bad_stack<br /><br />bad_save_user_regs<br /><br />bl&nbsp;<br />do_undefined_instruction<br /><br /><br />.align<br />5<br />software_interrupt:<br /><br />get_bad_stack<br /><br />bad_save_user_regs<br /><br />bl&nbsp;<br />do_software_interrupt<br /><br /><br />.align<br />5<br />prefetch_abort:<br /><br />get_bad_stack<br /><br />bad_save_user_regs<br /><br />bl&nbsp;<br />do_prefetch_abort<br /><br /><br />.align<br />5<br />data_abort:<br /><br />get_bad_stack<br /><br />bad_save_user_regs<br /><br />bl&nbsp;<br />do_data_abort<br /><br /><br />.align<br />5<br />not_used:<br /><br />get_bad_stack<br /><br />bad_save_user_regs<br /><br />bl&nbsp;<br />do_not_used<br /><br />#ifdef&nbsp;CONFIG_USE_IRQ<br /><br /><br />.align<br />5<br />irq:<br /><br />get_irq_stack<br /><br />irq_save_user_regs<br /><br />bl&nbsp;<br />do_irq<br /><br />irq_restore_user_regs<br /><br /><br />.align<br />5<br />fiq:<br /><br />get_fiq_stack<br /><br />/*&nbsp;someone&nbsp;ought&nbsp;to&nbsp;write&nbsp;a&nbsp;more&nbsp;effiction&nbsp;fiq_save_user_regs&nbsp;*/<br /><br />irq_save_user_regs<br /><br />bl&nbsp;<br />do_fiq<br /><br />irq_restore_user_regs<br /><br />#else<br /><br /><br />.align<br />5<br />irq:<br /><br />get_bad_stack<br /><br />bad_save_user_regs<br /><br />bl&nbsp;<br />do_irq<br /><br /><br />.align<br />5<br />fiq:<br /><br />get_bad_stack<br /><br />bad_save_user_regs<br /><br />bl&nbsp;<br />do_fiq<br /><br />#endif<br />
tmake 发表于 2009-7-9 13:45 | 显示全部楼层

好长啊!你要把代码全贴上估计还得好几页!

  
lpc2410 发表于 2009-7-9 14:04 | 显示全部楼层

很详细

  
 楼主| armqt 发表于 2009-7-24 18:05 | 显示全部楼层

共同学习

  
bespecial 发表于 2009-11-21 17:59 | 显示全部楼层
学习一下 标记
linhai1986 发表于 2009-11-21 21:39 | 显示全部楼层
不错,写的很详细
linhai1986 发表于 2009-11-21 21:39 | 显示全部楼层
赞一个:)
LIU_XF 发表于 2009-11-21 21:42 | 显示全部楼层
学习一下,做个标记

非常感谢楼主分享
xiaoxin1986 发表于 2009-11-22 00:20 | 显示全部楼层
好长啊
xiaoxin1986 发表于 2009-11-22 00:20 | 显示全部楼层
赞一下LZ
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

150

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部