day7
1. 进度记录
- 制作FIFO缓冲区接收键盘中断的字符,并在HariMain函数中显示缓冲区的字符
- new fifo.c 管理缓冲区
- 鼠标中断
2. 成果与总结
(1)键盘中断
- 按键时产生两次中断,发送两个字节键码值;松开时产生两次中断,发送两个字节键码值;
- 键盘端口号 0x0060
(2)鼠标中断
- 每当鼠标被激活,会发送答复信息——0xfa
- 鼠标一次中断产生三个字节的数据,三个字节分别说明状态、左右移、上下移的信息。
day6
1. 进度记录
- 分割bootpack.c -> grashic.c, dsctbl.c, bootpack.c
- 整理makefile
- 使用头文件减少重复代码
- 键盘鼠标的中断
2. 成果与总结
(1) 文件分割与链接
(2) makefile 一般规则
%.gas : %.c Makefile
$(CC1) -o $*.gas $*.c
# 可以替代
bootpack.gas : bootpack.c Makefile
$(CC1) -o bootpack.gas bootpack.c
等
(3) ar(access right)常见值(16位,其中8-11位是段限)
- 0x92 系统专用,可读写,不可执行
- 0x9a 系统专用,可执行,可读不可写
- 0xf2 应用程序专用,可读写,不可执行
- 0xfa 应用程序专用,可执行,可读不可写
(4) PIC连接
- 其中鼠标是IRQ12, 键盘是IRQ1, 对应中断指令 INT 0x2c, 0x21
(5) 键盘鼠标的中断
- 主体处理函数 inthandler21(int.c)
- inthandler21 在 asm_inthandler21 中被调用。asm_inthandler21 主要是为了中断前的现场保护以及中断后的现场恢复
- init_gdtidt (dectbl.c)时,将asm_inthandler21,asm_inthandler2c写入中断门 0x21,和0x2c。且中断门的选择符指向GDT中第二个段。也就bootpack所涵盖的段
3. 补充学习
(1) 中断示意图
day5
1. 进度记录
- 使用bootinfo结构体封装启动信息,varm,xsize等
- 将 hankaku.txt 制作成hankaku.obj, 并链接到 bootpack.bim中
- 字符显示(8*16),字符串显示
- 显示鼠标(16*16),但还不能移动
2. 成果与总结
(1) GDT, IDT 的初始化
考虑电脑内存空闲,给GDT分配0x270000~0x27ffff (范围大小=213*8 bytes), 给IDT分配0x26f800 ~ 0x26ffff(256 * 8 bytes)。
再把基址段限信息存入GDTR,IDTR中
gdt中特别注意的两个段:
set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0x4092); // 上线0xffffffff=4GB, 表示CPU所能管理的全部内存本身。
set_segmdesc(gdt + 2, 0x0007ffff, 0x00280000, 0x409a); // 大小为 512KB,为bootpack.hrb准备
set_segmdesc 设置段描述符时,如果段的限长超过 0xfffff 时,采用分页 属性令G=1;
(2) 内存分配
用途 | 地址 |
---|---|
BIOS,VRAM等 | 0x0000_0000 - 0x000f_ffff |
软盘内容 | 0x0010_0000 - 0x0026_7fff (1440KB) |
空 | 0x20026_8000 - 0x26_7ff (30KB) |
IDT | x0026_f800 ~ 0x0026_ffff |
GDT | 0x0027_0000 ~ 0x0027_ffff |
bootpack.hrb | 0x0028_0000 ~ 0x002f_ffff |
栈及其它 | 0x0030_0000 ~ 0x003f_ffff |
3. 补充学习
GDTR、IDTR、段描述符、中断门
- GDTR, IDTR, TR, LDTR
- 段描述符
段描述符中的访问权限字节格式如下:
- P:存在位,P = 0 表示段不在内存,P = 1 表示段在内存。
- DPL:描述符权限,即段被访问的特权级,0–3 共 4 级。
- S:描述符类型,S = 0为系统控制段描述符,S = 1为其他段描述符。
- E:段可执行性, E = 1 为代码段,可执行,E = 0 为数据段。-
- ED/C和W/R:数据段为ED、W,ED为扩展方向,ED = 0向上扩展,ED = 1向下扩展。W = 1为可写,W = 0为不可写。代码段为C、R,C = 0为非证实/非一致代码段,C = 1为证实/一致代码段。R = 0为不可读,可执行,R = 1为可读,可执行。
- 中断门
day4
1. 进度记录
- 初始化调色板:向端口 0x03c8写入调色号,然后依此写入R、G、B值;若继续设定调色板,则省略调色板号,直接按RGB顺序写入。
- 向 nask 中增加新功能:I/O, 读写Flags等
- bootpact.c 中增加绘制正方形的功能
2. 成果与总结
(1) 注意事项
- 由于汇编和C语言联合使用,在写汇编的时候,能自由使用的寄存器只有EAX, ECX, EDX 三种。其它只能使用其值,不能改变其值,因为C编译时会使用它们。
(2) 指针
char *p; // BYTE 类型地址,
short *p; // WORD 类型地址, 2字节
int *p; // DWORD 类型地址
(3) 调色板
写:0x03c8写入调色号,0x03c9写入RGB值
读:0x03c7写入调色号,0x03c9读出RGB值
3. 补充学习
标志寄存器(32位)
4. 待解决
day3
1. 进度记录
- 更改了系统名称,和相应的批处理文件
- 增加了读软盘功能、循环试错功能、读取多个扇区、多个柱面
- 软盘总共有 18280个扇区,此次读取了 18210-1 (不包括启动区)个扇区到内存 0x 8200-0x34fff处
- new haribote.nas, 用haribote.nas、ipl.nas 制作磁盘映像文件
在磁盘映像中,文件名haribote写在0x002600以后的地方,文件内容写在0x004200以后的地方。
做磁盘ox4200处的内容实际位于内存 0x8000+0x4200=0xc200号地址。
- haribote.nas -> asmhead.nas
- new bookpack.c, naskfunc.nas
2. 成果与总结
(1)汇编
symble | meaning |
---|---|
JNC | jump if not carry |
JAE | jump if above or equal |
JBE | jump if below of equal |
(2)INT 013
磁盘读写、检验、寻道。
(3)设置显卡模式
MOV AL,0x13 ;3x200x8bit color VGA graphics 模式
MOV AH,0x00
INT 0x10
; AL = 0x03, 16色字符模式,80*25
0x12, VAG图形模式,640*480*4位彩色模式, 独特的4面存储模式
0x13, 320*200*8, 调色板模式
0x6a, 拓展到VAG图形模式,800*600*4
(4) 整体流程
注其中省略了 bim->hrb->sys
3. 补充学习
4. 待解决
day2
1. 进度记录
- 改写了 helloos.nas: 将启动区内容装载的 0x7c00-0x7dff; 循环打印msg
- helloos.nas -> ipl.nas , 并修改 asm.bat(功能:ipl.nas -> ipl.bin)
- new makeimge.bat : 利用edimg.exe, 读入一个空白磁盘映像文件,然后再开头写入 ipl.bin , 输出为helloos.img
- 使用了make 和Makefile, 并删除了相关多于文件
2. 成果
(1)汇编
- ORG 0x7c00 此段程序装载位置在 0x7c00
- MOV BYTE [678],123 使用方括号表示内存地址,BYTE、WORD等指定内存大小
- 只有BX,BP,SI,DI可以指定内存地址,AX,CX,DX,SP不能
- HLT 让cpu待机
- INT 10H BIOS对屏幕及显示器所提供的服务程序。使用i时,先要进行一些简单的配置,比如指定功能号和子功能号。其中寄存器AH表示的就是功能号. 具体请点击链接。
3. 补充学习
makefile
参考
(1) 编译链接
.c—编译—> .obj (.o) —链接—>.exe
-
编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。
-
链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。
(2) Makefile 规则
target … : prerequisites …
command
…
target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label).
command也就是make需要执行的命令。(任意的Shell命令)
在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个Tab键作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话li,那么,make就会执行后续定义的命令
(3) 使用变量、自动推导、清除规则
例:
objects= main.o kbd.o command.o display.o\
insert.osearch.o files.o utils.o
edit: $(objects)
cc –o edit$(objects)
main.o : main.c defs.h # 可以不要main.c, make会自动推导;只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中
cc –c main.c
kbd.o :kbd.c defs.h command.h
cc -c kbd.c
clean:
rm edit$(objects) # 清空目标文件的规则
# -rm edit$(objects) # 小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。
#另一种定义变量方式 :=
CFLAGS=$(include_dirs) -O
include_dirs=-Ifoo -Ibar # 当“CFLAGS”在命令中被展开时,会是“-Ifoo-Ibar-O”。
y:=$(x)bar
x:=foo # 那么,y的值是“bar”,而不是“foobar”。
(4) makefile
Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。
(5) 通配符
symble | help |
---|---|
[…] | |
? | 匹配单个字符 |
* | 匹配多字符 |
% |
(6) 文件搜索
如果没有指明VPATH这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。如果定义了VPATH这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。
eg VPATH=src:../headers # 这是包含了两个文件,由:分隔。
(7)使用函数
eg: $(filter %.o,$(files))
表示调用Makefile的filter函数,过滤“$filter”集,只要其中模式为“%.o”的内容。
4. 待解决
- 软盘第一个扇区存储位置是不是 OX8000?
day1
1. 进度记录
- new /helloos/!cons_nt.bat : 实际执行cmd.exe
- new install.bat :使用了imgtol
- new run.bat :将映像文件考到qemu目录下,转成 .bin; 然后make qemu文件夹
- new asm.bat : 利用nask将汇编文件转换成映像文件
- 自制批处理文件 o.bat、d.bat、c.bat 用来打开、删除、复制文件
2. 成果
映像文件
对磁盘所存储的数据的映像,本质上是二进制文件,qemu模拟器所运行的实际上是fdimage0.bin这个二进制文件。
FAT12
FAT12是DOS时代就开始使用的文件系统(File System),直到2009年仍然在软盘上使用。
其主磁盘结构为:
1)引导扇区(boot sector):位于第一个扇区,在软盘上就是0柱面(磁道)0磁头1扇区。
2)文件分配表(FAT):紧接着引导扇区的是两个完全相同的FAT表,每个FAT表占用9个扇区
3)根目录表:FAT表之后是根目录区,根目录区长度不固定
4)数据区
启动区结尾必须是 55AA
3. 补充学习
(1)notepad++命令行使用
(2)批处理----文件操作
操作 | 举例 |
---|---|
创建文件夹 | md folder |
删除文件夹 | rd folder |
创建文件 | cd.>file.bat |
删除文件 | del file.bat |
(3)批处理----echo(命令行回显,也可以完成文件写)
操作 | 举例 |
---|---|
显示当前状态 | echo |
开启/关闭回显 | echo on/off |
不回显命令本身 | @echo … |
显示信息 | echo message |
覆盖写入文件 | echo hello world>test.txt |
追加写入文件 | echo hello world>>test.txt |
(4) 批处理----参数传递与选择结构
echo %1
echo %2
if "%1"=="" (
echo no
) else (
echo yes)
4. 待解决
- 现在是假设把整个操作系统放在一个软盘里(1.4MB),第一个扇区是启动区(512B),但这个大小够吗?