- 论坛徽章:
- 0
|
操作系统学习笔记——引导
看到这么多的朋友在研究和讨论
我再加点东东吧!
搜集了一些引导资料
转一下
第二章. 把你的操作系统引导起来
作者:易昭华
什么是操作系统的引导过程?
所谓操作系统的引导过程是将存放在硬盘上的静态的操作系统装载到内存中,并开始执行操作系统的过程。操作系统的整个引导过程应该从计算机上电开始,分为以下几个大步骤:
上电
自检
加载引导扇区
加载操作系统
运行操作系统
引导过程的原理与过程
上电
上电是指按下计算机的电源按钮让计算机开始加电运行。这个过程与计算机的硬件电路关系非常密切,因为计算机加电的第一个状态是由硬件电路决定的,加电后第一个状态主要由计算机处理器(CPU)生产商决定,对于x86系列的CPU,一加电就将指令寄存器设置为:0ffff:0000,表示CPU开始从0ffff:0000这个内存中取出一条指令执行,通常在0ffff:0000处是一条地址转跳指令,转向BIOS的入口。由于BIOS是固化在内存中的,所以,一加电后,CPU可以直接读取BIOS中的指令。
自检
进入BIOS后,BIOS的主要功能包括以下两项:第一项功能是进行计算机自检,第二项功能是加载引导扇区。BIOS进行自检的工作主要是检查计算机是否出现异常,是否可以继续运行下去,这一部分与引导过程本身关系不大,它只是引导过程中的一个步骤,BIOS中与引导关系密切的是上面提到的BIOS的第二项功能,即加载引导扇区,这一项工作的主要内容是把磁盘的引导扇区的内容加载到内存中来,并且转跳到引导程序的第一条指令。
加载引导扇区
硬盘与软盘都有引导扇区,引导扇区就是软盘或硬盘的第一个逻辑扇区,即软盘或硬盘的第0个磁头第0个磁道第1个扇区。软盘的结构比硬盘简单,在软盘上,一般只有一个分区,也就是可以装载一个操作系统,所以在软盘的第一个逻辑扇区就可以把操作系统加载到内存中,而硬盘则不同,由于硬盘的总容量比较大,所以硬盘被分为几个分区,理论上讲每个分区都可以安装一个操作系统,所以在每个分区上都有一个用于加载本分区的引导扇区,因此硬盘的引导扇区比软盘复杂,它不是立即加载操作系统而是加载分区上的引导扇区,然后由分区上的引导扇区加载本分区上的操作系统。在本文以软盘的引导扇区为例来介绍。
软盘的引导扇区是软盘的第一个逻辑扇区,当BIOS的自检过程结束以后,根据BIOS的规范,它下一步要做的工作就是把指定的引导设备(软盘、硬盘、光盘等)上的第一个扇区的内容加载到内存中,并且转跳到加载后的引导扇区的第一条指令。因此我们在开发操作系统引导程序的时候,只要将引导程序直接写如第一个逻辑扇区就可以了,BIOS会自动把它加载到内存中。
加载操作系统
对于软盘来讲,引导扇区中的引导程序就是用于加载操作系统。所谓加载操作系统,也就是把操作系统从磁盘拷贝到内存。因此引导程序首先必须知道操作系统在磁盘的位置,由于此时还没有文件系统,这时引导程序必须通过绝对位置来访问,也就是操作系统在磁盘的开始扇区和结束扇区。操作系统在磁盘的位置与操作系统的安装程序有关,操作系统的安装程序把操作系统从安装盘拷贝到计算机的磁盘上,引导程序把操作系统从磁盘拷贝到内存。
运行操作系统
引导程序把操作系统拷贝到内存后所要做的第一件事就是转跳到操作系统的第一条指令,这样,操作系统就开始运行了。
如何使操作系统引导起来?
要使操作系统引导起来,包括下面的环节:
编写引导程序 (Boot Loader)
制作引导扇 (Boot Sector): 把引导程序写入引导扇区
编写系统加载程序 (OS Loader)
制作系统加载映像 (OS Loader Image)
设置启动设备
第一步:编写引导扇启动程序 (Boot Loader)
这个例子的目标是编写一个运行于PC机上的引导扇启动程序 (Boot Loader) 。
开发语言:C语言和8086汇编语言
开发环境:Borland C++ 3.0
工程文件设置:编译模式为tiny模式
#include "platform.h"
#include "diskstru.h"
extern St_DOS_BootRecord g_stBootRecord;
static BYTE s_bHead;
static BYTE s_bTrack;
static BYTE s_bSector;
static void Lba2CHS(UINT Lba)
{
_asm mov ax, Lba
_asm xor dx, dx
_asm mov bx, g_stBootRecord.BPB.SectorsPerTrack
_asm div bx
_asm inc dx
_asm mov s_bSector, dl
_asm xor dx, dx
_asm mov bx, g_stBootRecord.BPB.Sides
_asm div bx
_asm mov s_bHead, dl
_asm mov s_bTrack, al
}
static int pascal ReadSector( void far * lpBuff )
{
_asm{
mov ax, word ptr [lpBuff+2]
mov es, ax
mov bx, word ptr [lpBuff]
mov ah, 02h
mov al, 1
mov ch, s_bTrack
mov cl, s_bSector
mov dh, s_bHead
mov dl, 0
int 13h
jc l_error
jmp short l_ret
}
l_error:
return 0;
l_ret:
return 1;
}
static const char s_szStarting[] = "Starting Myself Operating system...";
static const char s_szFail[] = "Fail to load OsLoader, system halt.";
static void TextOut(BYTE x, BYTE y, const char * szText, int n)
{
_asm {
mov cx, n
mov dh, y
mov dl, x
mov bx, 15
mov ax, szText
push bp
mov bp, ax
mov ax, 1300h
int 10h
pop bp
}
}
void start(void)
{
UINT uLba, i;
BYTE far * lpSect = (BYTE far *)0x80000000;
// Clear screen
_asm{
mov ax, 3
int 10h
}
// Display the logo information
TextOut( 0, 0, s_szStarting, sizeof(s_szStarting)-1 );
// Calculate the sector number of the first data sector
uLba = g_stBootRecord.BPB.ReservedSectors +
g_stBootRecord.BPB.FAT_Copies * g_stBootRecord.BPB.SectorsPerFAT +
(g_stBootRecord.BPB.RootDirEntries >;>; 4);
uLba = 6;
// Load the first 128 data sectors into memory at address 8000h:0000h
for( i = 0; i < 10; i ++ )
{
Lba2CHS( uLba );
if( !ReadSector( lpSect ) )
{
goto l_Fail;
}
uLba ++;
lpSect += 512;
}
// Execute the fetched OS loader at address 8000h:0100h
_asm {
mov ax, 0x8000
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0xFFF0
push ax //push cs
mov ax, 0x100
push ax //push ip(0)
retf // execute OS
}
l_Fail:
TextOut( 0, 1, s_szFail, sizeof(s_szFail)-1 );
for(;;
}
下一步:制作引导扇 (Boot Sector): 把引导程序写入引导扇区
第一步,把编译后的引导转为.com文件,所用的命令如下:tdstrip -c bootsect.exe bootsect.com
第二步,把引导程序写入引导扇区,这一步主要的工具是:DISKEDIT.EXE,操作步骤包括以下几步:
(1) 通过"Object"->;"files"菜单打开.com格式的引导程序
(2) 选择"Tools"->;"Write Object to…"菜单,然后选择"to physical sectors",然后选择第0个磁头,第0个磁道,第1个扇区。 |
|