mirror of https://github.com/kiukotsu/ucore.git
lab1-2
This commit is contained in:
parent
f64cb48d05
commit
a23ed1ce83
|
@ -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`。
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
file bin/kernel
|
||||
target remote :1234
|
||||
break kern_init
|
||||
continue
|
||||
set architecture i8086
|
||||
b *0x7c00
|
||||
continue
|
||||
x /2i $pc
|
||||
# break kern_init
|
||||
# continue
|
Loading…
Reference in New Issue