关于boot loader装载程序的学习纪录

突然来了兴趣,看了关于linux的一点点源代码,说实话一点看不懂,所以硬着头皮,查了许多的资料。有些收获,所以写了出来。 
  
首先我靠说一说关于系统的引导过程:原理上说,首先是bios自检,察看在其中设置的硬件的是否正常运行。然后就是我们这里要讲到的,由bios将磁盘上第一分区第一扇区的程序(最后两个字节为55AAh)载入道内存的0x0000:0x7c00处。然后程序将控制权交给已载入的程序,在进行操作系统的初始化等操作。 
所以,我们可以看到从功能上来说,boot Loader就是起到了引导系统装载程序的作用,这也就是他名字的含义。 
  下面的代码(该部分引用在tangl_99的博客): 
一个小小的微缩版的16位实模式下的Boot Loader。
BITS 16
org 0x7c00 
entry:
  mov ax, 0
  mov ds, ax 
  mov si, WelcomeMsg 
  call putstr
hang: 
  jmp hang 

WelcomeMsg db 'Welcome to My Operating System',0 

putstr:
    lodsb   
    or al, al  
    jz putstrd  
    mov ah, 0x0e 
    mov bx, 0x0007 
    int 0x10
    jmp putstr
putstrd:
    retn 

size equ $ - entry
%if size+2 > 512
  %error "code is too large for boot sector"
%endif
 times (512 - size - 2) db 0 
 db 0x55, 0xAA  
其中显示为深红色的才是真正的汇编代码,而显示为蓝色的是nasm的宏或一些控制语句.
首先是BITS 16,这个说明是要把我们这个程序编译成16位的代码,org 0x7c00则是告诉编译器我们的这段代码将从0x7c00这个地址开始执行(由于汇编编译器对于静太变量的引用都是使用绝对地址,所以一定要设置好你程序运行开始的地址.比如DOS下.com文件就要设置org 0x100也是一个道理.否则你的数据地址会出现错误) 
entry:
  mov ax, 0
  mov ds, ax 
  mov si, WelcomeMsg 
  call putstr
程序中entry开始进入执行.下面的汇编代码首先把0x0000传到ds去.因为我们这个程序是在0x0000:0x7c00执行,那么段地址应该是0x0000,否则后面我们的WelcomeMsg就显示不出来了.
然后调用一个子程序putstr.它的功能就是显示一个字符串.参数是放在SI寄存器中的,我把WelcomeMsg的地址传给SI,然后调用call putstr,就可以显示出来Welcome to My Operating System.看到这里,很多人都会兴奋不已的.毕竟看到自己的"操作系统"为自己打印出来一句话,确实让人高兴!但是没有完,这个Boot Loader程序连个真正的Boot Loader程序都算不上,怎么能说是操作系统. 
putstr:
    lodsb   
    or al, al  
    jz putstrd  
    mov ah, 0x0e 
    mov bx, 0x0007 
    int 0x10
    jmp putstr
putstrd:
    retn
这个子程序就不讲了吧,很简单,就是调用BIOS 10h显示字符的中断.需要注意的是,不要使用21h DOS中断来显示字符哦!因为那是DOS的东西,这里是在启动另外一个"操作系统",怎么用得了DOS的中断,是不是  

size equ $ - entry
%if size+2 > 512
  %error "code is too large for boot sector"
%endif
 times (512 - size - 2) db 0 
这段蓝色的代码不是我们程序的,只是为了控制我们的这个程序大小为512个字节而显示的.因为这个程序是放在软盘的第一个扇区里,是为软盘的第一个扇区量身打造的,所以大小一定要是512字节,也既是一个扇区的大小. 
db 0x55, 0xAA 
这里有点奇怪,为什么要在程序的最后加上0x55,0xAA 这个也是计算机BIOS规定的东西.前面不是说了,BIOS会自动读取软盘的第一个扇区并执行吗 当BIOS读到这里0x55,0xAA的时候,它就知道该读的扇区的信息已经结束了,然后自动去执行刚读取的代码.所以我们必须把这个0x55,0xAA加上去. 

比如你的boot loader program名字叫boot.asm.然后用nasm来编译 
nasmw boot.asm -o boot.bin 
debug
-n boot.bin
-l 0
-w 0 0 0 1
-q 
在你的dos下打入上面黄色的命令就可以把boot.asm编译并写入磁盘了. 
  



下面是我找到的号称最小的引导程序: 

最简单的引导程序的写法,功能很少,但是我想对操作系统的初学者有一定的帮助。
;它实现的功能是制作一张可引导的软盘,软盘的实际内容则是一段程序,则段程序在系统引导的时候在屏幕
;上打印一大串的‘a’。只要你有想象力,你就可以把它变成你想要的任何东西。
;程序的使用方法是:
;1.新建一个文本文件(setup.asm)把上面的程序拷贝到进去,保存
;2.用masm和link编译成.exe 文件。执行masm setup.asm;命令和link setup.obj;命令,生成的可执行文件名为setup.exe
;3.将软盘插入软驱,双击setup.exe程序运行,这样你就有了一张引导盘了
;4.重起系统,从软驱启动,你就会在屏幕上显示一大串‘a',这就是我们的杰作!


assume cs:code
;用来生成一个引导盘
;即把引导程序(boot)加载到软盘的第一个分区
code segment
main:
    mov    ah,3        ;3号功能是写,2号是读
    mov     al,1        ;扇区数
    mov    ch,0        ;磁道号
    mov    cl,1        ;起始的扇区号
    mov    dh,0        ;磁头号
    mov     dl,1        ;驱动器号,这里用的是B:盘,如果是A: 则是 mov dl,0
    
    mov    bx,cs
    mov     es,bx
    mov    bx,offset boot            ;es:bx指向i/o缓冲地址
    mov     byte ptr es:[bx + 510],55h    ;有效标识
    mov    byte ptr es:[bx + 511],0aah

    int     13h        ;bios磁盘存取功能
ret:
    mov     ax,4c00h    
    int     21h
;下面的是系统的引导程序
;他在软盘的第一个扇区中
;pc加点时它被加载到0x7c00h
boot:
    mov    bx,0b800h
    mov    es,bx
    mov    bx,100
    mov    cx,100h
s:    mov    byte ptr es:[bx],'a'
    add    bx,2h
    loop    s
    
code ends
 

你可能感兴趣的:(关于boot loader装载程序的学习纪录)