44biint.s(引导程序)

合集下载

了解电脑操作系统的启动过程和引导程序

了解电脑操作系统的启动过程和引导程序

了解电脑操作系统的启动过程和引导程序电脑操作系统的启动过程和引导程序电脑用户每天都在操作系统的环境下使用电脑,但是很少有人深入了解电脑操作系统的启动过程和引导程序。

本文将详细介绍电脑操作系统的启动过程和引导程序,并从硬件层面到软件层面逐步分析。

一、硬件层面的启动过程电脑的启动是从冷启动到操作系统加载的过程,其主要分为硬件层面和软件层面两个阶段。

首先,我们先来了解硬件层面的启动过程。

1. 加电自检(POST)当用户按下电源按钮,电脑主板上的电源管理芯片会向各硬件设备发送电源信号,进行供电。

此时,主板上的固件(BIOS、UEFI)开始运行,执行一系列的加电自检(POST)程序,以确保硬件设备正常工作。

2. BIOS/UEFIBIOS(基本输入输出系统)或者UEFI(统一扩展固件接口)是位于主板上的固件,用来进行电脑系统的启动和硬件设备的识别与初始化。

BIOS/UEFI会从存储设备中加载操作系统引导程序。

3. 引导设备选择在BIOS/UEFI初始化完成后,电脑会检测可启动设备,比如硬盘、光盘、USB设备等,并按照设定的启动顺序尝试加载引导程序。

4. 引导程序加载电脑会按照设定的启动顺序依次读取存储设备中的引导扇区,找到其中的引导程序。

引导程序通常是存储在硬盘的一个特定扇区,被称为主引导记录(MBR)。

5. 主引导记录(MBR)主引导记录包含一个小型的引导程序,它负责将操作系统的控制权转交给特定的分区上的操作系统引导程序。

MBR也会包含磁盘分区表,记录了硬盘的分区信息。

二、软件层面的启动过程在硬件层面的启动过程完成后,接下来是软件层面的启动过程。

这一阶段主要涉及操作系统的启动过程和引导程序。

1. 操作系统引导程序主引导记录会根据分区表找到活动分区,然后将控制权转交给该分区中的操作系统引导程序。

操作系统引导程序一般位于活动分区的引导扇区,它负责加载操作系统。

2. 操作系统加载操作系统引导程序会读取操作系统的核心文件,将其加载到计算机内存中。

计算机引导程序范文

计算机引导程序范文

计算机引导程序范文引导程序(Boot Program)通常被称为计算机引导程序,是计算机系统中运行的第一个软件。

它的主要功能是在系统加电后加载操作系统,并载入内核,以便用户可以开始使用计算机。

引导程序位于计算机的固态存储设备上,如硬盘、固态硬盘或光盘,通常是操作系统安装在硬盘上的第一个扇区(MBR)。

引导程序的历史可以追溯到机械计算机时代。

早期计算机需要运行独立的引导程序,以便用户能够手动输入程序或加载程序载体。

随着计算机技术的不断发展,引导程序已经变得更加复杂和自动化。

引导程序的功能包括:1.检查硬件:引导程序需要检查计算机的硬件设备和组件是否正常工作。

它会对RAM、I/O接口、外部设备等进行初始化和测试,以确保它们在系统启动时可以正常工作。

2. 导入操作系统:引导程序的主要任务是导入操作系统。

它会读取硬盘上的引导扇区,加载操作系统的引导程序(如GRUB或Windows引导管理器),然后将控制权转交给操作系统。

3.加载内核:引导程序加载操作系统的内核到内存中,并设置必要的参数和环境,以便操作系统可以正确运行。

内核是操作系统的核心组件,它负责管理计算机的硬件和执行用户程序。

4.错误检测和恢复:引导程序需要检测并处理可能发生的错误,如磁盘读取错误或内存故障。

它可以通过报告错误或采取恢复措施来处理这些问题,以确保系统的稳定性和安全性。

5.启动选项:引导程序还可以提供启动选项,如选择不同的操作系统、启动其他设备或进入诊断模式等。

这些选项提供了更大的灵活性和功能扩展,以满足用户的不同需求。

引导程序的实现通常是通过汇编语言编写,在固态存储设备上占据很小的空间。

它使用简单的指令来读写设备、加载程序和设置硬件参数。

尽管引导程序是操作系统的一部分,但它是独立于操作系统的。

不同类型的计算机可能需要不同的引导程序,因此它们的实现会因系统架构而异。

在现代计算机系统中,引导程序通常被称为启动加载器(Boot Loader),如GRUB、LILO或Windows引导管理器。

44BINIT.S引导程序注释

44BINIT.S引导程序注释

44BINIT.S引导程序注释;*******************************************************; * NAME : 44BINIT.S *; * Version : 10.JAn.2003 *; * Description: *; * C start up codes *; * Configure memory, Initialize ISR ,stacks *; * Initialize C-variables *; * Fill zeros into zero-initialized C-variables *; *******************************************************GET option.s ;相当于c语言中的#include "option.s"GET memcfg.s;Interrupt Control;声明一些符号常量,这些符号常量和地址相应寄存器的地址对应INTPND EQU 0x01e00004 ;指示中断请求状态寄存器每一位代变一种中断请求具体表示哪一种中断请参考44b0 spec INTMOD EQU 0x01e00008 ;中断模式寄存器有两种中断模式对应位为1代表fip mode 0代表riq modeINTMSK EQU 0x01e0000c ;确定哪个中断源被屏蔽屏蔽的中断源将不被服务I_ISPR EQU 0x01e00020 ;中断服务挂起寄存器I_CMST EQU 0x01e0001c ;当前主寄存器irq优先级;Watchdog timerWTCON EQU 0x01d30000 ;看门狗定时器控制寄存器;Clock ControllerPLLCON EQU 0x01d80000 ;pll控制寄存器CLKCON EQU 0x01d80004 ;时钟控制寄存器LOCKTIME EQU 0x01d8000c ;锁定时间计数值寄存器;Memory ControllerREFRESH EQU 0x01c80024 ;Dram/sdram刷新控制寄存器;下面是对arm处理器模式寄存器对应值的常数定义,arm处理器中有一个CPSR程序状态寄存器它的后五位决定目前的处理器模式;Pre-defined constantsUSERMODE EQU 0x10 ;0b10000用户模式FIQMODE EQU 0x11 ;0b10001FIQ模式IRQMODE EQU 0x12 ;0b10010IRQ模式SVCMODE EQU 0x13 ;0b10011管理模式ABORTMODE EQU 0x17 ;0b10111中止模式UNDEFMODE EQU 0x1b ;0b11011未定义MODEMASK EQU 0x1f ;0b11111系统模式NOINT EQU 0xc0 ;;check if tasm.exe is used.;arm处理器有两种工作状态 1.arm:32位这种工作状态下执行字对准的arm指令 2.Thumb:16位这种工作状态执行半字对准的Thumb指令;因为处理器分为16位 32位两种工作状态程序的编译器也是分16位和32两种编译方式所以下面的程序用于根据处理器工作状态确定编译器编译方式;code16伪指令指示汇编编译器后面的指令为16位的thumb指令;code32伪指令指示汇编编译器后面的指令为32位的arm指令;这段是为了统一目前的处理器工作状态和软件编译方式(16位编译环境使用tasm.exe编译)GBLL THUMBCODE ;设置一个全局逻辑变量[ {CONFIG} = 16 ;if config==16 这里表示你的目前处于领先地16位编译方式THUMBCODE SETL {TRUE} ;设置THUMBCODE 为 trueCODE32 ;转入32位编译模式| 次 ;elseTHUMBCODE SETL {FALSE} ;设置THUMBCODE 为 false][ THUMBCODE ;if THUMBCODE==TRUECODE32 ;for start-up code for Thumb mode;转入32位编译方式];注意下面这段程序是个宏定义很多人对这段程序不理解我再次强调这是一个宏定义所以大家要注意了下面包含的HandlerXXX HANDLER HandleXXX将都被下面这段程序展开;这段程序用于把中断服务程序的首地址装载到pc中,有人称之为“加载程序”。

引导程序 NTLDR Winload.exe BCD Bootmgr 简介

引导程序 NTLDR  Winload.exe  BCD  Bootmgr 简介

引导程序(英语:boot loader)位于电脑或其他计算机应用上,是指引导操作系统启动的程序。

引导程序启动方式及程序视应用机型种类而不同。

例如在普通的个人电脑上,引导程序通常分为两部分:第一阶段引导程序位于主引导记录(MBR),用以引导位于某个分区上的第二阶段引导程序,如NTLDR、BOOTMGR和GNU GRUB等。

BIOS开机完成后,bootloader就接手初始化硬件设备、创建内存空间的映射,以便为操作系统内核准备好正确的软硬件环境。

简单的bootloader的虚拟汇编码,如其后的八个指令:第一:将P寄存器的值设为8第二:检查纸带(paper tape)读取器,是否已经可以进行读取第三:如果还不能进行读取,跳至1第四:从纸带读取器,读取一byte至累加器第五:如为带子结尾,跳至8第六:将寄存器的值,存储至P寄存器中的数值所指定的地址第七:增加P寄存器的值第八:跳至1但是随着计算机操作系统越来越复杂,位于主引导记录的空间已经放不下引导操作系统的代码,于是就有了第二阶段的引导程序,而MBR中代码的功能也从直接引导操作系统变为了引导第二阶段的引导程序。

NTLDRNTLDR(NT loader的缩写)是微软的Windows NT系列操作系统(包括Windows XP和Windows Server 2003)的引导程序。

NTLDR可以从硬盘以及CD-ROM、U盘等移动存储器运行并引导Windows NT系统的启动。

如果要用NTLDR启动其他操作系统,则需要将该操作系统所使用的启动扇区代码保存为一个文件,NTLDR可以从这个文件加载其它引导程序。

Windows XP的NTLDR高级开机菜单NTLDR主要由两个文件组成,这两个文件必须放在系统分区(大多数情况下都是C 盘):NTLDR,这是引导程序本身boot.ini,这是引导程序的配置文件当boot.ini丢失时,NTLDR会启动第一块硬盘第一个分区上的\Windows目录中的系统。

WindowsXP引导流程

WindowsXP引导流程
1.预引导阶段
在预引导阶段里计算机所做的工作有:运行POST程序,POST将检测系统的总内存以及其他硬件设备的状况,将磁盘第一个物理扇区加载到内存,加载硬盘主引导记录并运行,主引导记录会查找活动分区的起始位置。接着活动分区的引导扇区被加载并执行,最后从引导扇区加载并初始化NTLDR文件。
2.引导阶段
multi(0)disk(0)rdisk(0)partition(2)\WINNT="Windows Windows 2000 Professional"
其中,multi(0)表示磁盘控制器,disk(0)rdisk(0)表示磁盘,partition(x)表示分区。NTLDR就是从这里查找Windows XP Professional的系统文件的位置的。(*本文不会更详细地讲解boot.ini的组成结构,因为其与本主题关系不大,如果想了解,可以到一些专门的网站处查询相关信息。)如果在boot.ini中只有一个操作系统选项,或者把timeout值设为0,则系统不出现操作系统选择菜单,直接引导到那个唯一的系统或者默认的系统。在选择启动Windows XP Professional后,操作系统选择阶段结束,硬件检测阶段开始。
接着系统来到了操作系统选择阶段,如果计算机安装了不止一个操作系统(也就是多系统),而且正确设置了boot.ini使系统提供操作系统选择的条件下,计算机显示器会显示一个操作系统选单,这是NTLDR读取boot.ini的结果。(至于操作系统选单,由于暂时条件不够,没办法截图,但是笔者模拟了一个)
小提示:从Windows XP SP2系统开始,执行安装程序时将会检测NTLDR和的版本,如果发现现有版本比安装程序上的版本新的话,那么将采用现有版本而不采用安装程序上的NTLDR和版本。

解析Linux系统启动的引导流程

解析Linux系统启动的引导流程

解析Linux系统启动的引导流程LINUX是自由开源软件,在LINUX里一切都是文件,不管是命令,操作等等都是以文件形式保存,这篇博客来记录LINUX启动时的引导流程是通过哪写文件来完成的.使用的LINUX版本是CentOS5,CentOS和Ubuntu都是自己联系使用时的较理想版本.下面以CentOS5.5版本为例,介绍LINUX的引导流程,具体流程如下:下面详细介绍每一步:1)第一步firmware固件自检,主要是进行CMOS/BIOS对硬件进行POST加电自检,在物理层次上对硬件进行检测是否正常。

例如检查硬盘是否插好等。

2)第二步读取硬盘中MBR的BootLoader,自启动程序,Linux下常用的自启动程序是GRUB。

这一步主要的功能是载入内核。

内核存放在/boot目录下3)第三步就是载入的内核Kernel的过程,主要功能是:1、驱动硬件,Kernel中含有大量驱动程序。

2、启动init进程。

4)init进程,主要是读取/etc/inittab文件,执行缺省运行级别,从而继续引导。

需要注意的是init京城的PID恒为1,是所有进程的父进程,而init进程的负景程是0,为内核调度器Kernel scheduler。

5)/etc/inittab 定义了初始化的操作。

命令主要格式是:id: runlevels : action : process其中,如上图红框中所示1、run-levels运行级别有7个,0—6分别如下:0 —— halt 关机1 —— Single user mode 单用户模式2 —— Multiuser,withoutNFS 多用户模式但不带网络(text模式)3 —— Full multiuser mode 完整功能的多用户模式(text模式)4 —— unused 预留5 —— X11 图形化多用户模式6 —— reboot 重启可以根据这7个运行级别来进行切换命令为:查看当前运行级别 #runlevel、切换运行级别 #init[0 |1 |2 |3 |4 |5 |6]2、而acion中也有几个比较重要的取值:1 initdefault:指定系统缺省启动的运行级别,如上图中标出,通常用于修复,比如我们要进入单用户模式,则可以将其设置为1,不可将默认设置为0或6,否则无法启动.2sysinit:系统启动执行process中指定的命令由inittab文件内容可以看出,没有设置运行级别,即为无论是哪个运行级别,都会执行/etc/rc.d/rc.sysinit6)initdefault,如第五步所说到的,主要是读取/etc/inittab中的信息,判断缺省的运行级别是什么。

嵌入式系统中引导程序的实现

嵌入式系统中引导程序的实现

在嵌入式系统的开发过程中,技术难点主要在于系统引导程序的编写,为此本文将详细论述在ARM7基础上开发嵌入式系统时引导程序的实现。

引导加载程序是系统加电后运行的第一段软件代码。

当一个微处理器最初启动时,他首先执行预定地址处的指令。

通常这个位置是只读内存,其中存放着系统初始化或引导程序。

在PC系统中,引导加载程序由BIOS(其本质就是一段固件程序)和位于硬盘MBR中的操作系统BootLoader(比如,LILO和GRUB等)一起组成。

BIOS进行CPU初始化、配置其他硬件,并完成硬件检测和资源分配。

然后,BIOS判断出哪一个磁盘包含有操作系统,再把硬盘MBR中的Boot Loader读到系统的RAM中,然后将控制权交给操作系统BootLoader。

BootLoader的主要运行任务就是将内核映象从硬盘上读到RAM中,然后跳转到内核的入口点去运行,也即开始启动操作系统,并把控制权交给操作系统,再由操作系统引导其他应用程序。

在嵌入式系统中,通常并没有像BIOS那样的固件程序(注:有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。

比如在一个基于ARM7TDMIcore的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader 程序。

2 引导程序流程嵌入式系统的资源有限,程序通常都是固化在ROM中运行。

ROM中程序执行前,需要对系统硬件和软件运行环境进行初始化,这些工作由用汇编语言编写的引导程序完成。

引导程序是嵌入式程序的开头部分,应与应用程序一起固化在ROM中,并首先在系统上运行。

他应包含各模块中可能出现的所有段类,并合理安排他们的次序。

写好引导程序是设计好嵌入式程序的关键,系统引导程序所执行的操作依赖于正在开发其软件的系统,一般流程包括:初始化端口,屏蔽中断,把程序拷贝到SRAM中;完成代码的重映射;配置中断句柄,连接到C语言人口,进入应用程序主循环。

脱离操作系统的bootloader—44binit.s的注释

脱离操作系统的bootloader—44binit.s的注释

;if I_ISPC isn't used properly, I_ISPR can be 0 in this routine.
ldr r9,=I_ISPR
。。。。。。。。。。。。。。。。。。。。。
;One of the following two routines can be used for non-vectored interrupt.
;下面这段程序是用来处理非向量中断,具体判断I_ISPR中各位是否置1 置1表示目前此中断等待响应(每次只能有一位置1),从最高优先级中断位开始判断,检测到等待服务
WTCON EQU 0x01d30000
;Clock Controller //时钟控制器
PLLCON EQU 0x01d80000
CLKCON EQU 0x01d80004
LOCKTIME EQU 0x01d8000c
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)堆栈的增长方向为递减
stmfd sp!,{r0} ;PUSH the work register to stack(lr does't push because it return to original address);将要使用的r0寄存器入栈
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;arm处理器有两种工作状态 1.arm:32位 这种工作状态下执行字对准的arm指令 2.Thumb:16位 这种工作状态执行半字对准的Thumb指令

系统引导过程简介

系统引导过程简介

系统引导过程简介一、系统引导过程简介系统引导过程主要由以下几个步骤组成(以硬盘启动为例)1、开机;2、BIOS加电自检(POST---Power On Self Test),内存地址为0fff:0000;3、将硬盘第一个扇区(0头0道1扇区,也就是Boot Sector)读入内存地址0000:7c00处;4、检查(WORD)0000:7dfe是否等于0xaa55.若不等于则转去尝试其他介质;如果没有其他启动介质,则显示”No ROM BASIC”,然后死机;5、跳转到0000:7c00处执行MBR中的程序;6、MBR先将自己复制到0000:0600处,然后继续执行;7、在主分区表中搜索标志为活动的分区.如果发现没有活动分区或者不止一个活动分区,则停止;8、将活动分区的第一个扇区读入内存地址0000:7c00处;9、检查(WORD)0000:7dfe是否等于0xaa55,若不等于则显示“Missing Operating System”,然后停止,或尝试软盘启动;10、跳转到0000:7c00处继续执行特定系统的启动程序;11、启动系统.以上步骤中(2),(3),(4),(5)步由BIOS的引导程序完成;(6),(7),(8),(9),(10)步由MBR中的引导程序完成.一般多系统引导程序(如Smart Boot Manager, BootStar, PQBoot等)都是将标准主引导记录替换成自己的引导程序,在运行系统启动程序之前让用户选择想要启动的分区.而某些系统自带的多系统引导程序(如LILO,NT Loader等)则可以将自己的引导程序放在系统所处分区的第一个扇区中,在Linux中即为两个扇区的SuperBlock.注:以上步骤中使用的是标准的MBR,多系统引导程序的引导过程与此不同.二、硬盘结构及参数3D参数(Disk Geometry):CHS(Cylinder/Head/Sector)C-Cylinder柱面数表示硬盘每面盘片上有几条磁道,最大为1024(用10个二进制位存储);H-Head磁头数表示硬盘总共有几个磁头,也就是几面盘片,最大为256(用8个二进制位存储);S-Sector扇区数表示每条磁道上有几个扇区,最大为63(用6个二进制位存储).1、引导扇区Boot Sector组成Boot Sector 也就是硬盘的第一个扇区,它由MBR(Master Boot Record), DPT(Disk Partition Table) 和Boot Record ID三部分组成. MBR又称为主引导记录,占用Boot Sector的前446个字节(0~0x1BD),存放系统主引导程序(它负责从活动分区中装载并且运行系统引导程序). DPT即主分区表占用64个字节(0x1BE~0x1FD),记录磁盘的基本分区信息.主分区表分为四个分区项,每项16个字节,分别记录每个主分区的信息(因此最多可以有四个主分区). Boot Record ID即引导区标记占用两个字节(0x1FE~0x1FF),对于合法引导区,它等于0xaa55,这是判别引导区是否合法的标志). Boot Secor具体结构如图:2、分区表结构简介分区表由四个分区项构成,每一项结构如下:BYTE State:分区状态,0=未激活,0x80=激活(注意此项);BYTE StartHead:分区起始磁头号;WORD StartSC:分区起始扇区和柱面号,底字节的底6位为扇区号,高2位为柱面号的第9,10位,高字节为柱面号的低8位;BYTE Type:分区类型,如0x0B=FAT32,0x83=Linux等,00表示此项未用;BYTE EndHead:分区结束磁头号;WORD EndSC:分区结束扇区和柱面号,定义同前;DWORD Relative:在线性寻址方式下的分区相对扇区地址(对于基本分区即为绝对地址);DWORD Sectors:分区大小(总扇区数).在DOS或Windows系统下,基本分区必须以柱面为单位划分(Sectors*Heads个扇区),如对于CHS为764/256/63的硬盘,分区的最小尺寸为256*63*512/1048576=7.875MB.由于硬盘的第一个扇区已经被引导扇区占用,所以一般来说,硬盘的第一个磁道(0头0道)的其余62个扇区是不会被分区占用的.某些分区软件甚至将第一个柱面全部空出来.扩展分区结构如图:硬件不同了3D 参数(Disk Geometry):CHS(Cylinder/Head/Sector) C-Cylinder柱面数表示硬盘每面盘片上有几条磁道,最大为1024(用10个二进制位存储);H-Head磁头数表示硬盘总共有几个磁头,也就是几面盘片,最大为256(用8个二进制位存储);S-Sector 扇区数表示每条磁道上有几个扇区,最大为63(用6个二进制位存储).应该注明以上是以前的磁盘结构。

UCOS-II移植ARM的读书笔记

UCOS-II移植ARM的读书笔记

UCOS-II移植ARM的读书笔记导读:昨天晚上边看移植代码边记下来的笔记不知道怎么回事在保存的时候竟然不见了,关键是我是第一次也是正式开始移植的学习之路啊,今天在工作之前先把昨天的笔记重新回顾一下,UCOS-II的移植需要提供2,真是很郁闷,昨天晚上边看移植代码边记下来的笔记不知道怎么回事在保存的时候竟然不见了。

5555。

一个晚上工作的结果啊,关键是我是第一次也是正式开始移植的学习之路啊。

真是够倒霉的。

今天在工作真是很郁闷,昨天晚上边看移植代码边记下来的笔记不知道怎么回事在保存的时候竟然不见了。

5555。

一个晚上工作的结果啊,关键是我是第一次也是正式开始移植的学习之路啊。

真是够倒霉的。

今天在工作之前先把昨天的笔记重新回顾一下,其实后来想想也许是件好事,可以让我今天在不借助其他的帮助的情况下自己看代码自己跟自己讲一遍,其实很多看起来是倒霉看起来是灰心的事情把我们的观点换一下那么就是一件好事。

这样的情况发生在我的身上已经挺多次了。

好啦,废话不说,开始补昨天的日记UCOS-II的移植需要提供2,3个文件分别介绍如下:一:OS_CPU.H1 与编译器有关的数据类型只是按照不同的编译器编写对应的数据类型的typedef对应于ARM7的数据类型的编写如下typedef unsigned char BOOLEAN; /* 布尔变量*/typedef unsigned char INT8U; /* 无符号8位整型变量*/typedef signed char INT8S; /* 有符号8位整型变量*/typedef unsigned short INT16U; /* 无符号16位整型变量*/typedef signed short INT16S; /* 有符号16位整型变量*/typedef unsigned int INT32U; /* 无符号32位整型变量*/typedef signed int INT32S; /* 有符号32位整型变量*/typedef float FP32; /* 单精度浮点数(32位长度)*/typedef double FP64; /* 双精度浮点数(64位长度)*/在上面定义的各种数据类型中按照ARM7的堆栈宽度选择INT32Utypedef INT32U OS_STK; /* 堆栈是32位宽度*/接下来一部分是为了兼容低版本UCOS的数据类型所编写的代码,在UCOS-II中暂不考虑2 与处理器相关的代码先定义中断的实现方式,预先设定的中断方式有三种,在ARM7中设置为方式2 #define OS_CRITICAL_METHOD 2 /* 选择开、关中断的方式*/接下来的一段是我暂时还没有完全搞懂的一部分,只知道是设定了12个软件中断的函数,当调用这些函数之前都会执行对应中断号的事情。

引导程序代码

引导程序代码
节,kernel有522字节,但是一个扇区只有512字节,怎么写得下?这个问题我最先也迷
惑,后来把两个exe文件反汇编才知道真正我们写的代码出现在exe文件的513字节处,
exe文件的前512字节是mircosoft定义的exe文件的前缀,其中有exe文件标识,大小,
段定位指针等东西,这512字节我们不需要我们就只要后面的,那么我们就来写个程序
i=0;
while(1)
{
fread(&kernel_buf[i],1,1,fp); /*读入后面的所有内容直到结束*/
i++;
if(feof(fp))
{
fclose(fp);
mov bx, 0 ; kernel偏移地址为0
mov dl, 0 ; 驱动器号为0h,即A盘
mov dh, 0 ; 磁头号为0
mov ch, 0 ; 磁道号为0
break;
}
}
boot_buf[510] = 0x55; /*最后两个字节必须为55aa*/
boot_buf[511] = 0xaa;
/* 设置:将boot中的引导程序写入A盘的第0磁道1扇区*/
i=0;
while(1)
{
fread(&boot_buf[i],1,1,fp); /*读入后面的所有内容直到结束*/
i++;
if(feof(fp))
{
fclose(fp);
if (_AH!=0) /*ah为0刚写盘成功,否则退出*/
{
printf("error writing");exit(0);

主板引导程序了解引导顺序和启动设置

主板引导程序了解引导顺序和启动设置

主板引导程序了解引导顺序和启动设置在计算机中,主板引导程序(BIOS、UEFI)是一段位于主板固态芯片上的软件,其作用是告诉计算机系统如何引导操作系统。

主板引导程序可以了解引导顺序,并且还可以对启动设置进行配置。

本文将介绍主板引导程序的功能,说明引导顺序和启动设置的相关知识。

一、主板引导程序的功能主板引导程序是计算机系统的重要组成部分,它主要具有以下功能:1. 引导加载操作系统:主板引导程序负责在计算机启动时加载操作系统,并将控制权交给操作系统,从而让计算机正常运行。

2. 设备初始化:主板引导程序负责初始化计算机的硬件设备,包括处理器、内存、硬盘等,保证计算机能够正常工作。

3. 发送错误提示:主板引导程序能够检测计算机系统中的错误,并向用户发送错误提示信息,帮助用户解决问题。

4. 设置启动项:主板引导程序可以配置引导顺序,选择不同的启动设备,从而启动不同的操作系统或工具。

二、了解引导顺序引导顺序决定了计算机在启动时会先从哪个设备加载操作系统。

常见的引导设备包括硬盘、光盘和USB设备等。

主板引导程序一般提供多种引导顺序的选择,并默认按照一定顺序进行引导。

用户可以根据自己的需求,设置不同的引导顺序。

了解引导顺序的方法如下:1. 进入主板引导程序设置界面:在计算机启动时,按下指定的键(通常是Del或F2键)可以进入主板引导程序的设置界面。

2. 导航到引导选项:在设置界面中,导航到引导选项或启动选项的菜单。

具体名称可能会因不同的主板而异。

3. 设置引导顺序:在引导选项菜单中,选择正确的启动设备,并将其排在所需的顺序前面。

4. 保存并退出设置界面:在设置完成后,按照指示将设置保存并退出设置界面。

三、配置启动设置除了引导顺序,主板引导程序还提供其他的启动设置,包括以下内容:1. 启动模式:主板引导程序支持不同的启动模式,包括传统的Legacy启动模式和新型的UEFI启动模式。

用户可以根据自己的需求选择合适的启动模式。

电脑开机后出现引导程序缺失如何解决

电脑开机后出现引导程序缺失如何解决

电脑开机后出现引导程序缺失如何解决当你满心欢喜地按下电脑电源键,期待着它迅速启动并带你进入熟悉的工作或娱乐世界,却突然遭遇开机后显示引导程序缺失的错误提示,那心情肯定是无比郁闷的。

别担心,下面咱们就来详细聊聊遇到这种情况该如何解决。

首先,咱们得弄清楚什么是引导程序。

简单来说,引导程序就像是电脑启动的“引路人”,它负责在电脑开机时引导操作系统加载和启动。

如果这个“引路人”不见了或者出了问题,电脑就会迷失方向,不知道该怎么启动了。

那么,为什么会出现引导程序缺失的情况呢?这可能有多种原因。

常见的有以下几种:一是病毒或恶意软件的攻击。

这些不速之客可能会破坏电脑的系统文件,包括引导程序。

二是不正确的关机操作。

比如突然断电、强行关机等,都可能导致引导程序损坏。

三是硬盘故障。

硬盘出现坏道或者其他硬件问题,也可能影响引导程序的正常存储和读取。

四是操作系统更新或安装新软件时出现错误,导致引导程序被覆盖或损坏。

既然知道了原因,那咱们就来看看具体的解决办法。

方法一:使用系统修复工具很多操作系统都自带了修复工具,比如 Windows 系统的“自动修复”功能。

在开机时连续按 F8 键(不同电脑可能按键不同),进入高级启动选项,选择“修复计算机”,然后按照提示进行操作。

系统会尝试自动检测和修复引导程序的问题。

方法二:重建引导记录对于 Windows 系统,我们可以使用命令提示符来重建引导记录。

首先,通过安装盘或者U 盘启动进入系统安装界面,选择“修复计算机”,然后进入“命令提示符”。

输入相应的命令,如“bootrec /fixmbr”(修复主引导记录)、“bootrec /fixboot”(修复引导扇区)、“bootrec /rebuil dbcd”(重建引导配置数据)等,然后按回车键执行。

方法三:恢复系统如果上述方法都不奏效,我们可以考虑使用系统还原功能。

前提是你之前创建过系统还原点。

同样在高级启动选项中,选择“系统还原”,然后按照提示选择一个合适的还原点进行恢复。

对Linux操作系统进行引导程序开发

对Linux操作系统进行引导程序开发

对Linux操作系统进行引导程序开发引导程序是操作系统启动过程中的重要组成部分,它负责加载操作系统的内核,并进行必要的初始化工作。

在Linux操作系统中,引导程序通常是由Boot Loader负责加载的。

本文将介绍如何进行Linux操作系统的引导程序开发,包括引导程序的概念、开发环境搭建以及开发步骤等内容。

一、引导程序的概念引导程序是计算机启动过程中的第一段可执行代码,它存储在计算机的引导扇区中。

当计算机开机时,BIOS会将控制权交给引导程序,引导程序再加载操作系统的内核。

在Linux操作系统中,常见的引导程序有GRUB、LILO等。

它们可以从硬盘、光盘、网络等不同的介质中加载操作系统。

二、开发环境搭建1. 硬件平台:PC或者嵌入式设备2. 开发工具:汇编语言或者高级语言(如C语言)3. 编译器:汇编器或者C语言编译器4. 调试工具:调试器或者仿真器5. 参考文档:Linux内核源代码、硬件手册等三、引导程序开发步骤以下是Linux操作系统引导程序的开发步骤:1. 确定引导程序的入口地址和加载地址引导程序的入口地址指的是BIOS将控制权交给引导程序执行的内存地址,加载地址指的是加载的操作系统内核在内存中的起始地址。

2. 编写引导程序代码根据开发环境选择合适的编程语言,编写引导程序的代码。

引导程序的代码应该包括初始化工作、加载操作系统内核、跳转到操作系统等步骤。

3. 编译引导程序代码使用相应的编译工具,将引导程序的代码编译成可执行的二进制文件。

4. 将引导程序写入引导扇区将编译好的引导程序二进制文件写入计算机的引导扇区中。

这个过程可以通过一些工具或者命令完成,如dd命令。

5. 测试引导程序使用调试工具或者仿真器,对引导程序进行调试和测试。

确保引导程序能够正确加载操作系统内核,并启动操作系统。

四、注意事项在进行Linux操作系统的引导程序开发时,需要注意以下事项:1. 确保引导程序的代码逻辑正确,它是操作系统启动过程中的关键环节。

引导程序

引导程序

引导程序1:概述计算机在开始启动的时候,首先运行BIOS程序,BIOS程序检测当前硬件。

完成后,根据CMOS中的关于驱动器启动顺序的设置,找到一个可用的驱动器来启动。

这里的驱动器包括软盘、光盘、硬盘等设备,但是为了简化问题,下面只讨论软盘驱动器或者硬盘驱动器的启动。

在软盘(硬盘)启动的过程中,最先是BOIS将软盘的首扇区(也就是0柱面,0头、1扇区)的512个字节的内容读到内存的7C00H的地方,然后CPU跳到7C00H(CS:IP=0000:7C00H?)处运行。

由于只有512个字节的大小,不可能放下一个操作系统的代码。

因此,这512个字节的代码一般是一个过渡性的代码,它主要由读软盘扇区指令构成,用来实现这样的一个功能:将操作系统的代码都读到内存中去,读完后再通过JMP指令跳到操作系统代码的入口地址,进一步运行程序。

习惯上,我们把保存在首扇区中的程序称为引导程序。

虽说引导程序一般是用来实现操作系统的引导的,的是但这并不是必要的;它可以是任何形式的代码,只要符合的一个条件:代码对应的机器代码不超过512个字节。

下面的引导程序演示代码就没有任何的读软盘指令,它只是不断的循环一个过程:接受并显示字符。

在最后,交代一下程序的运行软件环境:程序在XP编写、编译,在虚拟机下测试。

2:引导程序演示代码2.1演示代码BOOT.ASM.MODEL SMALL ;这个可以不用管CODE SEGMENTASSUME CS:CODE,DS:CODE ; 数据段和代码段混合在一起了ORG 7C00HSTART: JMP START1INFO DB 'A:\',0 ;提示信息STR1 DB 80 DUP (0) ;接受键盘输入缓冲区START1:MOV AX,CODEMOV DS,AX;设置光标的位置,在屏幕的最后一行,屏幕行号范围0—24,列号范围0-79MOV DH,24 ;行号MOV DL,0 ;列号MOV AH,2 ;子功能号INT 10HL1: MOV SI,OFFSET INFOCALL DISP_STR ;显示提示信息CALL GET_STR ;输入字符串,以回车结束输入CALL CRLF ;换行MOV SI,OFFSET STR1CALL DISP_STR ;输出刚才从键盘中接受到的字符串CALL CRLFMOV SI,OFFSET STR1CMP BYTE PTR [SI],0 ;如果直接回车,那么就退出程序JZ EXITJMP L1EXIT:MOV AH,4CHINT 21HDISP_STR PROC ;显示字符串CLD ;设置DF=0,给后面的串指令用.WHILE BYTE PTR [SI] != 0 ;.while是汇编伪指令,功能和高级语言的while一样LODSBMOV AH,0EH ;输出字符INT 10H.ENDWRETDISP_STR ENDPCRLF PROC ;实现回车功能;屏幕上卷一行MOV CH,0MOV CL,0MOV DH,24MOV DL,79MOV AL,1MOV AH,06HMOV BH,7INT 10H;获得光标位置MOV BH,0MOV AH,3INT 10H;设置光标位置MOV BH,0MOV DL,0MOV AH,02HINT 10HRETCRLF ENDPGET_STR PROC ;从键盘输入字符串MOV SI,OFFSET STR1GETS: MOV AH,0INT 16H.IF AL != 0DH ;如果输入的字符不是回车,就显示字符,并继续输入MOV [SI],ALINC SIMOV AH,0EHINT 10HJMP GETS.ENDIFMOV [SI],0RETGET_STR ENDPCODE ENDSEND START2.2说明1)我们首先将上面的BOOT.ASM文件编译、连接为BOOT.EXE文件。

BIOS的初始化和引导加载程序

BIOS的初始化和引导加载程序

⑴检测计算机硬件和外围设备。 当BIOS一启动就会做一个自我检测的 工作(POST,自检Power On Self Test), 以检测计算机的硬件和外围设备,如检 测CPU、内存、风扇等信息。 ⑵选择由哪一个设备来开机。 ⑶读取开机设备的第1 块(MBR)中 的内容并执行这段代码。 执行以上的三个步骤后,BIOS完成了 使命。 二、引导加载程序操作
Windows server 2016 (kernel)
Windows server 2016 (kernel)
/boot
Centos 6.5 (kernel)
/boot
Centos 6.5 (kernel)
GRUB
GRUB
开机选单 注:这台计算 机只有1个系统
⑵使用MBR来启动windows server 2016操作系统。
⑴使用MBR来启动Linux操作系统
MBR
Windows server 2016 (kernedows server 2016 (kernel)
sda
/boot
Centos 6.5 (kernel)
①当开机时BIOS 读入MBR的前446 /boot 字节的程序代码 ,即boot loader的 Centos 6.5 第一阶段的程序 (kernel) 代码。
446
MBR
②boot loader 第 一阶段的程序代 码运行之后,将 载入boot loader 第二阶段的程序 代码并进入GRUB 的开机选单,在 这个开机选单中 就可以选择在这 台计算机上可以 启动的所有操作 系统。
446
MBR
①当开机时 BIOS读入 MBR的前 446字节的 /boot 程序代码, Centos 6.5 即boot (kernel) loader的第 一阶段的程 序代码。 GRUB

系统引导过程简介

系统引导过程简介

系统引导过程简介一、系统引导过程简介系统引导过程主要由以下几个步骤组成(以硬盘启动为例)1、开机;2、BIOS加电自检(POST---Power On Self Test),内存地址为0fff:0000;3、将硬盘第一个扇区(0头0道1扇区,也就是Boot Sector)读入内存地址0000:7c00处;4、检查(WORD)0000:7dfe是否等于0xaa55.若不等于则转去尝试其他介质;如果没有其他启动介质,则显示”No ROM BASIC”,然后死机;5、跳转到0000:7c00处执行MBR中的程序;6、MBR先将自己复制到0000:0600处,然后继续执行;7、在主分区表中搜索标志为活动的分区.如果发现没有活动分区或者不止一个活动分区,则停止;8、将活动分区的第一个扇区读入内存地址0000:7c00处;9、检查(WORD)0000:7dfe是否等于0xaa55,若不等于则显示“Missing Operating System”,然后停止,或尝试软盘启动;10、跳转到0000:7c00处继续执行特定系统的启动程序;11、启动系统.以上步骤中(2),(3),(4),(5)步由BIOS的引导程序完成;(6),(7),(8),(9),(10)步由MBR中的引导程序完成.一般多系统引导程序(如Smart Boot Manager, BootStar, PQBoot等)都是将标准主引导记录替换成自己的引导程序,在运行系统启动程序之前让用户选择想要启动的分区.而某些系统自带的多系统引导程序(如LILO,NT Loader等)则可以将自己的引导程序放在系统所处分区的第一个扇区中,在Linux中即为两个扇区的SuperBlock.注:以上步骤中使用的是标准的MBR,多系统引导程序的引导过程与此不同.二、硬盘结构及参数3D参数(Disk Geometry):CHS(Cylinder/Head/Sector)C-Cylinder柱面数表示硬盘每面盘片上有几条磁道,最大为1024(用10个二进制位存储);H-Head磁头数表示硬盘总共有几个磁头,也就是几面盘片,最大为256(用8个二进制位存储);S-Sector扇区数表示每条磁道上有几个扇区,最大为63(用6个二进制位存储).1、引导扇区Boot Sector组成Boot Sector 也就是硬盘的第一个扇区,它由MBR(Master Boot Record), DPT(Disk Partition Table) 和Boot Record ID三部分组成. MBR又称为主引导记录,占用Boot Sector的前446个字节(0~0x1BD),存放系统主引导程序(它负责从活动分区中装载并且运行系统引导程序). DPT即主分区表占用64个字节(0x1BE~0x1FD),记录磁盘的基本分区信息.主分区表分为四个分区项,每项16个字节,分别记录每个主分区的信息(因此最多可以有四个主分区). Boot Record ID即引导区标记占用两个字节(0x1FE~0x1FF),对于合法引导区,它等于0xaa55,这是判别引导区是否合法的标志). Boot Secor具体结构如图:2、分区表结构简介分区表由四个分区项构成,每一项结构如下:BYTE State:分区状态,0=未激活,0x80=激活(注意此项);BYTE StartHead:分区起始磁头号;WORD StartSC:分区起始扇区和柱面号,底字节的底6位为扇区号,高2位为柱面号的第9,10位,高字节为柱面号的低8位;BYTE Type:分区类型,如0x0B=FAT32,0x83=Linux等,00表示此项未用;BYTE EndHead:分区结束磁头号;WORD EndSC:分区结束扇区和柱面号,定义同前;DWORD Relative:在线性寻址方式下的分区相对扇区地址(对于基本分区即为绝对地址);DWORD Sectors:分区大小(总扇区数).在DOS或Windows系统下,基本分区必须以柱面为单位划分(Sectors*Heads个扇区),如对于CHS为764/256/63的硬盘,分区的最小尺寸为256*63*512/1048576=7.875MB.由于硬盘的第一个扇区已经被引导扇区占用,所以一般来说,硬盘的第一个磁道(0头0道)的其余62个扇区是不会被分区占用的.某些分区软件甚至将第一个柱面全部空出来.扩展分区结构如图:硬件不同了3D 参数(Disk Geometry):CHS(Cylinder/Head/Sector) C-Cylinder柱面数表示硬盘每面盘片上有几条磁道,最大为1024(用10个二进制位存储);H-Head磁头数表示硬盘总共有几个磁头,也就是几面盘片,最大为256(用8个二进制位存储);S-Sector 扇区数表示每条磁道上有几个扇区,最大为63(用6个二进制位存储).应该注明以上是以前的磁盘结构。

第二课一个简单的“引导程序”

第二课一个简单的“引导程序”

第⼆课⼀个简单的“引导程序” 上⼀节中说到BIOS会将MBR中的主引导程序(512字节)加载到内存的0x7c00处,其中这512字节的主引导程序是软件程序,是操作系统的⼀部分,因此也是由操作系统开发者来编写的,BIOS将其加载到内存后,会⾃动跳到0x7c00处去执⾏。

接下来我们⾃⼰实现⼀个“主引导程序”,功能很简单,就是让它打印⼀串字符串到屏幕上(真正的主引导程序是加载操作系统内核⽤的),注意,这段程序现在是独⽴运⾏在裸机上的,我们⽤汇编语⾔来实现它。

这个过程我们需要调⽤中断向量表中的“打印函数”,调⽤的动作是通过int 0x10来实现的。

编写程序之前,我们先来介绍⼏个要⽤到的指令: mov :赋值操作,将右操作数赋值给左操作数 例:mov ax, 0 ;将0赋值给ax寄存器 int :触发中断 例:int 0x10 ; 触发0x10中断,对屏幕进⾏操作 hlt :停⽌,CPU进⼊暂停状态,不进⾏任何操作 例:hlt ;使程序进⼊睡眠状态 汇编中的地址访问形式:段地址:段内偏移地址 例:mov byte[0xb800:0x01] ; 0xb800:0x01 -> 0xb800 + 0x01 标签: ⽤于标识后续指令的地址,(与C语⾔中的标签等价) $ 与 $$ $表⽰当前指令⾏地址,$$表⽰当前汇编段起始地址 中断调⽤与函数调⽤的对应关系如下所⽰: 实现真正的打印之前,要向bx寄存器中写⼊0x0f,向ah寄存器中写⼊0x0e,这些都是打印函数规定好的。

⽽al寄存器中需要存⼊要打印的字符,寄存器中的内容准备好了之后使⽤int 0x10来调⽤打印函数,⽽后,就可以将字符打印到屏幕上。

下⾯直接给出⽤汇编语⾔写的“主引导程序“。

org 0x7c00start:mov ax, csmov ss, axmov ds, axmov es, axmov si, msgprint:mov al, [si]add si, 1cmp al, 0x00je lastmov ah, 0x0emov bx, 0x0fint 0x10jmp printlast:hltjmp lastmsg:db 0x0a, 0x0adb "Hello, DTOS!"db 0x0a, 0x0atimes 510-($-$$) db 0x00db 0x55, 0xaa 主引导程序实际待的起始地址是0x7c00,因此第⼀⾏的org 0x7c00告诉编译器,这段程序的加载地址是0x7c00,这样编译器就可以对地址进⾏正确的处理。

引导程序Bootlosder

引导程序Bootlosder


Boot Loader的 stage2工作步骤


初始化本阶段要使用到的硬件设备。
检测系统内存映射(memory map)。
将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空
间中。

为内核设置启动参数。 调用内核。
规划内核映像和根文件系统内存占用的布局

对于内核映像,一般将其拷贝到从(MEM_START+0x8000) 这个基地址开始的大约1MB大小的内存范围内(嵌入式 Linux 的内核一般都不操过 1MB)。为什么要把从 MEM_START 到 MEM_START+0x8000 这段 32KB 大小 的内存空出来呢?这是因为 Linux 内核要在这段内存中放 置一些全局数据结构,如:启动参数和内核页表等信息。 而对于根文件系统映像,则一般将其拷贝到 MEM_START+0x00100000 开始的地方。如果用 Ramdisk 作为根文件系统映像,则其解压后的大小一般是1MB。
bios在完成硬件检测和资源分配后将硬盘mbrbootloader读到系统的ram中然后将控制权交给osbootloaderbootloader的主要运行任务就是将内核映象从硬盘上读到ram中然后跳转到内核的入口点去运行也即开始启动操作系统


PC 机中的引导加载程序由 BIOS和位于硬盘 MBR 中的 OS Boot Loader(比如,LILO 和 GRUB 等)一起组成。BIOS 在完成硬件检测和资源分配后,将硬盘 MBR 中的 Boot Loader 读到系统的 RAM 中,然后将控制权交给 OS Boot Loader。Boot Loader 的主要运行任务就是将内核映象从硬 盘上读到 RAM 中,然后跳转到内核的入口点去运行,也即开 始启动操作系统。 嵌入式系统中,通常并没有像 BIOS 那样的固件程序,因此整 个系统的加载启动任务就完全由 Boot Loader 来完成。在一 个基于 ARM9的嵌入式系统中,系统在上电或复位时通常都从 地址 0x00000000 处开始执行,而在这个地址处安排的通常就 是系统的 Boot Loader 程序。

计算机的引导过程

计算机的引导过程

打开计算机电源后到计算机准备接受你发出的命令之间计算机所运行的过程称为引导(Boot)过程。

我们知道,当关闭电源后,RAM的数据将丢失,因此,计算机不是用RA 来保持计算机的基本工作指令,而是使用另外的方法将操作系统文件加载到RAM中,再由操作系统接管对机器的控制。

这是引导过程中的一个主要部分。

总的说来,引导过程有下面几个步骤:①加电––––打开电源开关,给主板和内部风扇供电。

②启动引导程序––––CPU开始执行存储在ROM BIOS中的指令。

③开机自检––––计算机对系统的主要部件进行诊断测试。

④加载操作系统––––计算机将操作系统文件从磁盘读到RAM中。

⑤检查配置文件,定制操作系统的运行环境––––读取配置文件,根据用户的设置对操作系统进行定制。

⑥准备读取命令和数据––––计算机等待用户输入命令和数据。

(一) 加电引导过程的第一步就是通电。

电扇开始运转,电源指示灯应该变亮,否则说明系统电源供应有问题,或是主板等部件和机箱发生短路。

(二) 启动引导程序CPU是从内存地址FFFF0H处开始执行指令的,从前面的介绍可知,这个地址实际上在系统BIOS的地址范围内,无论是哪家公司的BIOS,放在这里的只是一条跳转指令,跳到系统BIOS中真正的启动代码处。

(三) 开机自检系统BIOS的启动代码首先要做的事情就是进行POST(Power-On Self Test,加电后自检),POST的主要任务是检测系统中一些关键设备是否存在和能否正常工作,例如内存和显卡等设备。

由于POST是最早进行的检测过程,此时显卡还没有初始化,如果系统BIOS 在进行POST的过程中发现了一些致命错误,例如没有找到内存或者内存有问题(此时只会检查640K常规内存),那么系统BIOS就会直接控制喇叭发声来报告错误。

正常情况下,POST过程进行得非常快。

POST结束之后,系统BIOS将查找显卡的BIOS并调用它的初始化代码,由显卡BIOS 来初始化显卡,此时多数显卡都会在屏幕上显示出一些初始化信息,介绍生产厂商、图形芯片类型等内容。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

44BINIT.S引导程序注释;*******************************************************; * NAME : 44BINIT.S *; * Version : 10.JAn.2003 *; * Description: *; * C start up codes *; * Configure memory, Initialize ISR ,stacks *; * Initialize C-variables *; * Fill zeros into zero-initialized C-variables *; *******************************************************GET option.s ;相当于c语言中的#include "option.s"GET memcfg.s;Interrupt Control;声明一些符号常量,这些符号常量和地址相应寄存器的地址对应INTPND EQU 0x01e00004 ;指示中断请求状态寄存器每一位代变一种中断请求具体表示哪一种中断请参考44b0 spec INTMOD EQU 0x01e00008 ;中断模式寄存器有两种中断模式对应位为1代表fip mode 0代表riq modeINTMSK EQU 0x01e0000c ;确定哪个中断源被屏蔽屏蔽的中断源将不被服务I_ISPR EQU 0x01e00020 ;中断服务挂起寄存器I_CMST EQU 0x01e0001c ;当前主寄存器irq优先级;Watchdog timerWTCON EQU 0x01d30000 ;看门狗定时器控制寄存器;Clock ControllerPLLCON EQU 0x01d80000 ;pll控制寄存器CLKCON EQU 0x01d80004 ;时钟控制寄存器LOCKTIME EQU 0x01d8000c ;锁定时间计数值寄存器;Memory ControllerREFRESH EQU 0x01c80024 ;Dram/sdram刷新控制寄存器;下面是对arm处理器模式寄存器对应值的常数定义,arm处理器中有一个CPSR程序状态寄存器它的后五位决定目前的处理器模式;Pre-defined constantsUSERMODE EQU 0x10 ;0b10000用户模式FIQMODE EQU 0x11 ;0b10001FIQ模式IRQMODE EQU 0x12 ;0b10010IRQ模式SVCMODE EQU 0x13 ;0b10011管理模式ABORTMODE EQU 0x17 ;0b10111中止模式UNDEFMODE EQU 0x1b ;0b11011未定义MODEMASK EQU 0x1f ;0b11111系统模式NOINT EQU 0xc0 ;;check if tasm.exe is used.;arm处理器有两种工作状态 1.arm:32位这种工作状态下执行字对准的arm指令 2.Thumb:16位这种工作状态执行半字对准的Thumb指令;因为处理器分为16位 32位两种工作状态程序的编译器也是分16位和32两种编译方式所以下面的程序用于根据处理器工作状态确定编译器编译方式;code16伪指令指示汇编编译器后面的指令为16位的thumb指令;code32伪指令指示汇编编译器后面的指令为32位的arm指令;这段是为了统一目前的处理器工作状态和软件编译方式(16位编译环境使用tasm.exe编译)GBLL THUMBCODE ;设置一个全局逻辑变量[ {CONFIG} = 16 ;if config==16 这里表示你的目前处于领先地16位编译方式THUMBCODE SETL {TRUE} ;设置THUMBCODE 为 trueCODE32 ;转入32位编译模式| 次 ;elseTHUMBCODE SETL {FALSE} ;设置THUMBCODE 为 false][ THUMBCODE ;if THUMBCODE==TRUECODE32 ;for start-up code for Thumb mode;转入32位编译方式];注意下面这段程序是个宏定义很多人对这段程序不理解我再次强调这是一个宏定义所以大家要注意了下面包含的HandlerXXX HANDLER HandleXXX将都被下面这段程序展开;这段程序用于把中断服务程序的首地址装载到pc中,有人称之为“加载程序”。

;本初始化程序定义了一个数据区(在文件最后),34个字空间,存放相应中断服务程序的首地址。

每个字空间都有一个标号,以Handle***命名。

;在向量中断模式下使用“加载程序”来执行中断服务程序。

;这里就必须讲一下向量中断模式和非向量中断模式的概念;向量中断模式是当cpu读取位于0x18处的IRQ中断指令的时候,系统自动读取对应于该中断源确定地址上的指令取代0x18处的指令,通过跳转指令系统就直接跳转到对应地址;函数中节省了中断处理时间提高了中断处理速度标例如 ADC中断的向量地址为0xC0,则在0xC0处放如下代码:ldr PC,=HandlerADC 当ADC 中断产生的时候系统会;自动跳转到HandlerADC函数中;非向量中断模式处理方式是一种传统的中断处理方法,当系统产生中断的时候,系统将interrupt pending寄存器中对应标志位置位然后跳转到位于0x18处的统一中断;函数中该函数通过读取interrupt pending寄存器中对应标志位来判断中断源并根据优先级关系再跳到对应中断源的处理代码中MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabelsub sp,sp,#4 ;decrement sp(to store jump address)stmfd sp!,{r0} ;PUSH the work register to stack;将要使用的r0寄存器入栈ldr r0,=$HandleLabel;load the address of HandleXXX to r0ldr r0,[r0] ;load the contents(service routine start address) of HandleXXXstr r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack;将对应的中断函数首地址入栈ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR);将中断函数首地址出栈放入程序指针中系统将跳转到对应中断处理函数MEND;一个arm由RO,RW,ZI三个断组成其中RO为代码段,RW是已经初始化的全局变量,ZI是未初始化的全局变量(对于GNU工具对应的概念是TEXT ,DATA,BSS)bootloader;bootloader要将RW段复制到ram中并将ZI段清零编译器使用下列段来记录各段的起始和结束地址; |Image$$RO$$Base| ; RO段起始地址; |Image$$RO$$Limit| ; RO段结束地址加1; |Image$$RW$$Base| ; RW段起始地址; |Image$$RW$$Limit| ; RW段结束地址加1; |Image$$ZI$$Base| ; ZI段起始地址; |Image$$ZI$$Limit| ; ZI段结束地址加1;这些标号的值是通过编译器的设定来确定的如编译软件中对ro-base和rw-base的设定,例如 ro-base=0xc000000 rw-base=0xc5f0000IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)IMPORT |Image$$RW$$Base| ; Base of RAM to initialiseIMPORT |Image$$ZI$$Base| ; Base and limit of areaIMPORT |Image$$ZI$$Limit| ; to zero initialiseIMPORT Main ; The main entry of mon program;下面为代码段AREA Init,CODE,READONLY;异常中断矢量表(每个表项占4个字节)下面是中断向量表一旦系统运行时有中断发生即使移植了操作系统如linux 处理器已经把控制权交给了操作系统一旦发生中断处理器还是会跳转到从0x0开始;中断向量表中某个中断表项(依据中断类型)开始执行;具体中断向量布局请参考s3c44b0 spec 例如 adc中断向量为 0x000000c0下面对应表中第49项位置向量地址0x0+4*(49-1)=0x000000c0 ENTRY;扳子上电和复位后程序开始从位于0x0处开始执行硬件刚刚上电复位后程序从这里开始执行跳转到标号为ResetHandler处执行b ResetHandler ;for debugb HandlerUndef ;handlerUndefb HandlerSWI ;SWI interrupt handlerb HandlerPabort ;handlerPAbortb HandlerDabort ;handlerDAbortb . ;handlerReservedb HandlerIRQb HandlerFIQ;***IMPORTANT NOTE***;If the H/W vectored interrutp mode is enabled, The above two instructions should;be changed like below, to work-around with H/W bug of S3C44B0X interrupt controller.; b HandlerIRQ -> subs pc,lr,#4; b HandlerIRQ -> subs pc,lr,#4VECTOR_BRANCHldr pc,=HandlerEINT0 ;mGA H/W interrupt vector tableldr pc,=HandlerEINT1 ;ldr pc,=HandlerEINT2 ;ldr pc,=HandlerEINT3 ;ldr pc,=HandlerEINT4567 ;ldr pc,=HandlerTICK ;mGAb .b .ldr pc,=HandlerZDMA0 ;mGB ldr pc,=HandlerZDMA1 ;ldr pc,=HandlerBDMA0 ;ldr pc,=HandlerBDMA1 ;ldr pc,=HandlerWDT ;ldr pc,=HandlerUERR01 ;mGB b .b .ldr pc,=HandlerTIMER0 ;mGC ldr pc,=HandlerTIMER1 ;ldr pc,=HandlerTIMER2 ;ldr pc,=HandlerTIMER3 ;ldr pc,=HandlerTIMER4 ;ldr pc,=HandlerTIMER5 ;mGC b .b .ldr pc,=HandlerURXD0 ;mGD ldr pc,=HandlerURXD1 ;ldr pc,=HandlerIIC ;ldr pc,=HandlerSIO ;ldr pc,=HandlerUTXD0 ;ldr pc,=HandlerUTXD1 ;mGD b .b .ldr pc,=HandlerRTC ;mGKA b . ;b . ;b . ;b . ;b . ;mGKAb .b .ldr pc,=HandlerADC ;mGKBb . ;b . ;b . ;b . ;b . ;mGKBb .b .;0xe0=EnterPWDNldr pc,=EnterPWDNLTORG;下面是具体的中断处理函数跳转的宏,通过上面的$HandlerLabel的宏定义展开后跳转到对应的中断处理函数(对于向量中断)HandlerFIQ HANDLER HandleFIQHandlerIRQ HANDLER HandleIRQHandlerUndef HANDLER HandleUndefHandlerSWI HANDLER HandleSWIHandlerDabort HANDLER HandleDabortHandlerPabort HANDLER HandlePabortHandlerADC HANDLER HandleADCHandlerRTC HANDLER HandleRTCHandlerUTXD1 HANDLER HandleUTXD1HandlerUTXD0 HANDLER HandleUTXD0HandlerSIO HANDLER HandleSIOHandlerIIC HANDLER HandleIICHandlerURXD1 HANDLER HandleURXD1HandlerURXD0 HANDLER HandleURXD0HandlerTIMER5 HANDLER HandleTIMER5HandlerTIMER4 HANDLER HandleTIMER4HandlerTIMER3 HANDLER HandleTIMER3HandlerTIMER2 HANDLER HandleTIMER2HandlerTIMER1 HANDLER HandleTIMER1HandlerTIMER0 HANDLER HandleTIMER0HandlerUERR01 HANDLER HandleUERR01HandlerWDT HANDLER HandleWDTHandlerBDMA1 HANDLER HandleBDMA1HandlerBDMA0 HANDLER HandleBDMA0HandlerZDMA1 HANDLER HandleZDMA1HandlerZDMA0 HANDLER HandleZDMA0HandlerTICK HANDLER HandleTICKHandlerEINT4567 HANDLER HandleEINT4567HandlerEINT3 HANDLER HandleEINT3HandlerEINT2 HANDLER HandleEINT2HandlerEINT1 HANDLER HandleEINT1HandlerEINT0 HANDLER HandleEINT0;One of the following two routines can be used for non-vectored interrupt.;下面这段程序是用来处理非向量中断,具体判断I_ISPR中各位是否置1 置1表示目前此中断等待响应(每次只能有一位置1),从最高优先级中断位开始判断,检测到等待服务;中断就将pc置为中断服务函数首地址IsrIRQ ;using I_ISPR register.sub sp,sp,#4 ;reserved for PCstmfd sp!,{r8-r9};IMPORTANT CAUTION;if I_ISPC isn't used properly, I_ISPR can be 0 in this routine.ldr r9,=I_ISPRldr r9,[r9]mov r8,#0x0movs r9,r9,lsr #1bcs %F1add r8,r8,#4b %B01ldr r9,=HandleADCadd r9,r9,r8ldr r9,[r9]str r9,[sp,#8]ldmfd sp!,{r8-r9,pc};****************************************************;* START *;****************************************************;扳子上电和复位后程序开始从位于0x0执行b ResetHandler 程序从跳转到这里执行;板子上电复位后执行几个步骤这里通过标号在注释中加1,2,3....标示标号表示执行顺序;1.禁止看门狗屏蔽所有中断ResetHandlerldr r0,=WTCON ;watch dog disableldr r1,=0x0str r1,[r0]ldr r0,=INTMSKldr r1,=0x07ffffff ;all interrupt disablestr r1,[r0];2.根据工作频率设置pll;这里介绍一下计算公式;Fpllo=(m*Fin)/(p*2^s);m=MDIV+8,p=PDIV+2,s=SDIV;Fpllo必须大于20Mhz小于66Mhz;Fpllo*2^s必须小于170Mhz;如下面的PLLCON设定中的M_DIV P_DIV S_DIV是取自option.h中;#elif (MCLK==40000000);#define PLL_M (0x48);#define PLL_P (0x3);#define PLL_S (0x2);所以m=MDIV+8=80,p=PDIV+2=5,s=SDIV=2;硬件使用晶振为10Mhz,即Fin=10Mhz;Fpllo=80*10/5*2^2=40Mhz;****************************************************;* Set clock control registers *;****************************************************ldr r0,=LOCKTIMEldr r1,=800 ; count = t_lock * Fin (t_lock=200us, Fin=4MHz) = 800 str r1,[r0][ PLLONSTARTldr r0,=PLLCON ;temporary setting of PLLldr r1,=((M_DIV<<12)+(P_DIV<<4)+S_DIV) ;Fin=10MHz,Fout=40MHzstr r1,[r0]]ldr r0,=CLKCONldr r1,=0x7ff8 ;All unit block CLK enablestr r1,[r0];3.置存储相关寄存器的程序;这是设置SDRAM,flash ROM 存储器连接和工作时序的程序,片选定义的程序;SMRDATA map在下面的程序中定义;SMRDATA中涉及的值请参考memcfg.s程序;具体寄存器各位含义请参考s3c44b0 spec;****************************************************;* Set memory control registers *;****************************************************ldr r0,=SMRDATAldmia r0,{r1-r13}ldr r0,=0x01c80000 ;BWSCON Addressstmia r0,{r1-r13};****************************************************;* Initialize stacks *;****************************************************ldr sp, =SVCStack ;Why?bl InitStacks;5.设置缺省中断处理函数;****************************************************;* Setup IRQ handler *;****************************************************ldr r0,=HandleIRQ ;This routine is neededldr r1,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1cstr r1,[r0];6.将数据段拷贝到ram中将零初始化数据段清零跳入C语言的main函数执行到这步结束bootloader初步引导结束;********************************************************;* Copy and paste RW data/zero initialized data *;********************************************************LDR r0, =|Image$$RO$$Limit| ; Get pointer to ROM dataLDR r1, =|Image$$RW$$Base| ; and RAM copyLDR r3, =|Image$$ZI$$Base|;Zero init base => top of initialised dataCMP r0, r1 ; Check that they are differentBEQ %F1CMP r1, r3 ; Copy init dataLDRCC r2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4STRCC r2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4BCC %B01LDR r1, =|Image$$ZI$$Limit| ; Top of zero init segment MOV r2, #02CMP r3, r1 ; Zero initSTRCC r2, [r3], #4BCC %B2[ :LNOT:THUMBCODEBL Main ;Don't use main() because ......;跳入main函数B .][ THUMBCODE ;for start-up code for Thumb modeorr lr,pc,#1bx lrCODE16bl Main ;Don't use main() because ......;跳入main函数b .CODE32];4.初始化各模式下的栈指针;**************************************************** ;* The function for initializing stack *;**************************************************** InitStacks;Don't use DRAM,such as stmfd,ldmfd......;SVCstack is initialized before;Under toolkit ver 2.50, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'mrs r0,cpsrbic r0,r0,#MODEMASKorr r1,r0,#UNDEFMODE|NOINTmsr cpsr_cxsf,r1 ;UndefModeldr sp,=UndefStackorr r1,r0,#ABORTMODE|NOINTmsr cpsr_cxsf,r1 ;AbortModeldr sp,=AbortStackorr r1,r0,#IRQMODE|NOINTmsr cpsr_cxsf,r1 ;IRQModeldr sp,=IRQStackorr r1,r0,#FIQMODE|NOINTmsr cpsr_cxsf,r1 ;FIQModeldr sp,=FIQStackbic r0,r0,#MODEMASK|NOINTorr r1,r0,#SVCMODEmsr cpsr_cxsf,r1 ;SVCModeldr sp,=SVCStack;USER mode is not initialized.mov pc,lr ;The LR register may be not valid for the mode changes.;下面是pwdn模式下的相关寄存器的定义;****************************************************;* The function for entering power down mode *;****************************************************;void EnterPWDN(int CLKCON);EnterPWDNmov r2,r0 ;r0=CLKCONldr r0,=REFRESHldr r3,[r0]mov r1, r3orr r1, r1, #0x400000 ;self-refresh enablestr r1, [r0]nop ;Wait until self-refresh is issued. May not be needed. nop ;If the other bus master holds the bus, ...nop ; mov r0, r0nopnopnopnop;enter POWERDN modeldr r0,=CLKCONstr r2,[r0];wait until enter SL_IDLE,STOP mode and until wake-upmov r0,#0xff0 subs r0,r0,#1bne %B0;exit from DRAM/SDRAM self refresh mode.ldr r0,=REFRESHstr r3,[r0]mov pc,lrLTORG;这是上面提到的对存储寄存器初始化的数据mapSMRDATA DATA;*****************************************************************;* Memory configuration has to be optimized for best performance *;* The following parameter is not optimized. *;*****************************************************************;*** memory access cycle parameter strategy ***; 1) Even FP-DRAM, EDO setting has more late fetch point by half-clock; 2) The memory settings,here, are made the safe parameters even at 66Mhz.; 3) FP-DRAM Parameters:tRCD=3 for tRAC, tcas=2 for pad delay, tcp=2 for bus load.; 4) DRAM refresh rate is for 40Mhz.DCD 0x11110090 ;Bank0=OM[1:0], Bank1~Bank7=16bit, bank2=8bit;DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0 DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1 DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2 DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) ;REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019DCD 0x16 ;SCLK power mode, BANKSIZE 32M/32MDCD 0x20 ;MRSR6 CL=2clkDCD 0x20 ;MRSR7ALIGN;下面是对ram区域map的定义AREA RamData, DATA, READWRITE;这里定义了处理器工作于各模式的堆栈区在ram中map^ (_ISR_STARTADDRESS-0x500)UserStack # 256 ;c1(c7)ffa00SVCStack # 256 ;c1(c7)ffb00UndefStack # 256 ;c1(c7)ffc00AbortStack # 256 ;c1(c7)ffd00IRQStack # 256 ;c1(c7)ffe00FIQStack # 0 ;c1(c7)fff00;这里将中断异常向量建立在sdram中^ _ISR_STARTADDRESSHandleReset # 4HandleUndef # 4HandleSWI # 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ # 4HandleFIQ # 4;Don't use the label 'IntVectorTable',;because armasm.exe cann't recognize this label correctly. ;the value is different with an address you think it may be. ;IntVectorTableHandleADC # 4HandleRTC # 4HandleUTXD1 # 4HandleUTXD0 # 4HandleSIO # 4HandleIIC # 4HandleURXD1 # 4HandleURXD0 # 4HandleTIMER5 # 4HandleTIMER4 # 4HandleTIMER3 # 4HandleTIMER2 # 4HandleTIMER1 # 4HandleTIMER0 # 4HandleUERR01 # 4HandleWDT # 4HandleBDMA1 # 4HandleBDMA0 # 4HandleZDMA1 # 4HandleZDMA0 # 4HandleTICK # 4HandleEINT4567 # 4 HandleEINT3 # 4HandleEINT2 # 4HandleEINT1 # 4HandleEINT0 # 4 ;0xc1(c7)fff84 END。

相关文档
最新文档