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空间。
近期项目又紧张,更新会慢,但不会中断。。。加油。
- D_D系统构建-MBR(8)filesystem.inc代码整改适配32位(附提供当前整个开发目录文件)
- D_D系统构建-MBR(7)加载loader文件代码filesystem.inc解析
- D_D系统构建-开发文件目录结构
- D_D系统构建-MBR(3)代码
- D_D系统构建-MBR(4)代码剖析
- D_D系统构建-MBR(6)加载loader文件代码MBR解析
- D_D系统构建-MBR(1)
- D_D系统构建-文件分布及说明
- D_D系统构建-文件写入方法
- D_D系统构建-文件系统
- D_D系统构建-篇外话
- D_D系统构建-简述及环境准备
- D_D系统构建-loader保护模式修改
- D_D系统构建-Loader的保护模式尝试
- 从系统分区镜像文件构建MBR
- DD系统构建-MBR(5)加载loader文件
- 新云inc目录文件具体说明(解说)
- 复制整个目录文件
- Leetcode 646. Maximum Length of Pair Chain 找最长链 解题报告
- 递归之二分查找
- 石子合并-OJ
- ubuntu 下linux 常用命令
- 51nod1027---大数乘法(51nod基础:乘法模拟)
- D_D系统构建-MBR(8)filesystem.inc代码整改适配32位(附提供当前整个开发目录文件)
- BZOJ 2100 [Usaco2010 Dec]Apple Delivery 最短路
- The RT Patch---what needs to be done to get it into Mainline ---Steven Rostedt
- 汉诺塔
- C++中static、const、static const修饰变量作用详解
- 文章标题
- Logstash插件filter介绍及ELK相关预警配置
- 识别浏览器的方法
- POJ.1321 棋盘问题 (DFS)