D_D系统构建-MBR(8)filesystem.inc代码整改适配32位(附提供当前整个开发目录文件)

来源:互联网 发布:anaconda python 3.5 编辑:程序博客网 时间:2024/06/07 13:23

上几篇我们已经可以通过mbr加载loader文件,并能成功执行loader指令(PS<本章最下面将当前整个开发目录提供了出来,方便大家整个拷贝到本地进行验证)。

下面计划是要扩展我们的loader文件,来进入保护模式的,在保护模式中加载kernel文件,自然想复用我们已经有的filesystem.inc文件。

但检查过这个文件后,发现里面的函数寄存器基本使用的是16位的。且存在修改ds/es的操作。这在实模式下没有关系。但 在进入保护模式就会有问题了。

保护模式下,我们访问32位地址空间,基本要使用32位寄存器;同时在保护模式中ds/es等段寄存器的内容已经发生了变化(后面会说到),不再是实模式下的段物理地址了,而是变成了选择子的内容,如果 代码里面还有对ds/es赋值的,肯定会有问题。

因此需要以代码整改,包括两方面:1. 修改寄存器为32位 2.取消ds/es的修改。

代码如下:

filesystem.inc

;文件系统相关的宏定义MACRO_DDFS_SYSTEMBLOCK_START_SECTOR_NO  EQU 1MACRO_DDFS_SYSTEMBLOCK_SECTOR_NUM EQU 1MACRO_DDFS_SECTORBITMAP_START_SECTOR_NO  EQU 2MACRO_DDFS_SECTORBITMAP_SECTOR_NUM EQU 1MACRO_DDFS_INODEBITMAP_START_SECTOR_NO  EQU 3MACRO_DDFS_INODEBITMAP_SECTOR_NUM EQU 1MACRO_DDFS_INODEINFO_START_SECTOR_NO  EQU 4MACRO_DDFS_INODEINFO_SECTOR_NUM EQU 512MACRO_DDFS_FILESECTORLIST_START_SECTOR_NO  EQU 516MACRO_DDFS_FILESECTORLIST_SECTOR_NUM EQU 32MACRO_DDFS_FILEDATA_START_SECTOR_NO  EQU 548MACRO_DDFS_FILEDATA_SECTOR_NUM EQU 3548MACRO_DDFS_FILESYSTEM_SIZE_SYSTEMBLOCK EQU 16MACRO_DDFS_FILESYSTEM_SYSTEMBLOCK_OFFSET_TOTALSECTORNUM EQU 0MACRO_DDFS_FILESYSTEM_SYSTEMBLOCK_OFFSET_USEDSECTORNUM EQU 4MACRO_DDFS_FILESYSTEM_SYSTEMBLOCK_OFFSET_TOTALINODENUM EQU 8MACRO_DDFS_FILESYSTEM_SYSTEMBLOCK_OFFSET_USEDINODENUM EQU 12MACRO_DDFS_FILESYSTEM_SIZE_INODEINFO   EQU 64MACRO_DDFS_FILESYSTEM_INODEINFO_OFFSET_FILENAME EQU 0MACRO_DDFS_FILESYSTEM_INODEINFO_OFFSET_FILESIZE EQU 32MACRO_DDFS_FILESYSTEM_INODEINFO_OFFSET_FILESECTORNUM EQU 36MACRO_DDFS_FILESYSTEM_INODEINFO_OFFSET_FILESTARTSECTOR EQU 40MACRO_DDFS_FILESYSTEM_SIZE_FILESECTORLIST  EQU 8MACRO_DDFS_FILESYSTEM_FILESECTORLIST_OFFSET_ISNEXTVALID EQU 0MACRO_DDFS_FILESYSTEM_FILESECTORLIST_OFFSET_NEXTSECTOR EQU 4MACRO_DDFS_FILESYSTEM_INODE_NUM  EQU 4096globalSectorSpace: times 512 db 0;-------------------------------------------------------------;函数名:getDiskDataFromSectors(起始扇区号, 扇区数目, 起始内存地址);函数说明:从指定起始扇区处连续加载指定扇区数目的数据到指定的内存起始位置处;函数参数:;    参数说明      参数位置 参数大小;    起始扇区号,  bp+4     2字节;    扇区数目,    bp+6     2字节;    起始内存地址: bp+8     4字节;返回值:;    无;-------------------------------------------------------------getDiskDataFromSectors:    push ebp    mov ebp, esp    pushad    ;加载的内存起始地址    mov edi, [ebp+10]    ;要读取的扇区数目    mov ax, [ebp+8]    ;起始扇区号    mov si, [ebp+6]    mov dx,0x1f2    out dx,al                       ;读取的扇区数    inc dx                          ;0x1f3    mov ax,si    out dx,al                       ;LBA地址7~0    inc dx                          ;0x1f4    mov al,ah    out dx,al                       ;LBA地址15~8    xor ax, ax    inc dx                          ;0x1f5    out dx,al                       ;LBA地址23~16    inc dx                          ;0x1f6    mov al,0xe0                     ;LBA28模式,主盘    out dx,al    inc dx                          ;0x1f7    mov al,0x20                     ;读命令    out dx,al    .waits:        in al,dx        and al,0x88        cmp al,0x08        jnz .waits                      ;不忙,且硬盘已准备好数据传输     ;计算要循环读取的字节数目,由于一次读取是2个字节,因此总字节除以2    mov ax, [ebp+8]        mov bx, 512    mul bx        mov bx, 2    div bx    mov cx, ax    mov dx,0x1f0    .readw:        in ax,dx        mov [edi],ax        add edi, 2        loop .readw    popad    pop ebp        ret;-------------------------------------------------------------;函数名:getSystemBlockData(buf);函数说明:获取文件系统块,保存buf中;函数参数:;    参数说明      参数位置 参数大小;    buf           bp+4     4字节;返回值:;    无;补充说明:;-------------------------------------------------------------getSystemBlockData:    push ebp    mov ebp, esp    pushadmov eax, [ebp+6] push eaxmov ax, MACRO_DDFS_SYSTEMBLOCK_SECTOR_NUMpush axmov ax, MACRO_DDFS_SYSTEMBLOCK_START_SECTOR_NOpush axcall getDiskDataFromSectorspop axpop axpop eaxpopad    pop ebpret;-------------------------------------------------------------;函数名:getInodeBitMapData(buf);函数说明:获取inodebitmap,保存到buf中;函数参数:;    参数说明      参数位置 参数大小;    buf           bp+4     4字节;返回值:;    无;补充说明:;-------------------------------------------------------------getInodeBitMapData:    push ebp    mov ebp, esp    pushadmov eax, [ebp+6] push eaxmov ax, MACRO_DDFS_INODEBITMAP_SECTOR_NUMpush axmov ax, MACRO_DDFS_INODEBITMAP_START_SECTOR_NOpush axcall getDiskDataFromSectorspop axpop axpop eaxpopadpop ebpret;-------------------------------------------------------------;函数名:getInodeInfoByInodeIndex(inodeindex, buf);函数说明:通过inode索引获取对应的inodeinfo;函数参数:;    参数说明      参数位置 参数大小;    inodeindex    bp+4     2;    buf           bp+6     4字节;返回值:;    eax: 0:未使用 1:已经使用;补充说明:;-------------------------------------------------------------getInodeInfoByInodeIndex:    push ebp    mov ebp, esp    pushadmov ax, [ebp+6] xor edx, edxmov bx, MACRO_DDFS_FILESYSTEM_SIZE_INODEINFOmul bx    ;除以512后,ax保存扇区偏移,dx保存扇区内偏移mov bx, 512div bxadd ax, MACRO_DDFS_INODEINFO_START_SECTOR_NO    mov ebx, globalSectorSpacepush ebxmov bx, 1push bxmov bx, axpush bxcall getDiskDataFromSectorspop bxpop bxpop ebx;将64字节内容拷贝到用户区xor esi, esimov esi, globalSectorSpaceadd esi, edxxor edi, edimov edi, [ebp+8]mov cx, MACRO_DDFS_FILESYSTEM_SIZE_INODEINFOcldrep movsbpopadpop ebpret;-------------------------------------------------------------;函数名:getFileSectorListBySector(sector, buf);函数说明:通过Secto索引获取对应的filesectorlist信息;函数参数:;    参数说明      参数位置 参数大小;    sector        bp+4     2;    buf           bp+6     4字节;返回值:;    eax: 0:未使用 1:已经使用;补充说明:;-------------------------------------------------------------getFileSectorListBySector:    push ebp    mov ebp, esp    pushadmov ax, [ebp+6]xor edx,edx    mov bx, MACRO_DDFS_FILESYSTEM_SIZE_FILESECTORLISTmul bxmov bx,512div bxmov ebx, globalSectorSpacepush ebxmov bx, 1push bxmov bx, MACRO_DDFS_FILESECTORLIST_START_SECTOR_NOadd bx, axpush bxcall getDiskDataFromSectorspop bxpop bxpop ebx;将8字节内容拷贝到用户区mov esi, globalSectorSpaceadd esi, edxmov edi, [ebp+8]mov cx, MACRO_DDFS_FILESYSTEM_SIZE_FILESECTORLISTcldrep movsb    popad    pop ebp    ret;-------------------------------------------------------------;函数名:checkFileNameIsSame(dstFileName, srcFileName, FileLen, outBuf);函数说明:比较指定长度的源目的文件名是否相同;函数参数:;    参数说明      参数位置 参数大小;    dstFileName   bp+4     4字节;    srcFileName   bp+8     4字节;    dstFileName   bp+12    2字节;    outBuf        bp+14    4字节;返回值:;    outBuf: 0:不相同 1:相同;补充说明:;-------------------------------------------------------------checkFileNameIsSame:    push ebp    mov ebp, esp    pushadmov esi, [ebp+6]mov edi, [ebp+10]mov cx, [ebp+14]cldrepz cmpsbcmp cx, 0jz file_name_samemov esi, [ebp+16]mov word [esi], 0    popadpop ebpretfile_name_same:mov esi, [ebp+16]mov word [esi], 1    popadpop ebpret;-------------------------------------------------------------;函数名:checkFileNameIsSame(bitIndex, bitBuffer, outBuf);函数说明:比较指定长度的源目的文件名是否相同;函数参数:;    参数说明      参数位置 参数大小;    bitIndex      bp+4     2字节;    bitBuffer     bp+6     4字节;    outBuf        bp+10    4字节;返回值:;    outBuf: 0:不相同 1:相同;补充说明:;-------------------------------------------------------------checkBitIsSet:    push ebp    mov ebp, esp    pushadxor eax, eaxmov ax, [ebp+6]mov ebx, [ebp+8]mov ecx, [ebp+12]push ebxxor dx, dxmov bx, 8div bxpop ebxadd ebx, eaxmov esi, ebxbt [esi], dxjc bit_is_setmov esi, ecxmov word [esi], 0    popadpop ebpretbit_is_set:mov esi, ecxmov word [esi], 1    popadpop ebpret


最明显的变化是bp变成的ebp, 比如getDiskDataFromSectors,左侧是修改前,右侧是修改后的;还要注意的是用了32位后,实际的入栈参数偏移已经发生了变化 。



这里我们还多做了个文件,在写入boot后,先额外的写个其它文件(比如我们直接把boot.asm文件写入磁盘中),让它占用Inode0,然后再写入Loader.bin,通过这种方式来检查我们的查找loader.bin是否正确。如果 正确,它要显示 出Loader运行的提示。

我们把前面 的操作再重复一下, 操作按照如下步骤进行:


1. 先格式化我们的磁盘,并安装文件系统 。

使用我们之前编写的文件系统 初始化工具mkddfs,(D_D系统构建-文件写入方法: http://blog.csdn.net/b06030927/article/details/73050529)



2.编译并安装boot,这两个动作已经集成到makefile中。



3.在编译loader.bin之前,先安装个其它文件,我们选择了boot.asm,检查下inode分配是否正确,及后面写入loader.bin会不会有问题



4. 调用readddfs工具(同mkddfs), 查看当前文件系统 的应用情况,可以看到写入boot.asm后,可以看到它占用了一个Inode.同时能持到这个boot.asm文件大小,及占用的扇区情况。





5.此时 再编译并写入loader.bin,



6.检查下此时 的文件系统应用情况,占用两个inode,文件大小与实际 的大小一致。




7.最关键的一步到了,现在是检验我们的系统 能否正常加载 loader.bin了。运行bochs


很明显,它正确的找到了我们的Loader.bin,修改后的文件能正常生效,


这样,在下面的保护系统章节里面,我们还 能继续借用这个filessytem.inc函数,节省点开发时间。

PS: 另外,之前 一直没有找到能把整个开发文件目录打包并放到csdn上的方法,这里面把它压缩并放到百度网盘里面,下面是链接,不需要密码,大家随意取用。

http://pan.baidu.com/s/1o8iGp5K

这里面包含我使用的整个开发文件,大家下载后,到linux上解压开来,应该就可以使用。


下面开始我会改造当前的loader,让其工作在保护 模式下,跳出1M空间的限制,自由切换4G空间。

近期项目又紧张,更新会慢,但不会中断。。。加油。

原创粉丝点击