文档库 最新最全的文档下载
当前位置:文档库 › ARM 启动代码详解(Vectors.c、Init.s、Target.c、 Target.h)

ARM 启动代码详解(Vectors.c、Init.s、Target.c、 Target.h)

ARM 启动代码详解(Vectors.c、Init.s、Target.c、 Target.h)
ARM 启动代码详解(Vectors.c、Init.s、Target.c、 Target.h)

ARM启动代码详解(Vectors.c、Init.s、Target.c、Target.h)

启动代码是芯片复位后进入C语言的main()函数前执行的一段代码,主要是为运行C语言程序提供基本运行环境,如初始化存储器系统等。ARM公司只设计内核,不自己生产芯片,只是把内核授权给其它厂商,其它厂商购买了授权且加入自己的外设后生产出各具特色的芯片。这样就促进了基于ARM处理器核的芯片多元化,但也使得每一种芯片的启动代码差别很大,不易编写出统一的启动代码。ADS(针对ARM 处理器核的C语言编译器)的策略是不提供完整的启动代码,启动代码不足部分或者由厂商提供,或者自己编写。启动代码划分为4个文件:Vectors.c、Init.s、Target.c、Target.h。Vectors.c包含异常向量表、堆栈初始化及中断服务程序与C程序的接口。Init.s包含统初始化代码,并跳转到ADS提供的初始化代码。Target.c和Target.h包含目标板特殊的代码,包括异常处理程序和目标板初始化程序。这样做的目的是为了尽量减少汇编代码,同时把不需要修改的代码独立出来以减少错误。

§4.2.1Vectors.c文件的编写

§4.2.1.1中断向量表

Vectors

LDR PC,ResetAddr

LDR PC,UndefinedAddr

LDR PC,SWI_Addr

LDR PC,PrefetchAddr

LDR PC,DataAbortAddr

DCD0xb9205f80

LDR PC,[PC,#-0xff0]

LDR PC,FIQ_Addr

ResetAddr DCD Reset

UndefinedAddr DCD Undefined

SWI_Addr DCD SoftwareInterrupt

PrefetchAddr DCD PrefetchAbort

DataAbortAddr DCD DataAbort

nouse DCD0

IRQ_Addr DCD IRQ_Handler

FIQ_Addr DCD FIQ_Handler

异常是由内部或外部源产生的以引起处理器处理的一个事件。ARM处理器核支持7种类型的异常。异常出现后,CPU强制从异常类型对应的固定存储地址开始执行程序。这个固定的地址就是异常向量。向量从上到下依次为复位、未定义指令异常、软件中断、预取指令中止、预取数据中止、保留的异常、IRQ 和FIQ。IRQ向量“LDR PC,[PC,#-0xff0]”使用的指令与其它向量不同。在正常情况下这条指令所在地

址为0X00000018。当CPU执行这条指令但还没有跳转时,PC的值为0X00000020,0X00000020减去0X00000FF0为0XFFFFF030,这是向量中断控制器(VIC)的特殊寄存器VICVectAddr。这个寄存器保存当前将要服务的IRQ的中断服务程序的入口,用这一条指令就可以直接跳转到需要的中断服务程序中。至于在保留的异常向量“DCD0xb9205f80”位置填数据0xb9205f8是为了使向量表中所有的数据32位累加和为0。

§4.2.1.2初始化CPU堆栈

InitStack

MOV R0,LR

MSR CPSR_c,#0xd2;设置中断模式堆栈

LDR SP,StackIrq

MSR CPSR_c,#0xd1;设置快速中断模式堆栈

LDR SP,StackFiq

MSR CPSR_c,#0xd7;设置中止模式堆栈

LDR SP,StackAbt

MSR CPSR_c,#0xdb;设置未定义模式堆栈

LDR SP,StackUnd

MSR CPSR_c,#0xdf;设置系统模式堆栈

LDR SP,StackSys

MOV PC,R0

StackIrq DCD(IrqStackSpace+IRQ_STACK_LEGTH*4-4)

StackFiq DCD(FiqStackSpace+FIQ_STACK_LEGTH*4-4)

StackAbt DCD(AbtStackSpace+ABT_STACK_LEGTH*4-4)

StackUnd DCD(UndtStackSpace+UND_STACK_LEGTH*4-4)

StackSys DCD(SysStackSpace+SYS_STACK_LEGTH*4-4)

;/*分配堆栈空间*/

AREA MyStacks,DATA,NOINIT

IrqStackSpace SPACE IRQ_STACK_LEGTH*4;中断模式堆栈

FiqStackSpace SPACE FIQ_STACK_LEGTH*4;快速中断模式堆栈

AbtStackSpace SPACE ABT_STACK_LEGTH*4;中止义模式堆栈

UndtStackSpace SPACE UND_STACK_LEGTH*4;未定义模式堆栈

SysStackSpace SPACE SYS_STACK_LEGTH*4;系统模式堆栈

因为程序需要切换模式,而且程序退出时CPU的模式已经不再是管理模式而是系统模式LR已经不再保存返回程序地址,所以程序首先把返回地址保存到R0中,同时使用R0返回。然后程序把处理器模式转化为IRQ模式,并设置IRQ模式的堆栈指针。其中变量Stacklrq保存着IRQ模式的堆栈指针的初始值,Irqstackspace是分配给IRQ模式的堆栈空间的开始地址,IRQ_STACK_LEGTH是用户定义的常量,用于设置IRQ模式的堆栈空间的大小。程序使用同样的方法设置FIQ模式堆栈指针、中止模式堆栈指针、未定义堆栈指针和系统模式堆栈指针。

程序使用编译器分配的空间作为堆栈,而不是按照通常的做法把堆栈分配到RAM的顶端,之所以这样是因为这样做不必知道RAM顶端位置,移植更加方便;编译器给出的占用RAM空间的大小就是实际占用的大小,便于控制RAM的分配。对于LPC2106来说,中止模式是不需要分配堆栈空间的,这是因为LPC2106没有外部总线,也没有虚拟内存机制,如果出现取数据中止或取指令中止肯定是程序有问题。而一般情况下也不需要模拟协处理器指令或扩充指令,未定义中止也就意味着程序有错误,也不需要分配堆栈空间。

§4.2.1.3异常处理代码与C语言的接口程序

μC/OS-Ⅱ中断服务子程序流程图如图4-1所示:

图4-1中断服务子程序流程图

异常处理代码与C语言的接口程序如下:

MACRO

$IRQ_Label HANDLER$IRQ_Exception

EXPORT$IRQ_Label;输出的标号

IMPORT$IRQ_Exception;引用的外部标号$IRQ_Label

SUB LR,LR,#4;计算返回地址

STMFD SP!,{R0-R3,R12,LR};保存任务环境

MRS R3,SPSR;保存状态

STMFD SP!,{R3}

LDR R2,=OSIntNesting;OSIntNesting++

LDRB R1,[R2]

ADD R1,R1,#1

STRB R1,[R2]

BL$IRQ_Exception;调用c语言的中断处理程序MSR CPSR_c,#0x92;关中断

BL OSIntExit

LDR R0,=OSTCBHighRdy

LDR R0,[R0]

LDR R1,=OSTCBCur

LDR R1,[R1]

CMP R0,R1

LDMFD SP!,{R3}

MSR SPSR_cxsf,R3

LDMEQFD SP!,{R0-R3,R12,PC}^;不进行任务切换LDR PC,=OSIntCtxSw;进行任务切换

MEND

Undefined;未定义指令

b Undefined

PrefetchAbort;取指令中止

b PrefetchAbort

DataAbort;取数据中止

b DataAbort

IRQ_Handler HANDLER IRQ_Exception;中断

FIQ_Handler;快速中断

b FIQ_Handler

Timer0_Handler HANDLER Timer0;定时器0中断

未定义指令异常、取指令中止异常、取数据中止异常均是死循环,其中原因在上一小节已经说明。而快速中断在本应用中并未使用,所以也设置为死循环。LPC2106使用向量中断控制器,各个IRQ中断的人口不一样,所以使用了一个宏来简化中断服务程序与C语言的接口编写。由ARM处理器核的文档可知,处理器进入IRQ中断服务程序时(LR-4)的值为中断返回地址,为了使任务无论在主动放弃CPU 时还是中断时堆栈结构都一样,在这里先把LR减4。其它的部分与μC/OS-Ⅱ要求的基本一致。ARM处理核在进入中断服务程序时处理器模式变为IRQ模式,与任务的模式不同,它们的堆栈指针SP也不一样,而寄存器应当保存到用户的堆栈中,为了减少不必要的CPU时间和RAM空间的浪费,本移植仅在必要时将处理器的寄存器保存到用户的堆栈中,其它时候还是保存到IRQ模式的堆栈中。同时,从编译器的函数调用规范可知,C语言函数返回时,寄存器R4—R11、SP不会改变,所以只需要保存CPSR、R0—R3、R12和返回地址LR,在后面保存CPSR是为了必要时将寄存器保存到用户堆栈比较方便。

在异常处理代码与C语言的接口程序中没有与中断服务子程序流程图中的判断语句对应的语句。判断语句是为了避免在函数OSIntCtxsw()调整堆栈指针,这个调整量是与编译器、编译器选项、μC/OS-Ⅱ配置选项都相关的变量。在这里进行这些处理相对其它处理器结构可能增加的处理器时间很少,但对于ARM来说,由于中断(IRQ)有独立的堆栈,在这里这样做就需要把所有寄存器从中断的堆栈拷贝到任务的堆栈,需要花费比较多的额外时间。而变量OSIntNesting为0时,并不一定会进行任务切换,所以本移植没有与之对应的程序,而在函数OSIntCtxsw()中做这一项工作。这样,仅在需要时才处理这些事物,程序效率得以提高。

在中断调用后,如果需要任务切换,则变量OSTCBHighRdy和变量OSTCBCur的值不同;如果不需要任务切换这两个变量则相同。本移植通过判断这两个变量来决定是进行任务切换,还是不进行任务切换。通过比较,如果需要任务切换则执行“LDR PC,=OSIntCtxSw”跳转到OSIntCtxSw处进行任务切换;如果不需要任务切换则执行“LDMEQFD SP!,{R0-R3,R12,PC}^”中断返回。

这里需要对“MSR CPSR_c,#0x92”说明下,这条指令的作用是关IRQ中断。因为中断(IRQ)模式的LR寄存器在处理器响应中断时用于保存中断返回地址,所以在处理器响应中断时中断(IRQ)模式的LR寄存器不能保存有效数据。而BL指令要用LR寄存器保存BL下一条指令的位置,所以在中断(IRQ)模式时,在BL指令之前必须关中断,在保存LR后才能开中断。

§4.2.2Target.c文件的编写

为了使系统基本能够工作,必须在进人main()函数前对系统进行一些基本的初始化工作,这些工作由函数TargetResetInit()完成。

void TargetResetInit(void)

{

uint32i;

uint32*cp2;

extern void Vectors(void);

/*拷贝向量表,保证在flash和ram中程序均可正确运行*/

cp1=(uint32*)Vectors;

cp2=(uint32*)0x40000000;

for(i=0;i<2*8;i++)

{

*cp2++=*cp1++;

}

MEMMAP=0x2;

PINSEL0=(PINSEL0&0xFFFF0000)|UART0_PCB_PINSEL_CFG|0x50; PLLCON=1;/*设置系统各部分时钟*/

VPBDIV=0;

PLLCFG=0x23;

PLLFEED=0xaa;

PLLFEED=0x55;

while((PLLSTAT&(1<<10))==0);

PLLCON=3;

PLLFEED=0xaa;

PLLFEED=0x55;

MAMCR=2;/*设置存储器加速模块*/

#if Fcclk<20000000

MAMTIM=1;

#else

#if Fcclk<40000000

MAMTIM=2;

#else

#endif

#endif

首先向量表拷贝到RAM底部,加上这部分是为了代码无论从Flash基地址开始编译还是从RAM基地址开始编译程序均运行正确。而把RAM底部映射到向量表“MEMMAP=0x2”也是为了同一个目的。至于复制16个字而不是8个字,是因为后8个字存储跳转的地址是通过PC指针间接寻址的,它们与对应指令(在向量表中)相对位置是不能变化的。

因为在进入多任务环境前使用了一些外设,部分外设使用了芯片的引脚,而LPC2106的所有引脚都是多功能的,所以需要设置引脚功能。同时串口也进行了设置。时钟是芯片各部分正常工作的基础,虽然时钟可以在任何时候设置,但为了避免混乱,最好在进入main()函数前设置。程序首先使能PLL但不连接PLL,然后设置外设时钟(VPB时钟pclk)与系统时钟(cclk)的分频比。接着设置PLL的乘因子和除因子。设置完成后,使用“PLLFEED=0xaa;PLLFEED=0x55;”的访问序列把数据正确写人硬件,并等待PLL跟踪完成。最后,使能PLL,并使PLL联上系统。本应用外接的晶振频率(Fosc)为11.0592MHz,倍增器的值M=4,所以处理器时钟(Fcclk)为44.2368MHz。为了使电流控制振荡器频率(Fcco)满足156-320MHz,所以分频器的值P=2,使得Fcco=Fcclk×2×P=176.9472MHz。取VPB分频器的分频值为1/4,所以外设时钟(Fpclk)=Fcclk/4=11.0592MHz,则记数周期为0.09042μs,定时0.2ms,则记数值为2212个,这些时钟的定义都在config.h文件中。

用户程序最终是要在Flash中运行的,而系统复位时Flash是以最低速度运行,这对发挥芯片的性能极其不利。虽然存储器加速模块可以在任何时候设置,但为了避免混乱,最好在进入main()函数前设置。首先使存储器加速模块全速工作,然后根据系统主时钟利用条件编译将Flash的访问时钟设置到合适的值。

§4.2.3Init.s文件的编写

由于LPC2106微控制器的存储系统比较简单,所以系统初始化代码也比较简单,代码如下:

Reset

BL InitStack;初始化堆栈

BL TargetResetInit;目标板基本初始化

B__main;跳转到c语言入口

在芯片复位在芯片复位时程序会跳转到标号Reset处,程序首先调用Initstack初始化各种模式的堆栈,然后调用TargetResetlnit对系统进行基本初始化,最后跳转到ADS提供的启动代码__main。_main 是ADS提供的启动代码起始位置,它初始化库并最终引导CPU进入main函数。

STM32启动文件详解

STM32启动文件详解 (2012-07-28 11:22:34) 转载▼ 分类:STM32 标签: stm32 启动 在<>,用的是STM32F103RBT6,所有的例程都采用了一个叫STM32F10x.s的启动文件,里面定义了STM32的堆栈大小以及各种中断的名字及入口函数名称,还有启动相关的汇编代码。STM32F10x.s是MDK提供的启动代码,从其里面的内容看来,它只定义了3个串口,4个定时器。实际上STM32的系列产品有5个串口的型号,也只有有2个串口的型号,定时器也是,做多的有8个定时器。比如,如果你用的 STM32F103ZET6,而启动文件用的是STM32F10x.s的话,你可以正常使用串口1~3的中断,而串口4和5的中断,则无**常使用。又比如,你TIM1~4的中断可以正常使用,而5~8的,则无法使用。 而在固件库里出现3个文件 startup_stm32f10x_ld.s startup_stm32f10x_md.s startup_stm32f10x_hd.s 其中,ld.s适用于小容量产品;md.s适用于中等容量产品;hd适用于大容量产品; 这里的容量是指FLASH的大小.判断方法如下: 小容量:FLASH≤32K 中容量:64K≤FLASH≤128K 大容量:256K≤FLASH ;******************** (C) COPYRIGHT 2011 STMicroelectronics ******************** ;* File Name : startup_stm32f10x_hd.s ;* Author : MCD Application Team ;* Version : V3.5.0 ;* Date : 11-March-2011 ;* Description : STM32F10x High Density Devices vector table for MDK-ARM ;* toolchain. ;* This module performs: ;* - Set the initial SP ;* - Set the initial PC == Reset_Handler ;* - Set the vector table entries with the exceptions ISR address ;* - Configure the clock system and also configure the external ;* SRAM mounted on STM3210E-EVAL board to be used as data ;* memory (optional, to be enabled by user) ;* - Branches to __main in the C library (which eventually ;* calls main()). ;* After Reset the CortexM3 processor is in Thread mode,

如何编写ARM7的启动代码

如何编写ARM7的启动代码(LPC2119为例) 随着生活水平的提高和IT技术的进步,8位处理器的处理能力已经不能满足嵌入式系统的需要了;而16位处理器在性能和成本上都没有很大的突破。并且在8位机的开发中,大多使用汇编语言来编写用户程序。这使得程序的可维护性、易移植性等都受到了极大的挑战。正是基于此,ARM 公司适时的推出了一系列的32位嵌入式微控制器。目前广泛使用的是ARM7和ARM9系列,ARM7TDMI内核的ARM7处理器广泛应用于工业控制、仪器仪表、汽车电子、通讯、消费电子等嵌入式设备。本文主要以philips 公司ARM7TDMI核的LPC2119为例来分析如何编写ARM7的启动代码。 1、启动代码 在嵌入式系统软件的开发中,应用程序通常是在嵌入式操作系统的开发平台上采用C语言编写的。然而,在ARM系统上电复位后,需要设置中断向量表、初始化各模式堆栈、设置系统时钟频率等,而这些过程都是针对

ARM内部寄存器结构的操作,用C语言编程是很难实现的。因此在转到应用程序的c/c++编写之前,需要用ARM的汇编语言编写启动代码,由启动代码完成系统初始化以及跳转到用户C程序。在ARM设计开发中,启动代码的编写是一个极重要的过程。然而启动代码随具体的目标系统和开发系统有所区别,但通常包含以下部分: ·向量表定义 ·地址重映射及中断向量表的转移 ·堆栈初始化 ·设置系统时钟频率 ·中断寄存器的初始化 ·进入C应用程序 下面就结合PHILIPS的LPC2119的启动代码来分析与说明ARM7处理器的启动代码的编写。 1.1向量表定义 ARM芯片上电或复位后,系统进入管理模式、ARM状态、PC(R15)指向0x00000000地址处。中断向量表为每一个中断设置1个字的存储空间,存放一条跳转指令,通过这条指令使PC指针指向相应的中断服务程序入口,继而执行相应的中断处理程序。LPC2219的中断向量表和其它基于ARM核的芯片中断向量表较类似,只要注意LPC2219要使向量表所有数据32位累加和为零(0x00000000-0x0000001C的8个字的机器码累加), 才能使用户的程序脱机运行。 1.2 地址重映射及中断向量表的转移 ARM7处理器在复位后从地址0读取第一条指令并执行,因此系统上电后地址0必须是非易失的ROM/FLASH,这样才能保证处理器有正确可用的指令。为了加快对中断的处理以及实现在不同操作系统模式下对中断的处

UBOOT命令详解

常用U-boot命令详解(z) 2010-09-30 15:05:52| 分类:学习心得体会|字号订阅 U-boot发展到现在,他的命令行模式已经非常接近Linux下的shell了,在我编译的 U-boot-2009.11中的命令行模式模式下支持“Tab”键的命令补全和命令的历史记录功能。而且如果你输入的命令的前几个字符和别的命令不重复,那么你就只需要打这几个字符即可,比如我想看这个U-boot的版本号,命令就是“ version”,但是在所有的命令中没有其他任何一个的命令是由“v”开头的,所以只需要输入“v”即可。 [u-boot@MINI2440]# version U-Boot 2009.11 ( 4月04 2010 - 12:09:25) [u-boot@MINI2440]# v U-Boot 2009.11 ( 4月04 2010 - 12:09:25) [u-boot@MINI2440]# base Base Address: 0x00000000 [u-boot@MINI2440]# ba Base Address: 0x00000000 由于U-boot支持的命令实在太多,一个一个细讲不现实,也没有必要。所以下面我挑一些烧写和引导常用命令介绍一下,其他的命令大家就举一反三,或者“help”吧! (1)获取帮助 命令:help 或? 功能:查看当前U-boot版本中支持的所有命令。 [u-boot@MINI2440]#help ?- alias for'help' askenv - get environment variables from stdin base - print or set address offset bdinfo - print Board Info structure bmp - manipulate BMP image data boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol

电脑启动过程详解!!!

电脑启动过程详解 1.当按下电源开关时,电源就开始向主板和其它设备供电,这时电压还不太稳定,主板上的控制芯片组会向CPU发生并保持一个RESET(重置)信号,让CPU内部自动恢复到初始状态,但CPU在些刻不会马上执行指令,当芯片组检查到电源已经开始稳定供电了(当然从不稳定,到稳定的过程只是一瞬间的事情)它便撤去RESET信号(如果是手工按下电脑面板上的RESET按钮来重启机器,那么松开该按钮时芯片组就会撤去RESET信号)CPU马上从地址FFFF0H处开始执行指令,这个地址实际在系统BIOS的地址范围内, 无论是Award BIOS,还是AMI BIOS,在这里的只是一条跳转指令,跳到系统BIOS中真正的启动代码处。 2.系统BIOS的启动代码首先要做的事情就进行POST(Power-On Self Test,加电后自检),POST的主要任务是检查系统中一些关键设备是否存在和是否正常工作,例如内存和显卡等设备.由于POST是最早进行的检查过程,此时显卡还没有初始化,如果系统BIOS在进行POST的过程中发现了些致命错误,例如没有找到内存或内存有问题 (此时只会检查640KB常规内存),那么系统BIOS就会直接控制嗽叭发生声音来报告错误,声音的长短和次数代表了错误的类型.在正常情况下,POST过程进行的非常快,我们几乎无法感觉到它的存在,POST结束之后就会调用其它代码来进行更完整的硬件检测。 3.接下来系统BIOS将查找显卡的BIOS,前面说过,存放显卡BIOS的ROM芯片的超始地址通常设在 C0000H,系统BIOS在这个地方找到显卡BIOS之后就调用它的初始化代码来初始化显卡,此时多数显卡都在屏幕上显示出一些初始化信息,介绍生产厂商,图形芯片类型等内容,不过这个画面几乎是一闪而过,系统BIOS接着会查找其它设备的BIOS程序,找到之后同样会调用这些BIOS内部的初始化代码来初始化相关的设备。 4.查找完所有其它设备的BIOS之后,系统BIOS将显示出它自己的启动画面,其中包括有系统BISO的类型,序列号和版本号等内容. 5.接着系统BIOS将检查和显示CPU的类型和工作频率,然后开始测试所有RAM,并同时在屏莫显示内存测试的速度,用户可以在CMOS设置中自行决定使用简单耗时少或详细耗时多的测试方式. 6.内存测试通过之后,系统BIOS将开始检测系统中安装的一些标准硬件设备,包括硬盘,CD-ROM,串口,并口,软驱等设备,另外绝大数较新版本的系统BIOS在这一过程中还要自动检测和设置内存的定时参数,硬盘参数和访问模式等. 7.标准设备检查完毕后,系统BIOS内部的支持即插即用的代码将开始检测和配置系统中安装的的即插即用设备,每找到一个设备之后,系统BIOS都会在屏幕上显示出设备的名称和型号等信息,同时为该设备分配中断,DMA通道和I/O端口等资源。 8.到这一步为止,所有硬件都已经检测配置完毕了,多数系统BIOS会重新清屏并在屏幕上方显示出一个表格,其它概略地列出了系统中安装的各种标准硬件设备,以及它们使用的资源和一些相关工作参数。 9.接下来系统BIOS会更新ESCD(Extended system configuration data,扩展系统配置数据.)ESCD是系统BIOS用来与操作系统交换硬件配置信息的一种手段,这些数据被存放在CMOS之中,通常ESCD数据只在系统配置发生改变后才会更新,所以不是每次启动电脑时都能够看到"updata ESCD … Success"这样的信息, 不过某些主板的系统BIOS在保存ESCD数据时使用了与widnwos 9x不相同的数据格式,于是widnwos 9x在启动过程中会把ESCD数据修改成自己的格式,但在下一次启动时,既使硬件配置没有发生改变,系统BIOS也会把ESCD的数据格式修改回来,如此循环,将会导致在每次启动电脑时,系统BIOS都要更新一遍ESCD,这就是为什么有些机器在每次启动时都会显示出相关信息的原因。 10.ESCD更新完毕后,系统BIOS的启动代码将进行它的最后一项工作,即根据用户指定的启动顺序从软件,硬件或光驱启动,以从C盘启动为例,系统BIOS将读取并执行硬盘上的主引导记录,主引导记录接着从分区表中找到第一个活动分区,然后读取并执行这个活动分区的引导记录,而分区引导记录将负责读取并执行 IO.SYS这是DOS和widnows 9x的IO.SYS(或NT的NTLDR)首先要初始化一些重要的系统数据,然后将显示出我们熟悉的蓝天白云,在这幅画面之下,widnwos 将继续进行DOS部分和GUI(图形用户界面)部分的引导和初始化工作. 上面介绍的便是电脑在打开电源开关(或按RESET)进行冷启动时所要完成的各种初始化工作,如果在DOS 下按Ctrl Alt DEL组合键,(或从windows中选择重新启动电脑)来进行热启动,那么POST过程将被跳过去,

启动代码startups分析

启动代码start.s(相当于bootloader的前端代码),开机就执行的代码,即0x0000处放置的代码。给CPU一个合适的工作环境。面向CPU内核和外围硬件,所以一般用汇编编写。 1、在起始地址分配中断向量表即中断处理函数(CPU要求的),以为向量空间只有4字节,所以一般只是一个跳转指令,去别处执行。 2、之后初始化存储器系统 3、初始多个模式下的堆栈(模式切换时,硬件给SP置位) 4、初始化有特殊要求的外围设备,如LED灯、看门狗 5、初始化用户的执行环境(在FLASH中运行太慢了,把代码整体搬迁到RAM中) 6、切换处理器的工作模式 7、调用主程序 (没见到有存储控制器的配置代码,也没见到有时钟初始化代码) 下面分析,所给的2410的启动代码实现了以上的那些功能,实现得显然不全,或者不需要,或者在工程代码的其它部分实现。 读程序时注意,所有程序都是逐行顺序执行的,要看清跳转指令。 GET 2410addr.s //用到了2410addr.s中的寄存器地址宏定义 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Some ARM920 CPSR bit discriptions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Pre-defined constants//预定义的变量,一下后续代码中使用方便,与CPSR相关USERMODE EQU 0x10 FIQMODE EQU 0x11 IRQMODE EQU 0x12 SVCMODE EQU 0x13 ABORTMODE EQU 0x17 UNDEFMODE EQU 0x1b MODEMASK EQU 0x1f NOINT EQU 0xc0 I_Bit * 0x80 F_Bit * 0x40 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; MMU Register discription ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;p15 CP 15 ;c0 CN 0 ;c1 CN 1 ;c2 CN 2 ;c3 CN 3

UBoot移植详解

u-boot 移植步骤详解 1 U-Boot简介 U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。但是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 Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。 选择U-Boot的理由: ①开放源码; ②支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS; ③支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale; ④较高的可靠性和稳定性; ④较高的可靠性和稳定性; ⑤高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等; ⑥丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等; ⑦较为丰富的开发调试文档与强大的网络技术支持; 2 U-Boot主要目录结构 - board 目标板相关文件,主要包含SDRAM、FLASH驱动; - common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;

keil下C51启动代码详解

由于CPU和程序启动代码文件STARTUP.a51的重要性,一些8051派生的CPU产品要求初始化CPU来满足设计中的相应的硬件,因此,有时候用户需要对STARTUP.a51进行修改,所以进行注释一下: ;--------------------------------------------------- ;startup.A51: 用户上电初始化程序 ;---------------------------------------------------- ; ;使用以下EQU命令可定义在CPU复位时需要用0进行初始化的内存空间 ; ;IDA TA存储器的空间的绝对起始地址总是零 IDA TALEN EQU 80H ;需用0进行初始化的IDA TA存储器空间的字节数 ; XDA TASTART EQU 0H ;XDA TA存储器空间的绝对起始地址 XDA TALEN EQU 0H ;需用0进行初始化的XDA TA存储器的空间字节数 ; PDA TASTART EQU 0H ;PDA TA存储器的空间的绝对起始地址 PDA TALEN EQU 0H ;需用0进行初始化的PDA TA存储器的空间字节数 ;注意:IDA TA存储器的空间在物理上包括了8051单片机的DA TA和BIT存储空间 ;至少要保证与C51编译器运行库有关的存储器的空间进行0初始化 ; ;再入函数模拟初始化 ;----------------------------------------------------------- ;以下用EQU指令定义了再入函数模拟堆栈指针的初始化 ; ;使用SMALL存储器模式时再入函数的堆栈空间 IBPSACK EQU 0 ;使用SMALL存储器模式再入函数时将其设置成1 IBPSTACKTOP EQU 0FFH+1 ;将堆栈顶设置为最高地址加1 ; ;使用LARGE存储器模式时再入函数的堆栈空间 XBPSTACK EQU 0 ;使用LARGE存储器模式再入函数时将其设置成1 XBPSTACKTOP WQU 0FFFFH+1 ;将堆栈顶设置为最高地址加1 ; ;使用COMPACT存储器模式时再入函数的堆栈空间 PBPSTACK EQU 0 ; 使用COMPACT存储器模式再入函数时将其设置成1 PBPSTACKTOP WQU 0FFFFH+1 ;将堆栈顶设置为最高地址加1 ;;---------------------------------------------------- ;使用COMPACT存储器模式时,64KB X DA TA存储器空间的分页定义 ; ;以下用EQU指令定义PDA TA类型变量在XDA TA存储器空间的页地址 ;使用EQU指令定义PFAGE时必须与L51连接定位器PDA TA指令的控制参数一致 ; PPAGEENABLE EQU 0 ;使用PDA TA类型变量时将其设置成1 PPAGE EQU 0 ;定义页号 ; ;------------------------------------------------ NAME ? C_STARTUP ;模块名为? C_STARTUP ? C_51STARTUP SEGMENT CODE ;代码段 ? STACK SEGMENT IDA TA;堆栈段 RSEG ? STACK ;堆栈 DS 1 EXTRN COE(? C_START) ;程序开始地址

STM32F10x 启动代码文件选择

startup_stm32f10x_xx.s 启动代码文件选择startup_stm32f10x_cl.s 互联型的器件,STM32F105xx,STM32F107xx startup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_hd_vl.s 大容量的STM32F100xx startup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_ld_vl.s 小容量的STM32F100xx startup_stm32f10x_md.s 中容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_md_vl.s 中容量的STM32F100xx startup_stm32f10x_xl.s FLASH在512K到1024K字节的STM32F101xx,STM32F102xx,STM32F103xx 固件库中的Release_Notes_for_STM32F10x_CMSIS.html写到: STM32F10x CMSIS Startup files: startup_stm32f10x_xx.s Add new startup files for STM32 Low-density Value line devices: startup_stm32f10x_ld_vl.s Add new startup files for STM32 Medium-density Value line devices: startup_stm32f10x_md_vl.s SystemInit() function is called from startup file (startup_stm32f10x_xx.s) before to branch to applic ation main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file GNU startup file for Low density devices (startup_stm32f10x_ld.s) is updated to fix compilation err ors. 例如我用STM32F103RB,那么选启动文件为startup_stm32f10x_md.s

ARM启动代码研究

ARM启动代码研究 PRESERVE8: 1.1.PRESERVE8: Reguire8和Preserve8 C和汇编有8位对齐的要求,这两个伪指令可以满足此要求,存在REQUIRE8<——> PRESERVE8的对应关系,但不是说有一个REQUIRE8就要有一个PRESERVE8,如果是一个c文件和一个汇编文件的调用,也就涉及一个PRESERVE8或者是一个REQUIRE8. 另外,REQUIRE8和PRESERVE8并不完成8byte对齐的操作,对齐由ALIGN完成。 将ADS的代码移植到KEIL MDK上需要做的修改: 当用户拥有ADS遗留工程的所有源代码时,使用MDK重新编译链接全部代码是最好的解决方法,MDK中的新版本编译工具会重新生成满足堆栈8BYTE对齐要求的目标文件,避免由于堆栈不对齐引起的链接错误. 从ADS到KEIL很重要的一个修改的地方就是这里的8BYTE对齐,想要编译通过,在startup.s 里面我们必须加入PRESERVE8指令,使得寄存器8BYTE对齐. 代码: CODE32 PRESERVE8;这个在KEIL里面是必须的,要求8BYTE对齐.在ADS的启动代码中就没有. AREA vectors,CODE,READONLY 2:ARM的处理器可工作于多种模式,下面设置个模式的一些参数. Mode_USR EQU0x10用户模式 Mode_FIQ EQU0x11快中断模式 Mode_IRQ EQU0x12中断模式 Mode_SVC EQU0x13管理模式

Mode_ABT EQU0x17中止模式 Mode_UND EQU0x1B未定义模式 Mode_SYS EQU0x1F系统模式 参数的由来:这里各个模式的参数是由寄存器CPSR的模式位设置M[4:0]得来的,比如这里的用户模式,CPSR的M[4:0]设置为10000就是0x10,同理其他.详见<>P47页,CPSR设置很关键! 3: I_Bit EQU0x80;when I bit is set,IRQ is disabled F_Bit EQU0x40;when F bit is set,FIQ is disabled 也和CPSR寄存器的设置有关,这里两位是禁止/开启快速中断和一般中断的设置. 4:各模式下定义的堆栈地址. UND_Stack_Size EQU0x00000000 SVC_Stack_Size EQU0x00000100 ABT_Stack_Size EQU0x00000000 FIQ_Stack_Size EQU0x00000000 IRQ_Stack_Size EQU0x00000100 USR_Stack_Size EQU0x00000200 设置堆栈大小 Stack_Size EQU(UND_Stack_Size+SVC_Stack_Size+ABT_Stack_Size+ FIQ_Stack_Size+IRQ_Stack_Size+USR_Stack_Size) AREA STACK,NOINIT,READWRITE,ALIGN=3 Stack_Mem SPACE Stack_Size

u-boot启动分析

背景: Board →ar7240(ap93) Cpu →mips 1、首先弄清楚什么是u-boot Uboot是德国DENX小组的开发,它用于多种嵌入式CPU的bootloader程序, uboot不仅支持嵌入式linux系统的引导,当前,它还支持其他的很多嵌入式操作系统。 除了PowerPC系列,还支持MIPS,x86,ARM,NIOS,XScale。 2、下载完uboot后解压,在根目录下,有如下重要的信息(目录或者文件): 以下为为每个目录的说明: Board:和一些已有开发板有关的文件。每一个开发板都以一个子目录出现在当前目录中,子目录存放和开发板相关的配置文件。它的每个子文件夹里都有如下文件(以ar7240/ap93为例): Makefile Config.mk Ap93.c 和板子相关的代码 Flash.c Flash操作代码 u-boot.lds 对应的链接文件 common:实现uboot命令行下支持的命令,每一条命令都对应一个文件。例如bootm命令对应就是cmd_bootm.c cpu:与特定CPU架构相关目录,每一款Uboot下支持的CPU在该目录下对应一个子目录,比如有子目录mips等。它的每个子文件夹里都有入下文件: Makefile Config.mk Cpu.c 和处理器相关的代码s Interrupts.c 中断处理代码 Serial.c 串口初始化代码 Start.s 全局开始启动代码 Disk:对磁盘的支持

Doc:文档目录。Uboot有非常完善的文档。 Drivers:Uboot支持的设备驱动程序都放在该目录,比如网卡,支持CFI的Flash,串口和USB等。 Fs:支持的文件系统,Uboot现在支持cramfs、fat、fdos、jffs2和registerfs。 Include:Uboot使用的头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。该目下configs目录有与开发板相关的配置文件,如 ar7240_soc.h。该目录下的asm目录有与CPU体系结构相关的头文件,比如说mips 对应的有asm-mips。 Lib_xxx:与体系结构相关的库文件。如与ARM相关的库放在lib_arm中。 Net:与网络协议栈相关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。 Tools:生成Uboot的工具,如:mkimage等等。 3、mips架构u-boot启动流程 u-boot的启动过程大致做如下工作: 1、cpu初始化 2、时钟、串口、内存(ddr ram)初始化 3、内存划分、分配栈、数据、配置参数、以及u-boot代码在内存中的位置。 4、对u-boot代码作relocate 5、初始化malloc、flash、pci以及外设(比如,网口) 6、进入命令行或者直接启动Linux kernel 刚一开始由于参考网上代码,我一个劲的对基于smdk2410的板子,arm926ejs的cpu看了N 久,启动过程和这个大致相同。 整个启动中要涉及到四个文件: Start.S →cpu/mips/start.S Cache.S →cpu/mips/cache.S Lowlevel_init.S →board/ar7240/common/lowlevel_init.S Board.c →lib_mips/board.c 整个启动过程分为两个阶段来看: Stage1:系统上电后通过汇编执行代码 Stage2:通过一些列设置搭建了C环境,通过汇编指令跳转到C语言执行. Stage1: 程序从Start.S的_start开始执行.(至于为什么,参考u-boot.lds分析.doc) 先查看start.S文件吧!~ 从_start标记开始会看到一长串莫名奇妙的代码:

keil c51中启动代码详细说明

[ 2006-10-27 18:23:00 | By: CHYB_HSH ] 让我们先来看看STARTUP.A51文件(默认设置)吧!根据源文件中的说明文字,我们很容易分析出STARTUP.A51文件的工作方式和作用!让我们把它先汉化一下看看! $NOMOD51;Ax51宏汇编器控制命令:禁止预定义的8051 ;------------------------------------------------------------------------------ ; This file is part of the C51 Compiler package ; Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc. ;------------------------------------------------------------------------------ ; STARTUP.A51: This code is executed after processor reset. ; STARTUP.A51: STARTUP.A51文件所生成的代码将在单片机复位后被执行! ; To translate this file use A51 with the following invocation: ; 将按照下面的命令行语句调用A51编译器进行编译产生目标文件 ; A51 STARTUP.A51 ; ; To link the modified STARTUP.OBJ file to your application use the following ; BL51 invocation: ; 将按照下面的命令行语句调用BL51连接器把STARTUP.OBJ定位连接到您的程序代码中; BL51 , STARTUP.OBJ ;; ;------------------------------------------------------------------------------ ; ; User-defined Power-On Initialization of Memory ; 自定义上电后需要初始化的储存区域 ; With the following EQU statements the initialization of memory ; at processor reset can be defined: ; 使用下列EQU伪指令定义初始化的存储区域在单片机复位后定义生效 ; ; the absolute start-address of IDATA memory is always 0 IDATALEN EQU 80H ; the length of IDATA memory in bytes. ; IDATA(间接寻址区)其起始地址固定为0;IDA TALEN用于指定需要初始化 ; 的 IDATA区长度(以字节为单位)* XDATASTART EQU 0H ; the absolute start-address of XDATA memory XDATALEN EQU 0H ; the length of XDA TA memory in bytes. ;XDATA (外部直接寻址区)XDA TASTART用于指定需要初始化的XDA TA区起始地;址 XDATALEN 用于指定需要初始化的XDA TA区长度(以字节为单位)* PDATASTART EQU 0H ; the absolute start-address of PDA TA memory PDATALEN EQU 0H ; the length of PDATA memory in bytes. ;PDA TA(页寻址区)PDATASTART用于指定需要初始化的PDA TA区起始地址;PDATALEN 用于指定需要初始化的;PDATA区长度(以字节为单位)*

UBoot源码分析1

?UBoot源码解析(一)

主要内容 ?分析UBoot是如何引导Linux内核 ?UBoot源码的一阶段解析

BootLoader概念?Boot Loader 就是在操作系统内核运行之前运行 的一段小程序。通过这段小程序,我们可以初始 化硬件设备、建立内存空间的映射图,从而将系 统的软硬件环境带到一个合适的状态,以便为最 终调用操作系统内核准备好正确的环境 ?通常,Boot Loader 是严重地依赖于硬件而实现 的,特别是在嵌入式世界。因此,在嵌入式世界 里建立一个通用的Boot Loader 几乎是不可能的。 尽管如此,我们仍然可以对Boot Loader 归纳出 一些通用的概念来,以指导用户特定的Boot Loader 设计与实现。

UBoot来源?U-Boot 是 Das U-Boot 的简称,其含义是 Universal Boot Loader,是遵循 GPL 条款的开放源码项目。最早德国 DENX 软件工程中心的 Wolfgang Denk 基于 8xxROM 和 FADSROM 的源码创建了 PPCBoot 工程项目,此后不断 添加处理器的支持。而后,Sysgo Gmbh 把 PPCBoot 移 植到 ARM 平台上,创建了 ARMBoot 工程项目。最终, 以 PPCBoot 工程和 ARMBoot 工程为基础,创建了 U- Boot 工程。 ?而今,U-Boot 作为一个主流、通用的 BootLoader,成功地被移植到包括 PowerPC、ARM、X86 、MIPS、NIOS、XScale 等主流体系结构上的百种开发板,成为功能最多、 灵活性最强,并且开发最积极的开源 BootLoader。目前。 U-Boot 仍然由 DENX 的 Wolfgang Denk 维护

电脑启动过程详解

电脑从按完开关加电开始直到进入到系统桌面的整个过程详解本文以Windows2000/xp和Windows Vista/7两个内核做讲解 电脑从加电到进桌面可以分为两大部分: 无论是Windows2000/XP还是Windows Vista/7,在硬件自检方面都是想同的,不同的是在系统加截。 硬件部分: 在讲解前,我们先来了解几个概念: BIOS:即“Basic Input/Output System”(基本输入输出系统),它是一组被“固化”在计算机主板上的一块 ROM 中直接关联硬件的程序,保存着计算机最重要的基本输入输出的程序、系统设置信息、开机后自检程序和系统自启动程序,其主要功能是为计算机提供最底层的、最直接的硬件设置和控制,它包括系统 BIOS(主板 BIOS).其它设备 BIOS(例如 IDE 控制器 BIOS、显卡 BIOS 等)其中系统 BIOS 占据了主导地位.计算机启动过程中各个 BIOS 的启动都是在它的控制下进行的。 CMOS:即“Complementary Metal-Oxide-Semiconductor”(互补金属氧化物半导体),它本是计算机系统内一种重要的芯片,保存了系统引导最基本的资料。 内存地址:我们知道,内存空间的最基本单位是位,8 位视为一个字节,即我们常用的单位 B,内存中的每一个字节都占有一个地址(地址是为了让 CPU 识别这些空间,是按照 16 进制表示的),而最早的 8086 处理器只能识别 1MB(2 的 20 次方 B)的空间,这 1MB 内存中低端(即最后面)的 640KB 就被称为基本内存,而剩下的内存(所有的)则是扩展内存。这 640KB 的空间分别由显存和各 BIOS 所得。 我们来看一下硬件部分的流程图:

ARM7 启动代码

ARM启动代码解析 ARM启动代码解析 1:PRESERVE8: Reguire8和Preserve8 C和汇编有8位对齐的要求,这两个伪指令可以满足此要求,存在REQUIRE8<——> PRESERVE8的对应关系,但不是说有一个REQUIRE8就要有一个 PRESERVE8,如果是一个c文件和一个汇编文件的调用,也就涉及一个PRESERVE8或者是一个REQUIRE8. 另外,REQUIRE8和PRESERVE8并不完成8 byte 对齐的操作,对齐由ALIGN完成。 将ADS的代码移植到KEIL MDK上需要做的修改: 当用户拥有ADS遗留工程的所有源代码时,使用MDK重新编译链接全部代码是最好的解决方法,MDK中的新版本编译工 具会重新生成满足堆栈8BYTE对齐要求的目标文件,避免由于堆栈不对齐引起的链接错误. 从ADS到KEIL很重要的一个修改的地方就是这里的8BYTE 对齐,想要编译通过,在startup.s里面我们必须加入PRESERVE8指令,使得寄存器8BYTE对齐.

代码: CODE32 PRESERVE8 ;这个在KEIL里面是必须的,要求8BYTE对齐.在ADS的启动代码中就没有. AREA vectors,CODE,READONLY 2: ARM的处理器可工作于多种模式,下面设置个模式的一些参数. Mode_USR EQU 0x10 用户模式 Mode_FIQ EQU 0x11 快中断模式 Mode_IRQ EQU 0x12 中断模式 Mode_SVC EQU 0x13 管理模式 Mode_ABT EQU 0x17 中止模式 Mode_UND EQU 0x1B 未定义模式 Mode_SYS EQU 0x1F 系统模式 参数的由来:这里各个模式的参数是由寄存器CPSR的模式位设置M[4:0]得来的,比如这里的用户模式,CPSR的M[4:0]设置为10000就是0x10,同理其他.详见<>P47页,CPSR设置很关键! 3: I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled

GRUB2启动代码详解

GRUB2的介绍 目前Grub1已经停止开发了,不再增加新的功能,所有的开发都转移到Grub2上了,Grub 2 是新一代的Grub,它实现了一些Grub中所没有的功能:1.模块化设计 不同于Grub的单一内核结构,Grub 2 的功能分布在很多的小模块中,并且能在运行时动态装载和卸除。 2.支持多体系结构Grub 2可支持PC(i386), MAC(powerpc)等不同的体系结构,而且支持最新的EFI架构。 3.国际化的支持Grub 2 可以支持非英语的语言。 4.内存管理Grub 2 有真正的内存管理系统。 5.脚本语言Grub 2 可以支持脚本语言,例如条件,循环,变量,函数等。 当然,Grub 2正处在开发阶段,因此以上的某些功能可能现阶段还不是很完善。 如果你熟悉Grub2,应该可以看明白里面的内容。要注意的是: a、timeout, default等参数用变量来储存 b、菜单项由menuentry定义 c、第1个分区是(hd0,1)而不是(hd0,0) 理论的东西说多了大家估计也晕,举个简单的例子:在grub1中,要改变启动背景的时候只能选择支持640X480分辨率并且格式也只能是.xpm的图片,分辨率稍微大点的图就显示不出来了,但grub2不存在这个问题,它有更绚丽的菜单界面,grub2默认.png .tga .jpeg等很多种格式的图片都支持,而且支持的图片分辨率也更大。

GRUB2启动代码分析 # # DO NOT EDIT THIS FILE # # It is automatically generated by /usr/sbin/grub-mkconfig using templates # from /etc/grub.d and settings from /etc/default/grub # ### BEGIN /etc/grub.d/00_header ### if [ -s $prefix/grubenv ]; then #如果“$prefix/grubenv”目录不为空 load_env #从grubenv文件中加载环境变量 fi set default="0" #启动第1项# if [ ${prev_saved_entry} ]; then #如果prev_saved_entry的值不为空 set saved_entry=${prev_saved_entry} #将saved_entry的值设置成变量prev_saved_entry的值。 save_env saved_entry #将变量saved_entry保存到grubenv文件中。 set prev_saved_entry= #将prev_saved_entry的值设置为空 save_env prev_saved_entry #将prev_saved_entry保存到grubenv文件中 set boot_once=true #将boot_once的值设置为真(貌似是为了标志已经设置过启动的相关环境变量了)fi function savedefault {

相关文档