操作系统开发之——一个简单的Bootsect(改进版)

来源:互联网 发布:cmd mysql utf8 乱码 编辑:程序博客网 时间:2024/06/03 19:01

我们在前一篇文章: 操作系统开发之——一个简单的Bootsect 当中写了一个最最最简单的Bootsect,但还有些漏洞和缺陷,比如说,没有打印显示文字,等等。

还是直接贴代码:

;--------------------------; @imcjy; build:1; 11.7.2015; copyright (c) UOS Group;--------------------------ORG 0x7c00; BIOS load subroutine default to qualified disk first sector read 0x7c00.JMP os_entry ; Skip the useless code to "os_entry".; Define the boot structure.DAP ; DAP : Disk Address Packet.DAP.1  DB 16 ; size of DAP = 16 = 10hDAP.2  DB 0 ; unused, should be zeroDAP.3  DW 0 ; number of sectors to be read, (some Phoenix BIOSes are limited to a maximum of 127 sectors)DAP.4  DD 0 ; segment:offset pointer to the memory buffer to which sectors will be transferred (note that x86 is little-endian: if declaring the segment and offset separately, the offset must be declared before the segment)DAP.5  DQ 0 ; absolute number of the start of the sectors to be read (1st sector of drive has number 0)[bits 16]os_entry:; Init regs.MOVAX,CSMOVDS,AXMOVES,AXMOVSS,AX; Init stack pointer regs.MOV SP,0x7c00 ; Must be!; Set video mode or clear screen.MOV AH, 0MOV AL, 3INT 0x10; clear regs.XOR AX, AX; ES: BP pointing to display the stringMOV AX, loadmsgMOV BP, AX  MOV AH, 0X13 ; function 13MOV AL, 1MOV BH, 0 ; page 1  MOV BL, 0x0F ; char attributeMOV CX, loadmsglen ; length of msgMOV DX, 0 ; row 1,line 1INT 0x10; Move specified value to the target location.MOV dword [DAP.3], 2MOV dword [DAP.4], 0x80000000MOV dword [DAP.5], 1CALL read_disk ; Call the "read_disk" func.; Move specified value to the target location.MOV dword [DAP.3], 128MOV dword [DAP.4], 0x10000000MOV dword [DAP.5], 3CALL read_disk ; Call the "read_disk" func.; Move specified value to the target location.MOV dword [DAP.3], 128MOV dword [DAP.4], 0x20000000MOV dword [DAP.5], 131CALL read_disk ; Call the "read_disk" func.; Move specified value to the target location.MOV dword [DAP.3], 128MOV dword [DAP.4], 0x30000000MOV dword [DAP.5], 259CALL read_disk ; Call the "read_disk" func.; Set video mode or clear screen.MOV AH, 0MOV AL, 3INT 0x10; clear regs.XOR AX, AXJMP 0x8000:0read_disk:MOVAX, DAP ; Duplicate from "DAP" to AX.MOV SI, AXMOV DL, 0x80; drive index (e.g. 1st HDD = 80h)MOV AH, 0x42; 42h = function number for extended readINT 0x13JC die; clear DAPMOV dword [DAP.3], 0MOV dword [DAP.4], 0MOV dword [DAP.5], 0; clear regsXOR AX, AXXOR BX, BXXOR DX, DXRETdie:; Set video mode or clear screen.MOV AH, 0MOV AL, 3INT 0x10; ES: BP pointing to display the stringMOV AX, failmsgMOV BP, AX  MOV AH, 0X13 ; function 13MOV AL, 1MOV BH, 0 ; page 1  MOV BL, 0x0F ; char attributeMOV CX, failmsglen ; length of msgMOV DX, 0 ; row 1,line 1INT 0x10.hlt:JMP .hlt; string infomsg:;-------------------------failmsg:DB "Error in bootsect!"failmsglen EQU $ - failmsg;-------------------------loadmsg:DB "Loading kernel..."loadmsglen EQU $ - loadmsg;-------------------------;Boot signature.TIMES 510 - ($ - $$) DB 0DB 0x55,0xAA
想拷贝代码的朋友直接拷贝,但注意我们以AGPL开源UOS,所以,(嘻嘻)读者朋友也必须公开自己写的源代码。

注意!!!这次我们改了个读取硬盘的方式,上次是直接机械的一次次的读取,这次我们改为了函数调用的方式(注意,这里的函数调用不像保护模式下的函数调用那么麻烦,有兴趣的朋友可以去看看保护模式)。

如果读者朋友没有点点基础的话,笔者建议先把 http://blog.csdn.net/imcjysy/article/details/47660883 这里的一篇文章看完。

先讲讲”语法知识“(其实是基本知识)。

(参考http://blog.csdn.net/pdcxs007/article/details/43378229,其实就是复制)

BIOS的10H中断的13号中断用于显示字符串,参数为:

1、AH=13H

2、AL=显示方式

      如果AL=0,表示目标字符串仅仅包含字符,属性在BL中包含,不移动光标

      如果AL=1,表示目标字符串仅仅包含字符,属性在BL中包含,移动光标

      如果AL=2,表示目标字符串包含字符和属性,不移动光标

      如果AL=3,表示目标字符串包含字符和属性,移动光标

      总之,可以归纳为:    

           |BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0| AL

             BIT0为0表示不移动光标,为1表示移动光标

             BIT1为0表示字符串仅包含字符,为1表示字符串包含属性

             BIT2~BIT7未使用


3、BH表示视频区页数

4、如果AL的BIT1为0,则BL表示显示属性。属性为:

      |BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0| BL

         BIT7:背景是否闪烁。0不闪烁,1闪烁

         BIT6~BIT4为背景色,分别为RGB,000为黑色,111为白色

         BIT3为1,则前景色加亮,为0则不加亮

         BIT2-BIT0为前景色,意义同背景色

5、CX为字符串长度

6、DH表示在第几行显示(0为第一行)

7、DL表示在第几列显示(0为第一列)

8、ES:BP指向字符串

------------------------------------------------------分界-----------------------------------------------------------------

(参考维基百科)

INT 13h AH=42h: Extended Read Sectors From Drive[edit]

Parameters:

RegistersAH42h = function number for extended readDLdrive index (e.g. 1st HDD = 80h)DS:SIsegment:offset pointer to the DAP, see belowDAP : Disk Address Packetoffset rangesizedescription00h1 bytesize of DAP = 16 = 10h01h1 byteunused, should be zero02h..03h2 bytesnumber of sectors to be read, (some Phoenix BIOSes are limited to a maximum of 127 sectors)04h..07h4 bytessegment:offset pointer to the memory buffer to which sectors will be transferred (note that x86 is little-endian: if declaring the segment and offset separately, the offset must be declared before the segment)08h..0Fh8 bytesabsolute number of the start of the sectors to be read (1st sector of drive has number 0)

Results:

CFSet On Error, Clear If No ErrorAHReturn Code
------------------------------------------------------分界-----------------------------------------------------------------

还有一点,你会在代码中发现到,有清除一些寄存器以及数据的代码,这是因为后面可能需要(现在就用到了)这些数据或寄存器。

如果还有问题可以联系我:Email:2608184397@qq.com

如果读者朋友也有开发操作系统的想法,可以联系我。


1 0
原创粉丝点击