《30天自制操作系统》读书笔记Day19
2013-11-21 16:57
239 查看
GitHub地址:https://github.com/scusjs/
1.cat(type)命令
前面实现列出文件目录命令,这里该实现显示文件内容命令了,即cat(windows下为type)。
回忆前面的FILEINFO结构体,其中clustno表示文件从磁盘上哪个扇区开始存放。
通过观察系统文件发现如下规律:
磁盘镜像中的地址 = clustno * 512 + 0x003e00
接着就开始实现函数了。
先添加一个指针:
char *p;
然后具体实现命令:
前面的程序虽然能够显示文件内容了,但是对于大于一个扇区(512字节)的内容的显示还是有问题的。
在FAT(file allocation table)中,第0柱面、0磁头、2扇区开始的9个扇区(0x000200~0x0013ff)会记录大于一扇区文件的内容记录在哪些位置。
简单说下FAT:
FAT中记录下一部分内容在哪个位置。其中数据会进行处理,其实就是进行移位操作,比如磁盘上:
ab cd ef,处理后得到FAT真实数据:dab efc,其中,dab与efc分别表示数字。读文件时,例如clustno=2,读取0x004200~0x0043ff数据,接下来查看FAT第二个记录,如果其为003,则下一部分在clustno=3,即读取0x004400~0x0045ff,这样下去直到FAT中记录为FF8~FFF。
开始写代码:
3.代码整理
4.第一个应用程序
现在开始尝试编写第一个应用程序。试试第三天的那个程序:
将其编译,并在Makefile中将其编译进入系统。
然后在console.c中对其进行支持:
1.cat(type)命令
前面实现列出文件目录命令,这里该实现显示文件内容命令了,即cat(windows下为type)。
回忆前面的FILEINFO结构体,其中clustno表示文件从磁盘上哪个扇区开始存放。
通过观察系统文件发现如下规律:
磁盘镜像中的地址 = clustno * 512 + 0x003e00
接着就开始实现函数了。
先添加一个指针:
char *p;
然后具体实现命令:
else if ((strncmp(cmdline,"cat ",4) == 0) || (strncmp(cmdline,"type ",5) == 0)) { //准备文件名 for (y = 0; y < 11; y++) { s[y] = ' '; } y = 0; if (strncmp(cmdline,"cat ",4) == 0) { x = 4; } else { x = 5; } for (; y < 11 && cmdline[x] != 0; x++) { if (cmdline[x] == '.' && y <= 8) { y = 8; } else { s[y] = cmdline[x]; if ('a' <= s[y] && s[y] <= 'z')//全部转换为大写 { s[y] -= 0x20; } y++; } } //寻找文件 for (x = 0; x < 224; x++) { if (finfo[x].name[0] == 0x00) { break; } if ((finfo[x].type & 0x18) == 0) { for (y = 0; y < 11; y ++) { if (finfo[x].name[y] != s[y]) { break; } } if (y >= 11) break;//找到文件 } } if (x < 244 && finfo[x].name[0] != 0x00) { y = finfo[x].size; p = (char *) (finfo[x].clustno * 512 + 0x003e00 + ADR_DISKIMG); cursor_x = 8; for (x = 0; x < y; x++)//逐字输出 { s[0] = p[x]; s[1] = 0; if (s[0] == 0x09)//制表符 { for (;;) { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cursor_x += 8; if (cursor_x == 8 + 240) { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } if (((cursor_x - 8) & 0x1f) == 0) //被32整除则break { break; } } } else if (s[0] == 0x0a)//换行 { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } else if (s[0] == 0x0d)//回车 { } else { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); cursor_x += 8; if (cursor_x == 8 + 240) { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } } } } else { putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); cursor_y = cons_newline(cursor_y, sheet); } cursor_y = cons_newline(cursor_y, sheet); }2.FAT的支持
前面的程序虽然能够显示文件内容了,但是对于大于一个扇区(512字节)的内容的显示还是有问题的。
在FAT(file allocation table)中,第0柱面、0磁头、2扇区开始的9个扇区(0x000200~0x0013ff)会记录大于一扇区文件的内容记录在哪些位置。
简单说下FAT:
FAT中记录下一部分内容在哪个位置。其中数据会进行处理,其实就是进行移位操作,比如磁盘上:
ab cd ef,处理后得到FAT真实数据:dab efc,其中,dab与efc分别表示数字。读文件时,例如clustno=2,读取0x004200~0x0043ff数据,接下来查看FAT第二个记录,如果其为003,则下一部分在clustno=3,即读取0x004400~0x0045ff,这样下去直到FAT中记录为FF8~FFF。
开始写代码:
int *fat = (int *) memman_alloc_4k(memman, 4*2880); 。。。 file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200)); 。。。 if (x < 244 && finfo[x].name[0] != 0x00) { p = (char *) memman_alloc_4k(memman, finfo[x].size); file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); cursor_x = 8; for (y = 0; y < finfo[x].size; y++)//逐字输出 { ... } ... memman_free(memman, (int) p, finfo[x].size); }运行即可。
3.代码整理
窗口相关函数——>window.c 命令行窗口相关函数——>console.c 文件相关函数——>file.c在Makefile中添加相应的obj即可。
4.第一个应用程序
现在开始尝试编写第一个应用程序。试试第三天的那个程序:
[BITS 32] fin: HLT JMP fin输入命令:..\z_tools\nask.exe hlt.nas hlt.dog
将其编译,并在Makefile中将其编译进入系统。
然后在console.c中对其进行支持:
else if (strcmp(cmdline,"hlt") == 0) { for (y = 0; y < 11; y++) { s[y] = ' '; } s[0] = 'H'; s[1] = 'L'; s[2] = 'T'; s[8] = 'D'; s[9] = 'O'; s[10]= 'G'; for (x = 0; x < 224; x++) { if (finfo[x].name[0] == 0x00) { break; } if ((finfo[x].type & 0x18) == 0) { for (y = 0; y < 11; y ++) { if (finfo[x].name[y] != s[y]) { break; } } if (y >= 11) break;//找到文件 } } if (x < 224 && finfo[x].name[0] != 0x00) { p = (char *) memman_alloc_4k(memman, finfo[x].size); file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); set_segmdesc(gdt + 1003, finfo[x].size - 1, (int) p, AR_CODE32_ER);//将其注册到GDT的1003号 farjmp(0, 1003*8); memman_free_4k(memman, (int) p, finfo[x].size); } else { putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); cursor_y = cons_newline(cursor_y, sheet); } cursor_y = cons_newline(cursor_y, sheet); }运行系统,然后在命令行中输入hlt,发现命令行卡死,说明程序正确执行。
相关文章推荐
- 30天自制操作系统------保护操作系统
- 《30天自制操作系统》学习笔记(五)
- CPU存储电路之寄存器——《30天自制操作系统》笔记
- 《30天自制操作系统》学习笔记(六)
- 30天自制操作系统------图形处理相关
- 《30天自制操作系统》学习笔记--第3天
- 《30天自制操作系统》学习笔记--第11天
- 《30天自制操作系统》学习笔记--番外篇之Mac环境下的工具介绍
- 《30天自制操作系统》学习笔记--Mac环境搭建
- 30天自制操作系统day11
- 30天自制操作系统第二天笔记 Makefile文件
- 《30天自制操作系统》02_day_学习笔记
- 《30天自制操作系统》学习笔记——第四天
- 《30天自制操作系统》学习笔记——第六天
- 《30天自制操作系统》11_day_学习笔记
- 学习《30天自制操作系统》
- 30天自制操作系统——前三天
- 《30天自制操作系统》笔记(05)——启用鼠标键盘
- 读书笔记《30天自制操作系统》day05
- 《30天自制操作系统》读书笔记(4) 绘图