不要问我为什么要做一个操作系统
有人会说你,作为一个初中生写操作系统做甚,我也不知道,但自从读了《三十天自制操作系统》自己上手写了之后就停不下来了,并且还立志将它做成一个应用级别的操作系统即支持PCI驱动,USB的U盘驱动也有可能会写hub的驱动,支持一些早期网卡,支持uefi快速启动,并编译一个该系统能运行的GCC)
我将一步步将这个操作系统从16位实模式转到IA32E的64位长模式,当然这个操作系统不会是仅仅学习前者的知识更会有不少创新(包括bug上的创新,所以如果有bug就在下头留言)
那么开始正文
由于目前edkii的开发资料较少所以我还是先打算从传统启动开始写
这里我不打算使用传统的FAT文件系统进行开发,我准备自创一种粗暴的文件系统来储存loader,我他管它叫OFS(One File`s System),故名思议只是给一个文件做的文件系统具体怎么玩呢,看图
是的,按每个扇区512字节来算尾部有8字节偏移,偏移为0xffffffff(实际上是0xffffffffffffffff,但是16位下只能使用32位宽的寄存器,姑且算它是0xffffffff)时文件结束,同时由图你也马上明白做这个文件系统的主要目的是防止存储时介质坏块导致的文件存储不完整,不然的话我造就用dd指令一考,之后在引导程序里添上文件大小马上就能把loader加载到内存
这个文件系统还是有一点点优点的比方说在只存储一个文件时甚至可以不限制文件大小(前提是磁盘的寻扇区能力够强),当然出现PB级别的特大坏块时该文件系统也无能为力(要真的有这样的盘估计早扔了),同时用这个文件系统进行加载写程序特别方便每加载一个扇区就将section++之后在addr后加504粗暴简单,那么上代码吧!
;/./Boot/ofs.inc/ load_file: call LoadASec mov ax,[addr_of_buf_off] add ax,504 ;向后偏移504字节 jno continue_add ;执行到这里说明ax+504后溢出了,给段的位置+1 mov bx,[addr_of_buf_seg] inc bx mov [addr_of_buf_seg],bx continue_add: mov [addr_of_buf_off],ax ;保存回去 mov bx,[addr_of_buf_seg] mov ds,bx mov bp,ax mov ebx,[ds:bp] ;获取偏移扇区数 cmp ebx,0xffffffff ;已经到达文件尾 je vret mov ecx,[first_sec] ;获取首扇区 add ecx,ebx ;偏移到下一个扇区 mov [first_sec],ecx ;同样保存回去 jmp load_file
上面还有一些变量将会在disk.inc里定义,上代码
;/./Boot/disk.inc DISK_PACK_ST: size_of_pack db 10h unkown_val db 0 num_of_sec dw 1 addr_of_buf_off dw 0 addr_of_buf_seg dw 0 first_sec dq 0 DISK_PACK_SP: LoadASec: mov dl,80h ;选择你的英雄:/U盘(80h)/硬盘(80h/81h)按你的启动项选如果是USB_HDD就选0x80 xor ax,ax mov ds,ax mov si,DISK_PACK_ST mov ah,42h int 13h jnc vret mov cx,size_disk_err mov bl,red mov bp,str_disk_err call print jmp sys_halt str_disk_err db "Disk Error!" size_disk_err equ $ - str_disk_err - 1
至于print和sys_halt这种简单的东西之后在我传在百度网盘的代码里翻一番就能找到我就不多说了
下一篇来讲loader如何16位到64位(都是些简单的东西)
(实际上已经写到了内存分配和PCI驱动了可以自己翻代码看,当然还没写完就是...)
*tips:不要尝试直接编译,先把Makefile里的DISP和DISN改掉不然有可能会把/dev/sdd这个盘给毁掉,自然这个程序要在linux中编译(最好是ubuntu)
环境的搭建会在第0章(不要问为什么先写1再写0)提及
源码的下载地址:
链接: https://pan.baidu.com/s/1bPH5Ztcujk82zyoHWeRx4w 提取码: 28ni
以后源码可能会放在github上



