| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 14935 人关注过本帖, 4 人收藏
标题:编写操作系统?有趣:第一天
只看楼主 加入收藏
AXRZ
Rank: 2
等 级:论坛游民
威 望:5
帖 子:48
专家分:84
注 册:2016-3-23
收藏(4)
 问题点数:0 回复次数:23 
编写操作系统?有趣:第一天
直接进入正题,再考虑过操作系统的具体的功能分块后,第一件需要考虑的事情就是引导扇区了。引导扇区位于硬盘的0磁头,0柱面上的第一个扇区,并由电脑在开启电源,完成BIOS自检后加载到内存并执行,我们现在并不需要过多了解BIOS自检时的过程(因为这对于编写操作系统来说没什么意义),但我们需要了解一下关于引导扇区的知识点:

-引导扇区的最后两个字节必须为55H,AAH,这两字节为BIOS检查该硬盘是否为可引导硬盘的唯一条件。若硬盘最后这两个字节不为此,则BIOS将视其为不可引导硬盘

-引导扇区由BIOS加载到内存地址0000:7C00处,因此在设置编译器是必须将程序的偏移设为0x7C00

-引导扇区的长度只能为一个扇区(512字节),这个限制虽然非常不人性,但是足够引导操作系统的加载程序

-在引导扇区被加载到内存后,DL寄存器中将存放目前硬盘(引导的硬盘),这可以用来进行后面对操作系统硬盘的读写

此外关于硬件中断的内容我们在写操作系统本身时再提及

 

那么了解了基本的知识点后,我们正式开始编写引导扇区的代码。在这里,你需要的工具有(推荐):

-Disk Explorer for NTF-下载地址:https://www.        ;用于对IMG文件进行读写(这个软件我之后会破解)本文暂时不需要

-NASM-下载地址:http://www.nasm.us/pub/nasm/releasebuilds/2.12/nasm-2.12.zip        ;  用于编译汇编语言

-BOCHS-下载地址:https://

-任何文本编辑器,这里推荐NOTEPAD++

 

以下是BOOTLOADER.ASM(引导程序)的代码
ORG 7C00H

ENTRY:
    XOR BX,BX
    MOV DS,BX
    MOV SS,BX
    MOV ES,BX
    MOV BP,0FFFFH
    MOV SP,BP
    MOV [DriveNumber],DL
CHECKOSDISK:
    MOV SI,CODMessage0
    CALL WRITESTRING
    CALL RESETDRIVE
    MOV BX,513
    MOV CX,1
    MOV AL,1
    CALL READSECTOR
    JC CODERROR
    CMP BYTE [BX+508],42H
    JNE CODERROR
    CMP BYTE [BX+509],5AH
    JE CODNEXT
CODERROR:
    MOV SI,CODErrorMsg
    CALL WRITESTRING
    JMP ENDDELAY
CODNEXT:
    MOV SI,CODOKMessage
    CALL WRITESTRING
LOADOSMAIN:
    MOV SI,LOMessage
    CALL RESETDRIVE
    CALL WRITESTRING
    MOV BX,[OSMEntryOffset]
    MOV CX,2
    MOV AL,[OSMSectorCount]
    CALL READSECTOR
    JNC JUMPOSMAIN
LOMERROR:
    MOV SI,LOMErrorMsg
    CALL WRITESTRING
    JMP ENDDELAY
JUMPOSMAIN:
    MOV SP,BP
    JMP FAR [OSMEntryAddress]
ENDDELAY:
    MOV SI,EDMessage
    CALL WRITESTRING
    JMP $

WRITECHAR:                                ;AL = Character ASCII
    PUSH BX
    PUSH AX
    MOV BX,0FH
    MOV AH,0EH
    INT 10H
    POP AX
    POP BX
    RETN

WRITESTRING:                            ;DS:SI = Address Of String
    PUSH AX
WSLOOP:
    CLD
    LODSB
    TEST AL,AL
    JZ WSRET
    CALL WRITECHAR
    JMP WSLOOP
WSRET:
    POP AX
    RETN

WRITEHEXNUM:                            ;AX = Hex Number To Output
    PUSHAW
    CLD
    MOV CL,16
    MOV DX,AX
    MOV DI,HexNumTable
WHLOOP:
    MOV AX,DX
    MOV SI,DI
    SUB CL,4
    JZ WHNEXT
    SHR AX,CL
WHNEXT:
    AND AX,0000000000001111B
    ADD SI,AX
    LODSB
    CALL WRITECHAR
    TEST CL,CL
    JNZ WHLOOP
    POPAW
    RETN

WRAPTEXT:
    MOV AL,0DH
    CALL WRITECHAR
    MOV AL,0AH
    CALL WRITECHAR
    RETN

RESETDRIVE:                                ;DL = Drive Number
    XOR AH,AH
    INT 13H
    RETN                                ;Succeed: CF = 0, AH = 0; Failed: CF = 1, AH = Error Code

READSECTOR:                                ;AL = Number Of Sectors To Read, CH = Low 8 Bits Of Cylinder Number, CL = Sector Number(Bit 0-5) High 2 Bits Of Cylinder Number, DH = Head Number, DL = Drive Number, ES:BX = Address Of Buffer
    PUSH BP
    PUSH 2
    MOV BP,SP
RSLOOP:
    PUSHAW
    MOV AH,2
    INT 13H
    JNC RSRET
RSRETRY:
    DEC WORD [BP]
    POPAW
    JNZ RSLOOP
RSRET:
    ADD SP,18
    POP BP
    RETN                                ;Succeed: CF = 0, AH = 0, AL = Number Of Sectors Transferred; Failed: CF = 1, AH = Error Code

WRITESECTOR:                            ;AL = Number Of Sectors To Write, CH = Low 8 Bits Of Cylinder Number, CL = Sector Number(Bit 0-5) High 2 Bits Of Cylinder Number, DH = Head Number, DL = Drive Number, ES:BX = Address Of Buffer
    PUSH BP
    PUSH 2
    MOV BP,SP
WSELOOP:
    PUSHAW
    MOV AH,3
    INT 13H
    JNC WSERET
WSERETRY:
    DEC WORD [BP]
    POPAW
    JNZ WSELOOP
WSERET:
    ADD SP,18
    POP BP
    RETN                                ;Succeed: CF = 0, AH = 0, AL = Number Of Sectors Transferred; Failed: CF = 1, AH = Error Code

DriveInfo:
DriveNumber:
    DB 0
MaxCylinderNum:
    DW 0
MaxSectorNum:
    DB 0
MaxHeadNum:
    DB 0

OSMainInfo:
OSMEntryOffset:
    DW 7E00H
OSMSectorCount:
    DB 4
OSMEntryAddress:
    DD 07E00000H
   

Tables:
CharTable:
    DB "ABCDEFGHIJKLMNOPQRSTUVWXYZ",0
HexNumTable:
    DB "0123456789ABCDEF",0

Strings:
EDMessage:
    DB "SYSTEM PENDING...",0DH,0AH,0
CODMessage0:
    DB "CHECKING OS DRIVE...",0DH,0AH,0
CODOKMessage:
    DB "OS DRIVE IS NORMAL.",0DH,0AH,0
LOMessage:
    DB "LOADING OS MAIN, SYSTEM KERNEL...",0DH,0AH,0
CODErrorMsg:
    DB "ERROR: CURRENT DRIVE UNAVAILABLE.",0DH,0AH,0
LOMErrorMsg:
    DB "ERROR: OS MAIN LOAD FAILED.",0DH,0AH,0


BootSectSignature:
    TIMES 508-($-$$) DB 0
    DB 42H,5AH
    DB 55H,0AAH

 


如上代码是我编写的引导扇区,其中包括一些有必要的子程序和一些可扩展用的子程序,若部分子程序不需要可以去除。

将如上代码保存为.ASM文件后,我们用命令行(在NASM文件的文件夹里SHIFT加右键鼠标并选择“OPEN COMMAND WINDOWS HERE“)打开NASM并输入命令行:

nasm -f bin -o [路径/目标文件名] [路径/源代码文件名]

在这里,我输入

nasm -f bin -o BOOTLOADER.IMG BOOTLOADER.ASM

若没有不编译错误,则生成目标文件



随后我们运行位于BOCHS文件夹下的BOCHSDBG来调试我们的引导扇区

首先设置硬盘与引导,选择Disk & Boot, 并在新弹出的窗口中我们使用如下设置一下虚拟镜像:将只需将"Type of Floppy Media"设置成1.44M,然后将映象的路径添加到"First floppy image/device",并把"Type of Floppy Media"也设置为1.44M,最后把"Status"设置为"inserted"即可

在保存设置(保存至BOCHS目录下)后我们就可以点击start来开始调试了

 

开始调试后会弹出两个窗口,可以输入命令行的窗口是调试窗口,以及另一个是引导程序输出的窗口

我们首先往调试窗口中输入“b 0x7C00",在偏移0x7C00处放下一个断点

然后我们输入两次“c”来继续(一次是BOCHS加载程序后挂起用,一次是遇上了断点来继续程序)



可以看到输出窗口处成功的输出了我们引导程序的信息,但是输出后似乎挂起了,原因是我的代码内最后一条引导程序里的指令是JMP FAR [OSENADDR](意义是跳转至07E0:0000处,因为[OSENADDR]为07E00000),一条跳转至主操作系统的程序代码,但是我们还没有编写出主操作系统,其在我们的IMG镜像文件中是不存在的,所以0x7E00处是没有代码的。

-查看更多BOCHS调试命令行:http://

 

当然有兴趣的朋友可以自己试着编写自己的子程序和完全属于自己的操作系统,我在这里为你们提供:
-实模式内存布局(全英文):http://wiki.(x86)

-BIOS中断大全查询的网址(全英文):http://www.

了解硬件I/O的朋友可以在以下网址查询到各个I/O端口:

-硬件I/O端口大全(全英文):http://bochs.

另外,可以将NASM编译器的文件夹添加到系统环境目录的PATH项下,这样以后无论在哪个目录打开命令行,都可以运行NASM编译器。


以下为各个文件的备用下载地址:
-WinHex(代替NtExplorer)-下载地址:
WINHEXSETUP.zip (1.29 MB)


-NASM-下载地址:
NASMSETUP.zip (2.67 MB)


-BOCHS-下载地址:
BOCHSSETUP.zip (4.59 MB)


-NotePad++-下载地址:
NOTEPADPPSETUP.zip (3.57 MB)


-BOOTLOADER.ASM和BOOTLOADER.IMG-下载地址:
bf.zip (2.18 KB)


[此贴子已经被作者于2016-5-8 02:55编辑过]

搜索更多相关主题的帖子: 电源 知识点 操作系统 
2016-03-23 12:33
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
很久前研究过这些的,真的是没日没夜。现在年纪大了,没那个冲劲了。
小朋友,挺你一下,加油

能编个毛线衣吗?
2016-03-25 13:56
AXRZ
Rank: 2
等 级:论坛游民
威 望:5
帖 子:48
专家分:84
注 册:2016-3-23
收藏
得分:0 
有谁知道从单线程进入多线程的具体方法吗?
在网上翻了个遍,但是始终没找到关于操作系统通过修改APIC来进入多线程模式的信息
2016-03-27 23:39
zhulei1978
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:53
帖 子:1351
专家分:1200
注 册:2006-12-17
收藏
得分:0 
NASM的语法与MASM语法是不是有不同

其实我就是改变社会风气,提高少女素质,刺激电影市道,提高年轻人内涵,玉树临风,风度翩翩的整蛊专家,我名叫古晶,英文名叫JingKoo!
2016-04-12 06:15
zhulei1978
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:53
帖 子:1351
专家分:1200
注 册:2006-12-17
收藏
得分:0 
请问那个LODSB指令是做什么用的

其实我就是改变社会风气,提高少女素质,刺激电影市道,提高年轻人内涵,玉树临风,风度翩翩的整蛊专家,我名叫古晶,英文名叫JingKoo!
2016-04-12 06:21
zhulei1978
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:53
帖 子:1351
专家分:1200
注 册:2006-12-17
收藏
得分:0 
我查了一下书,LODS是从串取指令

其实我就是改变社会风气,提高少女素质,刺激电影市道,提高年轻人内涵,玉树临风,风度翩翩的整蛊专家,我名叫古晶,英文名叫JingKoo!
2016-04-12 06:42
zhulei1978
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:53
帖 子:1351
专家分:1200
注 册:2006-12-17
收藏
得分:0 
它那个数据段式定义在最后的么,我看的书不是这样的

其实我就是改变社会风气,提高少女素质,刺激电影市道,提高年轻人内涵,玉树临风,风度翩翩的整蛊专家,我名叫古晶,英文名叫JingKoo!
2016-04-12 07:21
AXRZ
Rank: 2
等 级:论坛游民
威 望:5
帖 子:48
专家分:84
注 册:2016-3-23
收藏
得分:0 
回复 7楼 zhulei1978
数据段定义的话看个人(有些编译器一定要你定义在代码段前面),一般来讲操作系统的引导扇区前三个字节是一个JMP NEAR的指令,跳开数据段。但是我比较倾向与这样写,个人喜好。

另外,数据和代码实际上是没有区别的(在内存中都是一样的储存方式),你在代码中间插一段数据段都是可以的。

NASM的语法和MASM确实有些许不同,编写操作系统不推荐MASM。我更喜欢NASM,因为比较倾向与纯正的汇编。
语法常用的不同点:
1. 段寄存器运用    MASM: MOV DS:[BX],AX    NASM: MOV [DS:BX],AX
2. 数据类型标明    MASM: MOV WORD PTR [BX],1234    NASM MOV WORD [BX],1234
3. 没有OFFSET!     MASM: MOV AX,OFFSET [DATA]    NASM:MOV AX,DATA
其他的不同都是少用的,更多语法转换: http://

[此贴子已经被作者于2016-4-29 07:44编辑过]

2016-04-12 11:37
zhulei1978
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:53
帖 子:1351
专家分:1200
注 册:2006-12-17
收藏
得分:0 
你在代码中间插一段数据段都是可以的

 那样的话逻辑上不会混乱吗

其实我就是改变社会风气,提高少女素质,刺激电影市道,提高年轻人内涵,玉树临风,风度翩翩的整蛊专家,我名叫古晶,英文名叫JingKoo!
2016-04-12 13:33
AXRZ
Rank: 2
等 级:论坛游民
威 望:5
帖 子:48
专家分:84
注 册:2016-3-23
收藏
得分:0 
回复 9楼 zhulei1978
确实会,只是打个比方。例如,我可以在操作系统子过程的开头插入一段子过程名字的字符串,然后就可以供为其他之后运行的程序查找和使用,虽然这样效率并不高。

[此贴子已经被作者于2016-4-12 21:44编辑过]

2016-04-12 21:40
快速回复:编写操作系统?有趣:第一天
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020924 second(s), 11 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved