操作系统的启动

BIOS

BIOS(Base Input & Output System, 即基本输入输出系统)是计算机上第一个运行的程序,它的运行是计算机开机后由硬件唤醒的。由于BIOS代码所做的工作基本上是不变的,正常情况下不会修改,所以BIOS代码存放在ROM(read only memory, 即只读存储器)中。此ROM映射在低端1MB内存的顶部,即地址0xF0000~0xFFFFF
操作系统的启动_第1张图片
在实模式下,段地址乘以16(即左移4位)再与偏移地址相加,其结果就是物理地址,所以地址是20位编码

我们可以利用bochs来看看开机时的情况:

在开机的一瞬间,CPU的cs:ip寄存器被强制初始化为0xF000:0xFFF0,而该处的内容是一个指令(jmp far f000:e05b),在执行的了该指令后,cs:ip变为0xF000:0xFE05B,而0xFE05B就是BIOS代码真正开始执行的地方

BIOS需要检查各种计算机硬件并初始化,然后需要建立数据结构(BIOS data Area),中断向量表(Interrupt Vector Table)并填写中断例程
操作系统的启动_第2张图片
BIOS的最后一项工作是校验启动盘中位于0盘0道1扇区的内容,如果此扇区的末尾的两个字节分别是魔数0x55和0xaa,BIOS便认为此扇区中确实存在可执行的程序,便从物理地址0x7c00处开始加载,随后跳转到此地址,继续执行
操作系统的启动_第3张图片
MBR(Main Boot Record, 即主引导记录)存在于硬盘最开始的那个扇区(0盘0道1扇区),并被BIOS加载进内存,这是编写操作系统的第一个程序

我们可以编写一个主引导程序,该程序实现的功能是在屏幕上打印字符串"Hello World!"

; MBR
SECTION MBR vstart=0x7c00 ; 起始地址编译为0x7c00
    mov ax,cs ; BIOS是通过jmp 0:0x7c00跳转的,因此cs=0
    ; 初始化各类栈寄存器
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov fs,ax
    
    mov sp,0x7c00 ; 0c7c00以下的内存区域是安全的,可以用作栈

    mov ah,3 ; 调用3号子功能,获取光标位置
    mov bh,0 ; 带获取光标的页号为0
    int 0x10 ; 输出:ch=光标开始行,cl=光标结束行,dh=光标所在行,dl=光标所在列号

    mov ax,message
    mov bp,ax ; es:bp是串首地址
    mov cx,[length] ; cx是串长度,不包括结束符0的字符个数
    mov ah,0x13 ; 调用0x13号子功能,表示显示字符即属性
    mov al,0x01 ; al设置写字符的方式,al=0x01表示显示字符串,光标跟随移动
    mov bh,0x0 ; bh存储要显示的页号
    mov bl,0x2 ; bl中是字符属性,bl=0x2表示属性是黑底绿字
    ; dh,dl存储光标开始的行和列
    int 0x10

    jmp $ ; 使程序悬停在此

    message db "hello world!"
    length dw $-message
    times 510-($-$$) db 0
    db 0x55,0xaa

使用nams将该汇编成二进制文件

nasm -o system.img mbr.S

利用qemu来虚拟计算机

qemu-system-i386  -boot a -hda system.img

运行成功
操作系统的启动_第4张图片

你可能感兴趣的:(操作系统,BIOS,intel汇编,MBR,bootsect,linux)