[原创]操作系统编写详解<二>

[原创]操作系统编写详解
2010年08月09日
  前一篇文章中我们学习了写引导程序,可是,引导程序大小不能超过512B,将运行代码写到引导程序里并不是不行,但是大小限制会让你的操作系统异常的"精简"
  所以一般的操作系统(包括Linux)都是使用一种叫二次加载的方法,也就是写一个及其简单的Boot引导程序,它只做两件事:一是初始化段寄存器(mov ds,ax....),二是从软盘第二扇区读入真正的内核加载到内存指定位置并用1个Jmp跳转到指定位置并执行内核
  到回来看看Linux,Linux0.11的Boot文件夹里有Boot.s与Head.s,boot.s的作用就是引导,并跳转至Head,Head才开始进入保护模式,最后跳转至Main.c(init/main.c,当然以编译为.o,并以链接到Tool/System)的,下面是一部分的Linux0.11 Makefile代码
  Image: boot/boot tools/system tools/build
  tools/build boot/boot tools/system > Image
  sync
  boot/head.o: boot/head.s
  tools/system:boot/head.o init/main.o \
  $(ARCHIVES) $(LIBS)
  $(LD) $(LDFLAGS) boot/head.o init/main.o \
  $(ARCHIVES) \
  $(LIBS) \
  -o tools/system > System.map
  boot/boot:boot/boot.s tools/system
  (echo -n "SYSSIZE = (";ls -l tools/system | grep system \
  | cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s
  cat boot/boot.s >> tmp.s
  $(AS86) -o boot/boot.o tmp.s
  rm -f tmp.s
  $(LD86) -s -o boot/boot boot/boot.o
  可以看到head.o与main.o被链接到tool/system,而boot只是负责引导,经过一连的Jmp之后,main函数开始初始化并运行Kernel,这就是二次加载
  考虑下面的程序代码
  ;boot.asm
  [ORG 0]
  jmp 07c0h:start
  start:
  ;设置段寄存器
  mov ax,cs
  mov ds,ax
  mov es,ax
  reset: ;重置软盘驱动器
  mov ax,0
  mov dl,0 ;Driver=0(=A)
  int 31h
  jc reset ;if error reset again
  read:
  mov ax,1000h ;ES:BX=1000:0000
  mov es,ax
  mov bx,0
  mov ah,2 ;读取磁盘数据到地址ES:BX
  mov al,5 ;读取5个扇区
  mov ch,0 ;柱面0
  mov cl,2 ;第二扇区,即为读入文件所在扇区
  mov dh,0 ;Head=0
  mov dl,0 ;Driver=0
  int 13h ;开始读
  jc read ;if error try again
  jmp 1000h:0000 ;跳转到装载的程序处开始执行
  times 510-($-$$) db 0
  dw 0AA55h ;结束标志
  ;Kernel.asm
  [ORG 0]
  jmp start2
  msg db 'Here is Xue s Operating System!OK,Here we go',$0 ;打印字符串定义
  start2:
  ;设置段寄存器
  mov ax,cs
  mov ds,ax
  mov es,ax
  mov si,msg
  print:
  lodsb
  cmp al,0 ;al为0?
  je hang ;if al=0 then 挂起
  mov ah,0Eh ;打印
  mov bx,7
  int 10h
  jmp print ;打印下一字符
  hang:
  jmp hang ;挂起,即无限循环
  times 510-($-$$) db 0
  dw 0AA55h ;结束标志
  编译
  nasm boot.asm -o boot.bin
  nasm kernel.asm -o kernel.bin
  可以发现,boot.bin在引导后,就从软盘第二扇区将Kernel.bin读取并装入内存,接下来跳转并执行Kernel.bin,而Kernel.bin便在屏幕上打印一字符串
  在这里要用到一个特殊工具:Partcopy 它能将文件写入软盘映像指定位置
  available at:http://newworklife.spaces.live.com/blog/cns!27EB11C0372B9EB1!348.entry
  编译好两个bin后,就要将它们写入磁盘
  用法
  partcopy boot.bin 0 200 floppy.img 0
  partcopy kernel.bin 0 200 floppy.img 200
  运行后,会发现当前目录多了个floppy.img,那正是我们需要的软盘映像文件
  我们还需要一个软件:Bochs
  这是个虚拟机,不用Vitrual Box是因为它引导软盘映像的成功率低
  available at:http://sourceforge.net/projects/bochs/
  它需要一个Bochsrc.bxrc文件作为配置
  在floppy.img同目录下创建一个Bochsrc.bxrc
  右键->编辑,写入
  ###############################################################
  # bochsrc.bxrc file for Xue's OS
  #(c)copyright xuejin 2010
  #All right reserved
  ###############################################################
  megs: 32
  romimage: file=$BXSHARE/BIOS-bochs-latest
  floppya: 1_44=C:\FLOPPY.IMG, status=inserted
  boot: a
  log: bochsout.txt
  mouse: enabled=0
  keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-us.map
  保存,然后运行,
  
  
  
  我们会发现Here is Xue s Operating System!OK,Here we go已被打印出来,说明二次装载成功了,ye~~~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值