操作系统引导Boot的初步实现

来源:互联网 发布:如何修复缺少网络协议 编辑:程序博客网 时间:2024/05/16 10:42
    那天,大圣问我:你这个操作系统系统能跑起来了吗?我一愣,想想,好久了,我的工作都是围绕着内核设计的。写线程,消息什么的。这次决定改变方向,先得让它跑起来呀,不然,一切工作都是徒劳。恩恩,这貌似符合于渊的风格。
    编程语言:AT&T汇编;编译器:as;环境:Linux。
    顺便说下,AT&T汇编的文法很奇怪,而且有失简洁,至于和Intel汇编的具体区别嘛,自己百度,主要怕误导大家。有的人可能会问:为什么不用nasm,Intel汇编多简单。这里,因为历史原因,GUN编译器只支持AT&T汇编,在C语言中又时不时的会嵌入几句汇编,一个工程中使用两种风格不同的汇编,有点不恰当。就请大家暂且忍受下这晦涩的汇编,特别是这鬼AT&T汇编。
    题外话,我写这个小boot程序竟花了我2个多小时,效率有待提高啊。写这个boot时,我借鉴了下谢昱波的代码,Linus的代码,于渊的代码,我在这里向3位前辈致敬了!

    直接贴代码了,注释很齐全,虽然有点罗嗦,但有利于新手理解学习,还是值得的。 我写代码就是这样,轰轰烈烈的。

/*=============================================================== *                       boot.s *启动扇区代码 ===============================================================*/.global _start.code16/************************************************************************//*                          主函数/*                          start/************************************************************************/jmp_start.org 128/* 预留128字节的空间,用于存放分区表什么的 */_start:/* 保存启动驱动器 */mov %dl,(boot_drive)/* 初始化段寄存器及堆栈指针 */mov %cs, %axmov %ax, %dsmov %ax, %ssmov $stack_top, %sp/* 显存段es */mov $0xb800, %bxmov %bx, %es/* 调用cls清屏 */call cls/* 调用disp_str显示字符串 */call disp_str/* 读取loader */call read_loader/* 死循环 */#loop: jmp loopljmp $0,$Loader_OffsetAddr/************************************************************************//*                          清屏/*                          cls/************************************************************************/cls:mov$0, %ax/* 空字符 */mov$2000, %cx/* 循环2000次 */xor%di, %di/* 对di清0 */_cls_loop:mov%ax, %es:(%di)/* 写入 */add$2, %di/* 指向下一个空间 */dec%cx/* 循环计数器减1 */test    %cx, %cx/* 测试是否为0 */jnz_cls_loop_cls_end:ret/************************************************************************//*                      在屏幕上显示字符串/*                         disp_str/************************************************************************/disp_str:mov$boot_msg, %si/* 字符串地址 */mov$0x0f, %ah      /* 黑底白字 */xor%di, %di/* 对di清0 */_disp_str_loop:lodsb/* (C)al=*si;si++; */test%al, %al/* 测试是否为0 */jz_disp_str_end/* 为0则结束 */mov%ax, %es:(%di)/* 写入 */add$2,  %di/* di+2*/jmp_disp_str_loop/* 进入下一次循环 */_disp_str_end:ret/************************************************************************//*                      读取loader/*                     read_loader/************************************************************************/Loader_Start        =2Loader_End=3Loader_Size=Loader_End - Loader_Start + 1Loader_BaseAddr        =0Loader_OffsetAddr=0x8000read_loader:mov $Loader_BaseAddr,%ax/* 段基址 */mov%ax,%esmov$Loader_OffsetAddr,%bx/* 偏移量 */mov $2, %ah/* 中断功能号 */mov(boot_drive), %dl/* 驱动器 */mov$0,%dh/* 磁头号 */mov$0, %ch/* 柱面 */mov$Loader_Start,%cl/* 起始扇区 */mov$Loader_Size,%al/* 扇区数 */int$0x13/* 调用中断*/jcread_loader/* 检测错误 */ret/************************************************************************//*                         数据区/*                          data/************************************************************************/boot_msg:.ascii"Booting..."boot_drive:.byte0free_space:.org0x200-0x2stack_top:.word0xAA55

Makefile

.PHONY: allall:    as boot.s -o boot.o    ld boot.o -Ttext 0x7c00 --oformat=binary -Map boot.map -o boot.bin    dd if=boot.bin of=boot.img bs=512 count=1 conv=notrunc

bochsrc

################################################################ Configuration file for Bochs###############################################################megs: 32romimage: file=/usr/share/bochs/bios/BIOS-bochs-latestvgaromimage: file=/usr/share/vgabios/vgabios.binfloppya: 1_44=boot.img, status=insertedboot: akeyboard_mapping: enabled=1, map=/usr/share/bochs/gui/keymaps/x11-pc-us.map

三个文件放在同一个目录下,下载boot.img,放在同一目录。
终端输入make
然后输入bochs
之后回车
在然后输入c后回车
就看到结果了。!!^_^非常兴奋!!