转载:自制操作系统

制作真正的操作系统
太繁琐?看看 https://github.com/HelloOSMe/RealOS ,可能和图片显示的开机信息不一样。
这是我照着原文编写的。
转载自洛谷,洛谷博客原链接失效,现在放上他的备份的转载

-1.写在开始之前

虽然网上此类教程云集,虽然此类书籍很多,但是!

这些书籍有很多地方讲得不够细致(主要是代码有缺漏),有些对代码的更改甚至在书中了无痕迹。

而这才是我开启这篇教程的原因。

这篇教程之中,只要照着所有的操作做了一遍,以您 wikidoter 的水平,应当能够写出完整的操作系统!

不过,与其说这篇文章是个教程,倒不如说是一个学习笔记和我自身编程经验的记录。

0.开发环境配置

如果您使用的是 Linux,我们只需要输入下面一行命令即可完成开发环境的配置:

sudo apt-get install nasm build-essential qemu-system-x86

如果您使用的 Linux 中不含有 apt 系列包管理器,请使用您系统中的包管理器。

如果您使用的是 Linux,但您的系统内没有包管理器,那么您可以去 nasm 官网、 gcc 官网和 qemu 官网下载源码,然后 configure -> make -> sudo make install。

如果您使用的是 Windows,请获取所需要的工具:

nasm
交叉编译的gcc(请下载i686-elf-tools-windows.zip)
qemu
make
dd
bochs(其实我们只需要其中的 bximage.exe )(如果是 32 位电脑请下载 2.5 以前的版本)

如果您使用的是 macOS,那么请注意,系统内置的 gcc 会把文件编译成 Mach-O 格式,请通过 Homebrew 下载交叉编译器:

sudo brew install i386-elf-binutils
sudo brew install i386-elf-gcc

然后我们还需要去往NASM官网获取可执行文件,并执行:

sudo brew install qemu

获取 qemu

在安装完之后,如果您使用的是 Windows,请确保它们的路径位于 PATH 下!

除此之外便没什么重点了,不过,对于下文给出的工具名称默认以 Windows 为准,若您使用 Linux,请去掉工具前缀,若您使用 macOS,请将工具前缀中的 i686 改为 i386!!!

对了,如果您使用的是 Linux 或 macOS,请确保您在 dd 命令的后面加入 conv=notrunc !!!

那么,开发环境配置正式结束,征程开始!

1.引导扇区

所谓引导扇区,其实就是一段可执行的代码而已,不过加入了一个小限制:编译后的总字节数不能超过 512,同时扇区最后两个字节必须是55 AA

虽然现在看来这个限制并不怎样,但一到后面再回过头来,您将会发现这是一个非常恶心的限制。不过没关系,对于现在的我们来说,这个限制并不大。

那么我们的目标就是用 BIOS 中断int 10h,往屏幕上输出信息,具体用法如下:

AH=13h:输出信息

BH=页码(一般可以置0)

BL=属性(当al=0或1)

(DH, DL):行和列

ES:BP:字符串地址

AL=输出方式

AL=0:仅含显示字符,字符属性(颜色等)位于 BL 中。显示后,光标位置不变。

AL=1:同 AL=0,但显示后光标位置改变。

AL=2:字符串中含有显示字符和显示属性。显示后,光标位置不变。

AL=3:同 AL=2,但显示后光标位置改变。

那么此次我们要使用的就是 AH=13h AL=01h 的显示方法,即显示字符串后光标移动

知道怎么显示字符串,代码也就好写了:

代码 1-1 最简单的引导扇区(boot.asm)

    org 07c00h ; 告诉编译器程序将装载至0x7c00处

    mov ax, cs
    mov ds, ax
    mov es, ax ; 将ds es设置为cs的值(因为此时字符串存在代码段内)
    call DispStr ; 显示字符函数
    jmp $ ; 死循环

DispStr:
    mov ax, BootMessage
    mov bp, ax ; es前面设置过了,所以此处的bp就是串地址
    mov cx, 16 ; 字符串长度
    mov ax, 01301h ; 显示模式
    mov bx, 000ch ; 显示属性
    mov dl, 0 ; 显示坐标(这里只设置列因为行固定是0)
    int 10h ; 显示
    ret

BootMessage: db "Hello, OS world!"
times 510 - ($ - $$) db 0
db 0x55, 0xaa ; 确保最后两个字节是0x55AA

程序写好了,我们该怎么运行呢?首先编译一下:

nasm boot.asm -o boot.bin

对于 Linux 和 macOS 用户而言,只需要下面两行命令就可以完成软盘映像的创建与写入:
dd if=/dev/zero of=a.img bs=512 count=2880
dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc

如果您使用的是 Windows,那么请执行 bximage。下面是使用 bximage 创建软盘映像的实例:
> bximage
========================================================================
                                bximage
                  Disk Image Creation Tool for Bochs
        $Id: bximage.c,v 1.34 2009/04/14 09:45:22 sshwarts Exp $
========================================================================

Do you want to create a floppy disk image or a hard disk image?
Please type hd or fd. [hd] fd

Choose the size of floppy disk image to create, in megabytes.
Please type 0.16, 0.18, 0.32, 0.36, 0.72, 1.2, 1.44, 1.68, 1.72, or 2.88. [1.44]

I will create a floppy image with
  heads=2
  sectors per track=18
  total sectors=2880
  total bytes=1474560

What should I name the image? [a.img]

Writing: [] Done.

I wrote 1474560 bytes to a.img.

The following line should appear in your bochsrc:
  floppya: image="a.img", status=inserted
(The line is stored in your windows clipborad, use CTRL-V to paste)

Press any key to continue
>

硬盘镜像制作完成之后,我们再执行一条写入命令:
dd if=boot.bin of=a.img bs=512 count=1

注意,Windows 下的 dd 不支持 conv 选项。

另外,如果您的 boot.bin 被报毒 KillMBR,请不要惊慌,因为它就是一个 MBR,因此被判为覆盖 MBR 的病毒非常正常,默认不做操作即可。

无论是上述哪种情况,在制作完成之后,直接执行一行命令来执行:

qemu-system-i386 -fda a.img

如果您的执行结果如下图,那么恭喜您,您的引导扇区成功执行了!mg4exw5o.png

搬运自 https://www.cnblogs.com/yet-another-cnblogs-blog/articles/16818235.html


讨论区

新回复
© 地下黑市
2020~2026
属于闲人的社区
萌ICP备20240682号