diff --git a/Makefile b/Makefile index a5320a8..9a47921 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ SRC := arch/x86/boot kernel mm drivers all: clean iso iso: build - ld -b elf64-x86-64 -z muldefs -o kernel.elf -T link.lds $(shell find $(SRC) -name "*.o") + ld -b elf64-x86-64 -z muldefs -o kernel.elf -Map=./kernel.map -T link.lds $(shell find $(SRC) -name "*.o") @bash build_iso.sh build: $(SRC) @@ -17,4 +17,7 @@ clean: $(SRC) @for s in $(SRC); do \ make -C $$s clean || exit 1; \ done - rm -rf *.elf *.iso + rm -rf *.elf *.iso *.map + +qemu-run: + qemu-system-x86_64 -m 2G HelloOS.iso diff --git a/README.md b/README.md index 7b40d3f..79d3ac2 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ 1. 安装依赖 ```bash -$ apt install -y make gcc grub git +$ apt install -y make gcc grub git xorriso ``` 2. 代码拉取 diff --git "a/docs/resources/Linux\350\256\276\345\244\207\351\251\261\345\212\250\347\250\213\345\272\217.pdf" "b/docs/resources/Linux\350\256\276\345\244\207\351\251\261\345\212\250\347\250\213\345\272\217.pdf" new file mode 100644 index 0000000..faeb316 Binary files /dev/null and "b/docs/resources/Linux\350\256\276\345\244\207\351\251\261\345\212\250\347\250\213\345\272\217.pdf" differ diff --git a/docs/resources/interceptor_descriptor.webp b/docs/resources/interceptor_descriptor.webp new file mode 100644 index 0000000..92f4a7e Binary files /dev/null and b/docs/resources/interceptor_descriptor.webp differ diff --git a/docs/resources/memory_addr.png b/docs/resources/memory_addr.png new file mode 100644 index 0000000..dcd5f7d Binary files /dev/null and b/docs/resources/memory_addr.png differ diff --git a/docs/resources/seg_gdtr.png b/docs/resources/seg_gdtr.png new file mode 100644 index 0000000..1e0634e Binary files /dev/null and b/docs/resources/seg_gdtr.png differ diff --git a/docs/resources/segment_descriptor.webp b/docs/resources/segment_descriptor.webp new file mode 100644 index 0000000..582706f Binary files /dev/null and b/docs/resources/segment_descriptor.webp differ diff --git a/docs/resources/segment_selector.webp b/docs/resources/segment_selector.webp new file mode 100644 index 0000000..eb5bbbd Binary files /dev/null and b/docs/resources/segment_selector.webp differ diff --git "a/docs/\345\210\206\346\256\265\345\210\206\351\241\265.md" "b/docs/\345\210\206\346\256\265\345\210\206\351\241\265.md" new file mode 100644 index 0000000..f1a83b6 --- /dev/null +++ "b/docs/\345\210\206\346\256\265\345\210\206\351\241\265.md" @@ -0,0 +1,37 @@ +## 内存地址 +![](./resources/memory_addr.png) + +* 逻辑地址:程序代码指令中的地址,可以认为是虚拟地址; +* 线性地址:逻辑地址经过分段计算后得到。在现代 x86-64 位操作系统中,线性地址和逻辑地址是一样的; +* 物理地址:线性地址经过 MMU 后,得到物理上真正地址; + + + +## 分段 + +段描述符:用于描述一个段的信息。在长模式下,其格式是: + + + +在操作系统中,多个段描述符组成一个描述符表。通过 gdtr(全局描述符寄存器)指向表的基地址。 + +> 还有一个 ldtr(局部描述符寄存器),现代操作系统都是通过分页来管理内存,分段处理只是为了兼容,ldtr 用的比较少,所以也不讨论 ldtr。 + +段选择子:通过段选择子可以确定该使用哪个段描述符: + + + +通过分段来计算线性地址流程: + +![](./resources/seg_gdtr.png) + +同理,在长模式下中断门描述符格式: + + + + + + + + + diff --git a/mm/mm.c b/mm/mm.c index 94240c4..1da1a99 100644 --- a/mm/mm.c +++ b/mm/mm.c @@ -52,7 +52,7 @@ void page_bitmap_init(uint_t start_addr) { gmdsc.total_mem_length = total_mem; gmdsc.page_bits = (uint_t*)start_addr; - gmdsc.page_bits_size = total_mem >> PAGE_4K_SHIFT; + gmdsc.page_bits_size = total_mem >> PAGE_4K_SHIFT; gmdsc.page_bits_length = (((uint_t)(total_mem >> PAGE_4K_SHIFT) + sizeof(uint_t) * 8 - 1) / 8) & ( ~ (sizeof(uint_t) - 1)); kinfo("page_bitmap start_addr:%x page_bits_size:%d page_bits_length:%d\n", gmdsc.page_bits, gmdsc.page_bits_size, gmdsc.page_bits_length); memset(gmdsc.page_bits, 0xff, gmdsc.page_bits_length);