从0开始写内核(二)MBR小试

参考书籍:操作系统真相还原

源码:https://github.com/wutiaojian000/AFKernel.git
本文地址:https://www.cnblogs.com/angel-fish/p/18798903

0. 基础知识

这里只贴一张实模式下的内存布局供以后查看

1. MBR

1.1 代码

这里我就直接从MBR开始了

;主引导程序
SECTION MBR vstart=0x7c00
  mov ax, cs
  mov ds, ax
  mov es, ax
  mov ss, ax
  mov fs, ax
  mov sp, 0x7c00

; 清屏利用0x06号功能,上卷全部行即可清屏
; INT 0x10 功能号:0x06 上卷窗口
; 输入:
; AH:功能号=0x06
; AL:上卷的行数,0表示全部
; BH:上卷行属性
; (CL,CH)=窗口左上角(X,Y)位置
; (DL,DH)=窗口右下角(X,Y)位置
; 无返回值
  mov ax, 0x600
  mov bx, 0x700
  mov cx, 0       ;(0, 0)
  mov dx, 0x184f  ;(80,25)

  int 0x10

; 获取光标位置
  mov ah, 3  ;3号子功能是获取光标位置
  mov bh, 0  ;待获取光标的页号

  int 0x10   ;输出:ch=光标开始行,cl=光标结束行,dh=光标所在行号,dl=光标所在列号

; 打印字符串 使用0x13功能号
  mov ax, message
  mov bp, ax

  mov cx, 5       ;串长度,不包括'\0'
  mov ax, 0x1301  ;0x13为功能号,0x01表示显示字符串,光标跟随移动
  mov bx, 0x02    ;bh存储要显示的页号,这里是0,bl是字符属性,0x02表示黑底绿字

  int 0x10

  jmp $  ;程序悬停在这里

  message db "1 MBR"
  times 510-($-$$) db 0
  db 0x55, 0xaa

像ds,es,fs,gs这些sreg,cpu是没有办法直接赋值的,需要通过通用寄存器来间接赋值。开头的位置使用cs来初始化了这些段寄存器。
mov sp, 0x7c00是初始化栈指针,mbr也是程序,当然也要有栈结构。0x7c00以下的地址可以看成是安全的。
然后是清屏和打印,打印需要先确定光标的位置,然后在光标的位置处打印(打印的位置可以不在光标位置上。。。)。
从代码中可以看到获取光标是有一个页的概念,在文本模式下默认一屏是80*25,2000个字符,每个字符一字节表示ASCII码,另一字节表示字符属性,所以一共4000字节,实际上分配给一屏的是4kb,这一屏就成为一页,0页是默认页。
打印字符的功能号0x13,al寄存器低2位才有意义:
(1)al=0,显示字符串,光标回到起始位置;
(2)al=1,显示字符串,光标追随到新位置;
(3)al=2,显示字符串及其属性,光标回到起始位置;
(4)al=3,显示字符串及其属性,光标追随到新位置。
jmp \(为跳转到当前指令所在地址,就是循环跳回到自己。 times 510-(\)-$$) db 0:(\(-\)\()是当前行到section的偏移,512 - 2 - (\)-$$)为本扇区需要填充的0的个数。

1.2 编译

(记得先安装nasm)

nasm -o mbr.bin mbr.S


确实是512字节。

1.3 写入扇区

这里需要用到dd指令
man dd

bs=BYTES
              read  and  write  up  to  BYTES bytes at a time (default: 512);
              overrides ibs and obs
count=N
              copy only N input blocks
conv=CONVS
              convert the file as per the comma separated symbol list
if=FILE
              read from FILE instead of stdin
of=FILE
              write to FILE instead of stdout
seek=N skip N obs-sized blocks at start of output
append append  mode  (makes  sense  only for output; conv=notrunc sug‐
              gested)
dd if=mbr.bin of=/home/zcm/bochs/hd60M.img bs=512 count=1 conv=notrunc


成功!

posted @ 2025-03-29 16:01  横渡大海的神仙鱼  阅读(34)  评论(0)    收藏  举报