diff --git a/docs/lab1/练习一.md b/docs/lab1/练习一.md index 22becaf..58cc9de 100644 --- a/docs/lab1/练习一.md +++ b/docs/lab1/练习一.md @@ -115,7 +115,7 @@ dd if=bin/kernel of=bin/ucore.img seek=1 conv=notrunc | 编译选项 | 含义 | | :--------------------- | :----------------------------------------------------------: | -| `-I` | 指定库文件包含路径(① 指定值 ② 环境变量 ③ 标准系统搜索路径 | +| `-I` | 指定库文件包含路径(① 指定值 ② 环境变量 ③ 标准系统搜索路径) | | `-fno-builtin` | 只识别以 `__builtin_`为前缀的 GCC 內建函数,禁用大多数內建函数,防止与其重名 | | `-Wall` | 编译后显示所有[警告信息](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options) | | `-ggdb` | 使用 GDB 加入[调试信息](https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging-Options) | @@ -123,5 +123,53 @@ dd if=bin/kernel of=bin/ucore.img seek=1 conv=notrunc | `-gstabs` | 产生 stabs 格式的调试信息,不包含 GDB 扩展 | | `-nostdinc` | 不搜索标准系统目录的头文件,只搜索 `-I / -iquote / -isystem / -dirafter`指定的头文件, [目录选项](https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Directory-Options) | | `-fno-stack-protector` | 禁用堆栈保护机制,[工具选项](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#Instrumentation-Options) | -| | | +| `-c` | 编译或汇编源文件,但是不进行链接。将`.c/.i/.s`等后缀的文件编译成 `.o` 后缀。[输出类型控制](https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options) | +| `-O` | 优化生成的代码,`-Os` 仅仅是优化生成代码的大小,它开启了所有的`-O2`优化选项,除了那些会使代码尺寸增大的选项。 [优化选项](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options) | +**LD** [编译选项](https://sourceware.org/binutils/docs-2.31/ld/Options.html#Options)详解: + +| 编译选项 | 含义 | +| ------------------------------------- | :----------------------------------------------------------: | +| `-m` | 指定生成文件的格式,默认使用 `LDEMULATION`环境变量,如果没有这个环境变量,则依赖与linker 的默认配置。通过 `ld -V` 可以查看它支持的 `emulation`。 | +| `-nostdlib` | 只搜索命令行中显示制定的库目录,链接脚本里面制定的目录被忽略,包括命令行中制定的链接脚本。 | +| `-N` | 设置 `text and data section` 可读写,数据段不进行页对其,不链接动态链接库 | +| `-e entry` | 指定程序开始执行的入口函数,而不是默认的入口点。 | +| `-Tbss=org / -Tdata=org / -Ttext=org` | 通过 `org` 制定一个 `section` 在输出文件中的绝对地址。 | +| | | + +**dd** [磁盘维护命令](http://www.runoob.com/linux/linux-comm-dd.html)详解: + +``` +Linux dd命令用于读取、转换并输出数据。dd可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。 + +if = 文件名:输入文件名,缺省为标准输入。 +of = 文件名:输出文件名,缺省为标准输出。 + ibs = bytes:一次读入bytes个字节,即指定一个块大小为bytes个字节。(默认 512 字节) + obs = bytes:一次输出bytes个字节,即指定一个块大小为bytes个字节。(默认 512 字节) + bs = bytes:同时设置读入/输出的块大小为bytes个字节。 + cbs = bytes:一次转换bytes个字节,即指定转换缓冲区大小。 +skip = blocks:从输入文件开头跳过blocks个块后再开始复制。 +seek = blocks:从输出文件开头跳过blocks个块后再开始复制。 +count = blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数。 +conv = <关键字>,关键字可以有以下11种: + conversion:用指定的参数转换文件。 + ascii:转换ebcdic为ascii + ebcdic:转换ascii为ebcdic + ibm:转换ascii为alternate ebcdic + block:把每一行转换为长度为cbs,不足部分用空格填充 + unblock:使每一行的长度都为cbs,不足部分用空格填充 + lcase:把大写字符转换为小写字符 + ucase:把小写字符转换为大写字符 + swab:交换输入的每对字节 + noerror:出错时不停止 + notrunc:不截短输出文件 + sync:将每个输入块填充到ibs个字节,不足部分用空(NUL)字符补齐。 + +N and BYTES may be followed by the following multiplicative suffixes: +c =1, w =2, b =512, kB =1000, K =1024, MB =1000*1000, M =1024*1024, xM =M +GB =1000*1000*1000, G =1024*1024*1024, and so on for T, P, E, Z, Y. +``` + +**问题二**:一个被系统认为是符合规范的硬盘主引导扇区的特征是什么? + +**回答**:硬盘主引导扇区的 size = 512 Bytes,并且最后两个字节为`0x55AA`。 \ No newline at end of file diff --git a/labcodes/lab1/boot/bootasm.S b/labcodes/lab1/boot/bootasm.S index 3e64e21..c47ee09 100644 --- a/labcodes/lab1/boot/bootasm.S +++ b/labcodes/lab1/boot/bootasm.S @@ -26,10 +26,11 @@ start: # For backwards compatibility with the earliest PCs, physical # address line 20 is tied low, so that addresses higher than # 1MB wrap around to zero by default. This code undoes this. + seta20.1: inb $0x64, %al # Wait for not busy(8042 input buffer empty). - testb $0x2, %al - jnz seta20.1 + testb $0x2, %al # 如果 %al 第低2位为1,则ZF = 0, 则跳转 + jnz seta20.1 # 如果 %al 第低2位为0,则ZF = 1, 则不跳转 movb $0xd1, %al # 0xd1 -> port 0x64 outb %al, $0x64 # 0xd1 means: write data to 8042's P2 port @@ -42,6 +43,10 @@ seta20.2: movb $0xdf, %al # 0xdf -> port 0x60 outb %al, $0x60 # 0xdf = 11011111, means set P2's A20 bit(the 1 bit) to 1 + # 全局描述符表:存放8字节的段描述符,段描述符包含段的属性。 + # 段选择符:总共16位,高13位用作全局描述符表中的索引位,GDT的第一项总是设为0, + # 因此孔断选择符的逻辑地址会被认为是无效的,从而引起一个处理器异常。GDT表项 + # 最大数目是8191个,即2^13 - 1. # Switch from real to protected mode, using a bootstrap GDT # and segment translation that makes virtual addresses # identical to physical addresses, so that the diff --git a/labcodes/lab1/kern/debug/kdebug.c b/labcodes/lab1/kern/debug/kdebug.c index 27dded0..0f2d930 100644 --- a/labcodes/lab1/kern/debug/kdebug.c +++ b/labcodes/lab1/kern/debug/kdebug.c @@ -302,5 +302,20 @@ print_stackframe(void) { * NOTICE: the calling funciton's return addr eip = ss:[ebp+4] * the calling funciton's ebp = ss:[ebp] */ + uint32_t ebp = read_ebp(); + uint32_t eip = read_eip(); + int i, j; + for(i = 0; i < STACKFRAME_DEPTH && ebp != 0; i++) { + cprintf("ebp:0x%08x eip:0x%08x", ebp, eip); + uint32_t *arg = (uint32_t *)ebp + 2; + cprintf(" arg:"); + for(j = 0; j < 4; j++) { + cprintf("0x%08x ", arg[j]); + } + cprintf("\n"); + print_debuginfo(eip - 1); + eip = ((uint32_t *)ebp)[1]; + ebp = ((uint32_t*)ebp)[0]; + } } diff --git a/labcodes/lab1/kern/trap/trap.c b/labcodes/lab1/kern/trap/trap.c index af78676..7a2ef29 100644 --- a/labcodes/lab1/kern/trap/trap.c +++ b/labcodes/lab1/kern/trap/trap.c @@ -46,6 +46,13 @@ idt_init(void) { * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. * Notice: the argument of lidt is idt_pd. try to find it! */ + extern uintptr_t __vectors[]; + int i; + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { + SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); + } + SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); + lidt(&idt_pd); } static const char * @@ -147,6 +154,10 @@ trap_dispatch(struct trapframe *tf) { * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks(). * (3) Too Simple? Yes, I think so! */ + ticks++; + if (ticks % TICK_NUM == 0) { + print_ticks(); + } break; case IRQ_OFFSET + IRQ_COM1: c = cons_getc(); diff --git a/labcodes/lab1/tools/gdbinit b/labcodes/lab1/tools/gdbinit index abf6161..ab17c11 100644 --- a/labcodes/lab1/tools/gdbinit +++ b/labcodes/lab1/tools/gdbinit @@ -1,4 +1,8 @@ file bin/kernel target remote :1234 -break kern_init -continue \ No newline at end of file +set architecture i8086 +b *0x7c00 +continue +x /2i $pc +# break kern_init +# continue \ No newline at end of file