This commit is contained in:
kiukotsu 2018-12-03 21:39:27 +08:00
parent f64cb48d05
commit a23ed1ce83
5 changed files with 89 additions and 6 deletions

View File

@ -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`。

View File

@ -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 21ZF = 0,
jnz seta20.1 # %al 20ZF = 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
# 1613GDT0
# GDT
# 81912^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

View File

@ -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];
}
}

View File

@ -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();

View File

@ -1,4 +1,8 @@
file bin/kernel
target remote :1234
break kern_init
set architecture i8086
b *0x7c00
continue
x /2i $pc
# break kern_init
# continue