diff --git a/devlog/devlog20191221.md b/devlog/devlog20191221.md index c9791dec4a554ad70bc7d5cb7ac525cc72504295..ec15c078f63b39ac1cb5b1b0aee4f8d9f726bef4 100644 --- a/devlog/devlog20191221.md +++ b/devlog/devlog20191221.md @@ -247,4 +247,42 @@ vmm_init å®Œæˆ - 总结: 有些项目的注释太å‘了ï¼ï¼ï¼æœ‰ä¸ªé¡¹ç›®æ³¨é‡Šå’Œä»£ç 是两个东西,我å´å¤©çœŸçš„相信了注释,然åŽé™·å…¥é€»è¾‘怪圈ä¸èƒ½è‡ªæ‹”,最åŽè¿˜æ˜¯æ‰‹æŽ¨äº†ä¸€é。。引以为戒引以为戒 + + + +# SimpleKernel 开呿—¥å¿— 20200115 + +将目å‰çš„进度 checkout 出去,顺便更新了 master 的进度 + +ä¿®å¤äº† Makefile 的一处 bug + +- å†™åˆæ¥çš„å †ç®¡ç† + + 首先由 pmm_alloc 获å–一个物ç†é¡µ + + å†ç”± map å‡½æ•°æ˜ å°„åˆ°æŒ‡å®šè™šæ‹Ÿåœ°å€ï¼Œè¿™ä¸ªè™šæ‹Ÿåœ°å€æ˜¯ä»Žå †åº•开始å‘ä¸Šå¢žåŠ çš„ï¼ˆä»¥é¡µä¸ºå•ä½ï¼‰ + + 以页为å•ä½åˆ†é…/回收,ä¸è€ƒè™‘页内空间 + + ​ + +- ä¿®å¤äº† map å‡½æ•°çš„å° bug,umap å¯èƒ½ä¹Ÿå˜åœ¨ + +æ·»åŠ äº†è¿›ç¨‹è°ƒåº¦çš„ç›¸å…³æ–‡ä»¶ + +把任务和调度分开æ¥ï¼Œä»»åŠ¡ä¸»è¦æ˜¯ task 的定义,创建ã€åœæ¢ç‰ + +调度是任务调度的算法 + + + +# SimpleKernel 开呿—¥å¿— 20200116 + +- 修改了链接脚本ä¸å®šä¹‰çš„å˜é‡åœ¨å†…æ ¸ä¸çš„声明 + +- å®Œæˆ heap + + åªæœ‰ç®€å•的链表管ç†ï¼ŒæŒ‰é¡µä¸ºå•ä½è¿›è¡Œåˆ†é…,已分é…的页ä¸ä¼šè¿›è¡Œ umap + +- 开始写 task diff --git a/devlog/devlog20200202.md b/devlog/devlog20200202.md new file mode 100644 index 0000000000000000000000000000000000000000..5e7d982ff3ce516cb3be43127a83464f79d2d284 --- /dev/null +++ b/devlog/devlog20200202.md @@ -0,0 +1,99 @@ +# SimpleKernel 开呿—¥å¿— 20200202 + +- åˆ é™¤äº†ä¹‹å‰è¿›ç¨‹ç›¸å…³çš„代ç ,é‡å†™ +- 在之å‰çš„æäº¤ä¸æ›´æ–°äº†ä»£ç é£Žæ ¼ + +- å…³äºŽä»»åŠ¡åˆ‡æ¢ + + 首先ä¿å˜æ—§ä»»åŠ¡ä¿¡æ¯ï¼š + + ​ cr3ï¼Œå†…æ ¸æ ˆï¼Œå¯„å˜å™¨ + + 将新任务的相关信æ¯å¡«å……进寄å˜å™¨ + + ​ cr3ï¼Œå†…æ ¸æ ˆï¼Œå¯„å˜å™¨ + + 开始执行新任务 + + ​ 指定 eip + + æ–°ä»»åŠ¡è¿”å›žåŽæ¢å¤æ—§ä»»åŠ¡çš„ä¿¡æ¯åˆ°å¯„å˜å™¨ä¸ + +- switch_to + + 这个函数一定è¦ç”¨å†…嵌汇编完æˆï¼Œå®ƒå®žé™…完æˆäº†ä»»åŠ¡åˆ‡æ¢çš„动作 + + proc->fork()->switch_to->sub_proc->fork()->proc + + å¦åˆ™çš„è¯æ˜¯æ— 法返回调用它的程åºçš„(指ä¸ä¿å˜é¢å¤–å˜é‡çš„æƒ…况下) + + + +å‘现内å˜åˆ†é…有 bug,这边先暂åœä¸€ä¸‹ï¼ŒæŠŠå†…å˜å…ˆå†™å®Œ + + + +# SimpleKernel 开呿—¥å¿— 20200203 + +ç»§ç»é‡å†™å†…å˜ç®¡ç† + +åæ±‡ç¼– pmm_init 的时候å‘现使用了 xmm 寄å˜å™¨ï¼ŒæŸ¥äº†ä¸€ä¸‹ï¼š + +`å› æ¤ï¼Œå†…æ ¸åªåœ¨æœ‰é™çš„场åˆä½¿ç”¨FPUã€MMX或XMM指令,比如移动或清除大内å˜åŒºå—段ã€è®¡ç®—æ ¡éªŒå’Œç‰ã€‚`(http://abcdxyzk.github.io/blog/2018/01/08/kernel-fpu-2/) + +æ˜¯å› ä¸ºåœ¨æ“作大å—结构体 e820map + +- é‡åˆ°äº†ä¸€ä¸ªæœ‰è¶£çš„ bug + + 在 pmm.c 䏿œ‰è¿™ä¹ˆä¸€è¡Œä»£ç + + `e820map->map[e820map->nr_map].length = len;` + + 直接执行的è¯ä¼šå‡º INT_INVALID_OPCODE 䏿–,百æ€ä¸å¾—其解,最åŽå汇编的时候å‘现使用了 xmm 寄å˜å™¨ï¼Œç„¶åŽé€ä¸€æŠŠä¸ªè¯å¥åˆ†è§£åŽå‘现。åªè¦æœ‰ xmm1 寄å˜å™¨å‡ºçŽ°å°±ä¸€å®šä¼š INT_INVALID_OPCODEï¼ŒåŽŸå› æˆ‘çŒœæœ‰è¿™ä¹ˆå‡ ç‚¹å¯èƒ½ï¼š + + 1. 没有åˆå§‹åŒ– FPU + 2. 32 ä½ä»£ç 䏿”¯æŒ + 3. æ°´å¹³ä¸å¤Ÿæƒ³ä¸æ¥äº† + + 解决方案: + + 1. åœ¨ç¼–è¯‘é€‰é¡¹é‡Œæ·»åŠ -mno-see ç¦æ¢ç”Ÿæˆ see 指令 + 2. 分解代ç ,直到编译器生æˆä¸ä½¿ç”¨ xmm 的汇编代ç + + åˆ°åº•æ˜¯å•¥é—®é¢˜çœ‹äº†ä¸€åœˆèµ„æ–™ä¹Ÿæ²¡æžæ˜Žç™½ï¼Œä»¥åŽå¦‚æžœé‡åˆ°å›žæ¥çœ‹ä¸€ä¸‹**[MARK]** + +- 写 first fit 算法 + + 感觉æ€è·¯ä¸å¤ªå¯¹ï¼Œæ˜Žå¤©ç»§ç» + + + +# SimpleKernel 开呿—¥å¿— 20200204 + +ç»§ç»å†™ ff,现在的问题是如何分é…ä¿å˜ç‰©ç†å†…å˜ä¿¡æ¯çš„内å˜ã€‚ + +ç›´æŽ¥å†™æˆæ•°ç»„çš„è¯ä¼šå¯¼è‡´ bss 段过大,有 3MB+ + +- 解决方案 + + åœ¨å†…æ ¸ç»“æŸåŽå˜æ”¾ç›¸å…³ç»“构体,首先得把 bootinit.c 里é¢è™šæ‹Ÿå†…å˜æ˜ å°„åŠ åˆ° 8MB + + 第二需è¦åœ¨ä»£ç 里手动分é…空间,firstfit.c ä¸çš„ pmm_info å˜é‡åšäº†è¿™ä»¶äº‹ + +ç›®å‰åŸºæœ¬ç¨³å®š + +新的问题:multiboot 返回的 mmap ç»“æž„æ˜¯æ ¹æ®ä»€ä¹ˆå¾—出的? + +按我的写法,实际上物ç†å†…å˜çš„å‰ 8MB 是ä¸èƒ½ç”¨çš„,å¦åˆ™ä¼šè¦†ç›–å†…æ ¸æ•°æ®ï¼Œä½†æ˜¯å®ƒç»™å‡ºçš„布局图显示从 1MB 开始是å¯ç”¨å†…å˜ï¼Œè¿˜ä¸æ¸…æ¥šè¿™ä¸¤è€…çš„å…³ç³»æ˜¯æ€Žæ ·çš„ + + + +# SimpleKernel 开呿—¥å¿— 20200205 + +昨天的问题想通了,mmap çš„åœ°å€æ˜¯ç†è®ºä¸Šå¯ç”¨çš„地å€ï¼Œå®žé™…ä¸Šå› ä¸ºå†…æ ¸æ˜¯ä»Žç‰©ç†åœ°å€ 1MB 处开始的,所以实际å¯ç”¨å†…å˜æ˜¯ mmap çš„å¯ç”¨å†…å˜å‡åŽ»å†…æ ¸å 用的空间,å¯ç”¨å†…å˜å¼€å§‹åœ°å€ä¸º1MB+å†…æ ¸å¤§å° + +ä¿®å¤äº† ff 内å˜åˆ†é…çš„ä¸€ä¸ªå° bug + +åŸºæœ¬å®Œæˆ ff free 函数 + +基本内å˜ç®¡ç†å¤§è‡´å®Œæˆï¼Œä¸‹ä¸€æ¥å¼€å§‹å†™å †ç®¡ç† \ No newline at end of file diff --git a/iso/boot/kernel.bin b/iso/boot/kernel.bin index a9a4bf91e3fa3ac9ff8a84cc3c850dcfc3c68068..24b9384eba7f17401a121a5596ecd3443bbe7b4c 100755 Binary files a/iso/boot/kernel.bin and b/iso/boot/kernel.bin differ diff --git "a/related_docs/Linux\345\206\205\346\240\270\346\265\205\346\236\220-\350\277\233\347\250\213\350\260\203\345\272\246\346\227\266\346\234\272\345\222\214\350\277\207\347\250\213 - \347\237\245\344\271\216.pdf" "b/related_docs/Linux\345\206\205\346\240\270\346\265\205\346\236\220-\350\277\233\347\250\213\350\260\203\345\272\246\346\227\266\346\234\272\345\222\214\350\277\207\347\250\213 - \347\237\245\344\271\216.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..42df72eec3375141baf9e9201904b7579a0b2584 Binary files /dev/null and "b/related_docs/Linux\345\206\205\346\240\270\346\265\205\346\236\220-\350\277\233\347\250\213\350\260\203\345\272\246\346\227\266\346\234\272\345\222\214\350\277\207\347\250\213 - \347\237\245\344\271\216.pdf" differ diff --git a/related_docs/README.md b/related_docs/README.md deleted file mode 100644 index 76adc0f9fb0b6ac9a3c8af9e4246a1f14e980e7f..0000000000000000000000000000000000000000 --- a/related_docs/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# someknowledge/ -## 文件说明 - -è¿™ä¸ªç›®å½•ä¸‹å˜æ”¾çš„æ˜¯åœ¨å†™ä»£ç 过程ä¸é‡åˆ°çš„一些问题,我把我ä¸å¤ªç†è§£çš„东西整ç†äº†ä¸€ä¸‹æ”¾åœ¨è¿™é‡Œã€‚ - diff --git a/simplekernel.iso b/simplekernel.iso index 4411236f5769df90065c0fc7fde8bd84d78b183e..516a5bd50924d3b490e36c717f449fb43ed44265 100644 Binary files a/simplekernel.iso and b/simplekernel.iso differ diff --git a/src/Makefile b/src/Makefile index 0b8649a953eee155020198513e50389bea1465cd..ea60672acf3d41b273b66066f2638b71480acbef 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ # This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). # -# Makefile.env for MRNIU/SimpleKernel. +# Makefile for MRNIU/SimpleKernel. # 设置 make 环境 @@ -43,6 +43,8 @@ clean: @echo æ£åœ¨åˆ 除... $< @find . -name "*.o" | xargs rm -f @find . -name "*.gch" | xargs rm -f + @rm -f *.map + @rm -f *.nm @rm -f *.bin @for subdir in $(SUB_DIR); \ do $(MAKE) -C $$subdir clean || exit 1; \ @@ -99,11 +101,17 @@ code_line_count: .PHONY: generate_map generate_map: - $(READELF) -s $(IMAGE) >> $(MAP) + $(READELF) -s $(IMAGE_KERNEL) >> $(RES_KERNEL_MAP) +ifeq ($(ARCH),x86_64) + $(READELF) -s $(IMAGE_BOOT) >> $(RES_BOOT_MAP) +endif .PHONY: generate_nm generate_nm: - $(NM) $(IMAGE) + $(NM) $(IMAGE_KERNEL) >> $(RES_KERNEL_NM) +ifeq ($(ARCH),x86_64) + $(NM) $(IMAGE_BOOT) >> $(RES_BOOT_NM) +endif .PHONY: info info: diff --git a/src/Makefile.env b/src/Makefile.env index d5d93ba7fa2c3c798361de5c35afaab94301c227..92fb6ab299583137ef4c545925d016775fc795a4 100644 --- a/src/Makefile.env +++ b/src/Makefile.env @@ -17,6 +17,12 @@ OBJCPY = $(TARGET)-objcopy STRIP = $(TARGET)-strip NM = $(TARGET)-gcc-nm READELF = $(TARGET)-readelf +IMAGE_KERNEL = kernel.bin +IMAGE_BOOT = bootloader.bin +RES_KERNEL_MAP = kernel.map +RES_BOOT_MAP = bootloader.map +RES_KERNEL_NM = kernel.nm +RES_BOOT_NM = bootloader.nm mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) ROOT_DIR := $(patsubst %/,%,$(dir $(mkfile_path))) @@ -45,6 +51,7 @@ CXXFLAGS = -std=c++11 -ffreestanding -nostdinc -nostdlib -fno-exceptions -fno-rt CFLAGS = -std=gnu11 -ffreestanding -nostdinc -nostdlib -fno-exceptions -nostartfiles \ -fno-builtin -O2 -Wall -Wextra -Wshadow -Wunreachable-code -Winline \ -Wmissing-prototypes -Wsign-compare \ + -mno-sse \ -g -ggdb -C -c \ -I$(LIBC_DIR) -I$(ARCH_DIR) -I$(DRV_DIR) -I$(KERNEL_DIR) -I$(BOOT_DIR) \ -I$(INCLUDE_DIR) -I$(DATASTRUCTURE_DIR) #-v diff --git a/src/arch/x86_64/README.md b/src/arch/x86_64/README.md index 3b2d88bc15ad0774f9f2b3ea51f311f42f0a52e4..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/src/arch/x86_64/README.md +++ b/src/arch/x86_64/README.md @@ -1,15 +0,0 @@ -# src/arch/i386/ -## 文件说明 - -- boot.s - - å¯åЍ代ç ,使用 Grub 引导。 - -- link.ld - - 链接脚本,规定了生æˆç¨‹åºåœ°å€ç©ºé—´çš„布局。 - -## å‚考资料 - -[系统åˆå§‹åŒ–](https://wiki.osdev.org/Bare_Bones) - diff --git a/src/arch/x86_64/arch_init.c b/src/arch/x86_64/arch_init.c new file mode 100644 index 0000000000000000000000000000000000000000..d85706b5bb2818664caefedab4bd074f4d12b734 --- /dev/null +++ b/src/arch/x86_64/arch_init.c @@ -0,0 +1,28 @@ + +// This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). +// +// arch_init.c for MRNIU/SimpleKernel. + +#ifdef __cplusplus +extern "C" { +#endif + +#include "cpu.hpp" +#include "intr/include/intr.h" +#include "gdt/include/gdt.h" +#include "arch_init.h" + +void arch_init(void) { + cpu_cli(); + // GDT åˆå§‹åŒ– + gdt_init(); + // IDT åˆå§‹åŒ– + intr_init(); + cpu_sti(); + return; +} + + +#ifdef __cplusplus +} +#endif diff --git a/src/arch/x86_64/boot/Makefile b/src/arch/x86_64/boot/Makefile index 083aa10e6779d8f3f6e98168be3109bec2a5cfb2..06e0a116533b57a3c1d47c86a766a2915d16b5b3 100644 --- a/src/arch/x86_64/boot/Makefile +++ b/src/arch/x86_64/boot/Makefile @@ -28,7 +28,7 @@ all: $(SUB_DIR) done @# $(MAKE) info @$(MAKE) boot.o - # @$(MAKE) bootinit.o + @# $(MAKE) bootinit.o @$(MAKE) $(patsubst %.c, %.o, $(wildcard *.c)) @echo Leave $(CURR_DIR) diff --git a/src/arch/x86_64/boot/bootinit.c b/src/arch/x86_64/boot/bootinit.c index 58e9ed440472bfbd79bc1f7cbc35f9e45c4a31c9..4803e3cb2096c5dcc5ac0ed5e09868065c83da27 100644 --- a/src/arch/x86_64/boot/bootinit.c +++ b/src/arch/x86_64/boot/bootinit.c @@ -7,6 +7,9 @@ extern "C" { #endif +#include "stdio.h" +#include "mem/pmm.h" +#include "mem/vmm.h" #include "include/bootinit.h" // When writing a higher-half kernel, the steps required are: @@ -17,6 +20,12 @@ extern "C" { // 5. Jump to higher half. // 6. Remove the lower half kernel mapping. +// å¼€å¯åˆ†é¡µæœºåˆ¶ä¹‹åŽçš„å†…æ ¸æ ˆ +uint8_t kernel_stack[STACK_SIZE] __attribute__( (aligned(STACK_SIZE) ) ); + +// å†…æ ¸æ ˆé¡¶ +ptr_t kernel_stack_top = ( (ptr_t)kernel_stack + STACK_SIZE); + void enable_page(pgd_t * pgd) { // 设置临时页表 __asm__ volatile ("mov %0, %%cr3" : : "r" (pgd) ); @@ -32,22 +41,29 @@ void enable_page(pgd_t * pgd) { void mm_init() { // init 段, 4MB // å› ä¸º mm_init 返回åŽä»ç„¶åœ¨ init æ®µï¼Œä¸æ˜ å°„çš„è¯ä¼šçˆ†ç‚¸çš„ - pgd_tmp[0] = (uint32_t)pte_init | VMM_PAGE_PRESENT | VMM_PAGE_RW; + pgd_tmp[0] = (ptr_t)pte_init | VMM_PAGE_PRESENT | VMM_PAGE_RW; // å†…æ ¸æ®µ pgd_tmp[0x300], 4MB - pgd_tmp[VMM_PGD_INDEX(KERNEL_BASE)] = (uint32_t)pte_kernel | VMM_PAGE_PRESENT | VMM_PAGE_RW; + pgd_tmp[VMM_PGD_INDEX(KERNEL_BASE)] = (ptr_t)pte_kernel_tmp | VMM_PAGE_PRESENT | VMM_PAGE_RW; + // å†…æ ¸æ®µ pgd_tmp[0x301], 4MB + pgd_tmp[VMM_PGD_INDEX(KERNEL_BASE) + 1] = (ptr_t)pte_kernel_tmp2 | VMM_PAGE_PRESENT | VMM_PAGE_RW; // æ˜ å°„å†…æ ¸è™šæ‹Ÿåœ°å€ 4MB 到物ç†åœ°å€çš„å‰ 4MB // å°†æ¯ä¸ªé¡µè¡¨é¡¹èµ‹å€¼ // pgd_tmp[0] => pte_init for(uint32_t i = 0 ; i < VMM_PAGES_PRE_PAGE_TABLE ; i++) { + // 物ç†åœ°å€ç”± (i << 12) 给出 pte_init[i] = (i << 12) | VMM_PAGE_PRESENT | VMM_PAGE_RW; } // æ˜ å°„ kernel 段 4MB - // æ˜ å°„ 0x00000000-0x00400000 的物ç†åœ°å€åˆ°è™šæ‹Ÿåœ°å€ 0xC0000000-0xC0400000 + // æ˜ å°„è™šæ‹Ÿåœ°å€ 0xC0000000-0xC0400000 到物ç†åœ°å€ 0x00000000-0x00400000 // pgd_tmp[0x300] => pte_kernel - for(uint32_t i = 0 ; i < VMM_PAGES_PRE_PAGE_TABLE ; i++) { - pte_kernel[i] = (i << 12) | VMM_PAGE_PRESENT | VMM_PAGE_RW; + for(uint32_t i = 0 ; i < VMM_PAGES_PRE_PAGE_TABLE ; i++) { + pte_kernel_tmp[i] = (i << 12) | VMM_PAGE_PRESENT | VMM_PAGE_RW; + } + // æ˜ å°„è™šæ‹Ÿåœ°å€ 0xC0400000-0xC0800000 到物ç†åœ°å€ 0x00400000-0x00800000 + for(uint32_t i = 0, j = VMM_PAGES_PRE_PAGE_TABLE ; i < VMM_PAGES_PRE_PAGE_TABLE ; i++, j++) { + pte_kernel_tmp2[i] = (j << 12) | VMM_PAGE_PRESENT | VMM_PAGE_RW; } enable_page(pgd_tmp); diff --git a/src/arch/x86_64/boot/include/bootinit.h b/src/arch/x86_64/boot/include/bootinit.h index 4ce5e916e231656afd2c983c430917fe5d0472ee..1e204aa5149737f8c99d044f010ed1c9fe1c9bf3 100644 --- a/src/arch/x86_64/boot/include/bootinit.h +++ b/src/arch/x86_64/boot/include/bootinit.h @@ -21,25 +21,22 @@ extern "C" { // #endif #include "stdint.h" -#include "stdbool.h" -#include "stdio.h" -#include "mem/pmm.h" -#include "mem/vmm.h" // å†…æ ¸ä½¿ç”¨çš„ä¸´æ—¶é¡µè¡¨å’Œé¡µç›®å½• // ç”¨äºŽæ˜ å°„ init æ®µä¸Žå†…æ ¸æ®µ -__attribute__( (section(".init.data") ) ) pgd_t pgd_tmp[VMM_PAGE_TABLES_PRE_PAGE_DIRECTORY] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); +__attribute__( (section(".init.data") ) ) +pgd_t pgd_tmp[VMM_PAGE_TABLES_PRE_PAGE_DIRECTORY] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); // init 段 -__attribute__( (section(".init.data") ) ) pte_t pte_init[VMM_PAGES_PRE_PAGE_TABLE] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); -// å†…æ ¸æ®µ -__attribute__( (section(".init.data") ) ) pte_t pte_kernel[VMM_PAGES_PRE_PAGE_TABLE] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); - - -// å¼€å¯åˆ†é¡µæœºåˆ¶ä¹‹åŽçš„å†…æ ¸æ ˆ -uint8_t kernel_stack[STACK_SIZE] __attribute__( (aligned(STACK_SIZE) ) ); - -// å†…æ ¸æ ˆé¡¶ -ptr_t kernel_stack_top = ( (ptr_t)kernel_stack + STACK_SIZE); +__attribute__( (section(".init.data") ) ) +pte_t pte_init[VMM_PAGES_PRE_PAGE_TABLE] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); +// å†…æ ¸æ®µï¼Œå…± 8MB +__attribute__( (section(".init.data") ) ) +pte_t pte_kernel_tmp[VMM_PAGES_PRE_PAGE_TABLE] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); +__attribute__( (section(".init.data") ) ) +pte_t pte_kernel_tmp2[VMM_PAGES_PRE_PAGE_TABLE] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); +// å†…æ ¸æ ˆæ®µ(还没用上) +__attribute__( (section(".init.data") ) ) +pte_t pte_stack_tmp[VMM_PAGES_PRE_PAGE_TABLE] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); __attribute__( (section(".init.text") ) ) void kernel_entry(ptr_t magic, ptr_t addr); __attribute__( (section(".init.text") ) ) void enable_page(pgd_t * pgd); diff --git a/src/arch/x86_64/cpu.hpp b/src/arch/x86_64/cpu.hpp index 5134e7e50b824439fe1d63a0f888cf1e6b9c2c76..59a09c497ff1446ff2060cf08744639a6f8bc55c 100644 --- a/src/arch/x86_64/cpu.hpp +++ b/src/arch/x86_64/cpu.hpp @@ -105,60 +105,60 @@ extern "C" { // 执行CPU空æ“作 static inline void cpu_hlt(void) { - __asm__ volatile ( "hlt" ); + __asm__ volatile ("hlt"); return; } // å¼€å¯ä¸æ– static inline void cpu_sti(void) { - __asm__ volatile ( "sti" ); + __asm__ volatile ("sti"); return; } // å…³é—䏿– static inline void cpu_cli(void) { - __asm__ volatile ( "cli" ::: "memory" ); + __asm__ volatile ("cli" ::: "memory"); return; } static inline void debug_intr(void) { - __asm__ volatile ( "int $0x01" ); + __asm__ volatile ("int $0x01"); return; } // è¯»å– EFLAGS static inline uint32_t read_eflags(void) { uint32_t eflags; - __asm__ volatile ( "pushf;pop %0" - : "=r" ( eflags ) ); + __asm__ volatile ("pushf;pop %0" + : "=r" (eflags) ); return eflags; } // è¯»å– CR0 static inline uint32_t cpu_read_cr0(void) { uint32_t cr0; - __asm__ volatile ("mov %%cr0, %0" : "=b" (cr0)); + __asm__ volatile ("mov %%cr0, %0" : "=b" (cr0) ); return cr0; } // è¯»å– CR2 static inline uint32_t cpu_read_cr2(void) { uint32_t cr2; - __asm__ volatile ("mov %%cr2, %0" : "=b" (cr2)); + __asm__ volatile ("mov %%cr2, %0" : "=b" (cr2) ); return cr2; } // è¯»å– CR3 static inline uint32_t cpu_read_cr3(void) { uint32_t cr3; - __asm__ volatile ("mov %%cr3, %0" : "=b" (cr3)); + __asm__ volatile ("mov %%cr3, %0" : "=b" (cr3) ); return cr3; } // è¯»å– CR4 static inline uint32_t cpu_read_cr4(void) { uint32_t cr4; - __asm__ volatile ("mov %%cr4, %0" : "=b" (cr4)); + __asm__ volatile ("mov %%cr4, %0" : "=b" (cr4) ); return cr4; } @@ -166,7 +166,7 @@ static inline uint32_t cpu_read_cr4(void) { //程åºèƒ½å¤Ÿè®¾ç½®æˆ–æ¸…é™¤è¿™ä¸ªæ ‡å¿—æŒ‡ç¤ºäº†å¤„ç†å™¨å¯¹ CPUID 指令的支æŒã€‚ static inline bool FL_ID_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_ID ); + return (eflags & EFLAGS_ID); } // Virtual interrupt pending flag @@ -175,7 +175,7 @@ static inline bool FL_ID_status(void) { static inline bool EFLAGS_VIP_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_VIP ); + return (eflags & EFLAGS_VIP); } // Virtual interrupt flag @@ -183,45 +183,45 @@ static inline bool EFLAGS_VIP_status(void) { // ä½¿ç”¨è¿™ä¸ªæ ‡å¿—ä»¥åŠVIPæ ‡å¿—ï¼Œå¹¶è®¾ç½®CR4控制寄å˜å™¨ä¸çš„VMEæ ‡å¿—å°±å¯ä»¥å…è®¸è™šæ‹Ÿæ¨¡å¼æ‰©å±•(virtual mode extensions) static inline bool EFLAGS_VIF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_VIF ); + return (eflags & EFLAGS_VIF); } // Alignment check flag 地å€ä¸çš„坹齿£€æŸ¥ static inline bool EFLAGS_AC_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_AC ); + return (eflags & EFLAGS_AC); } // 虚拟 8086 ,为 1 时进入 static inline bool EFLAGS_VM_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_VM ); + return (eflags & EFLAGS_VM); } // Resume flag 控制处ç†å™¨å¯¹è°ƒè¯•异常的å“应。 static inline bool EFLAGS_RF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_RF ); + return (eflags & EFLAGS_RF); } // Nested task flag // è¿™ä¸ªæ ‡å¿—æŽ§åˆ¶ä¸æ–链和被调用任务。若当å‰ä»»åŠ¡ä¸Žå‰ä¸€ä¸ªæ‰§è¡Œä»»åŠ¡ç›¸å…³åˆ™ç½® 1,å之则清零。 static inline bool EFLAGS_NT_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_NT ); + return (eflags & EFLAGS_NT); } // æƒé™æ ‡å¿— static inline uint32_t get_IOPL(void) { uint32_t eflags = read_eflags(); uint32_t level = 0; - if (eflags & EFLAGS_IOPL_0) + if(eflags & EFLAGS_IOPL_0) level = 0; - else if (eflags & EFLAGS_IOPL_1) + else if(eflags & EFLAGS_IOPL_1) level = 1; - else if (eflags & EFLAGS_IOPL_2) + else if(eflags & EFLAGS_IOPL_2) level = 2; - else if (eflags & EFLAGS_IOPL_3) + else if(eflags & EFLAGS_IOPL_3) level = 3; else return 2333; return level; @@ -230,7 +230,7 @@ static inline uint32_t get_IOPL(void) { // æº¢å‡ºæ ‡å¿— static inline bool EFLAGS_OF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_OF ); + return (eflags & EFLAGS_OF); } // 控制串指令(MOVS, CMPS, SCAS, LODS以åŠSTOS)。 @@ -239,188 +239,188 @@ static inline bool EFLAGS_OF_status(void) { // STD以åŠCLDæŒ‡ä»¤åˆ†åˆ«ç”¨äºŽè®¾ç½®ä»¥åŠæ¸…除DFæ ‡å¿—ã€‚ static inline bool EFLAGS_DF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_DF ); + return (eflags & EFLAGS_DF); } // 䏿–æ ‡å¿— static inline bool EFLAGS_IF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_IF ); + return (eflags & EFLAGS_IF); } static inline bool EFLAGS_TF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_TF ); + return (eflags & EFLAGS_TF); } // Sign flag ç¬¦å·æ ‡å¿— static inline bool EFLAGS_SF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_SF ); + return (eflags & EFLAGS_SF); } // Zero flag é›¶æ ‡å¿— static inline bool EFLAGS_ZF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_ZF ); + return (eflags & EFLAGS_ZF); } // Adjust flagè°ƒæ•´ä½ static inline bool EFLAGS_AF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_AF ); + return (eflags & EFLAGS_AF); } // Parity flag奇å¶ä½ static inline bool EFLAGS_PF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_PF ); + return (eflags & EFLAGS_PF); } // Carry flag è¿›ä½æ ‡å¿— static inline bool EFLAGS_CF_status(void) { uint32_t eflags = read_eflags(); - return ( eflags & EFLAGS_CF ); + return (eflags & EFLAGS_CF); } -static inline void __native_flush_tlb_single(ptr_t addr) { - __asm__ volatile ( "invlpg (%0)" : : "r" ( addr ) : "memory" ); +static inline void CPU_INVLPG(ptr_t addr) { + __asm__ volatile ("invlpg (%0)" : : "r" (addr) : "memory"); return; } static inline bool CR4_VME_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_VME ); + return (cr4 & CR4_VME); } static inline bool CR4_PVI_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_PVI ); + return (cr4 & CR4_PVI); } static inline bool CR4_TSD_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_TSD ); + return (cr4 & CR4_TSD); } static inline bool CR4_DE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_DE ); + return (cr4 & CR4_DE); } static inline bool CR4_PSE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_PSE ); + return (cr4 & CR4_PSE); } static inline bool CR4_PAE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_PAE ); + return (cr4 & CR4_PAE); } static inline bool CR4_MCE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_MCE ); + return (cr4 & CR4_MCE); } static inline bool CR4_PGE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_PGE ); + return (cr4 & CR4_PGE); } static inline bool CR4_PCE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_PCE ); + return (cr4 & CR4_PCE); } static inline bool CR4_OSFXSR_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_OSFXSR ); + return (cr4 & CR4_OSFXSR); } static inline bool CR4_OSXMMEXCPT_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_OSXMMEXCPT ); + return (cr4 & CR4_OSXMMEXCPT); } static inline bool CR4_VMXE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_VMXE ); + return (cr4 & CR4_VMXE); } static inline bool CR4_SMXE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_SMXE ); + return (cr4 & CR4_SMXE); } static inline bool CR4_PCIDE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_PCIDE ); + return (cr4 & CR4_PCIDE); } static inline bool CR4_OSXSAVE_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_OSXSAVE ); + return (cr4 & CR4_OSXSAVE); } static inline bool CR4_SMEP_status(void) { uint32_t cr4 = cpu_read_cr4(); - return ( cr4 & CR4_SMEP ); + return (cr4 & CR4_SMEP); } static inline bool CR0_PE_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_PE ); + return (cr0 & CR0_PE); } static inline bool CR0_MP_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_MP ); + return (cr0 & CR0_MP); } static inline bool CR0_EM_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_EM ); + return (cr0 & CR0_EM); } static inline bool CR0_TS_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_TS ); + return (cr0 & CR0_TS); } static inline bool CR0_ET_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_ET ); + return (cr0 & CR0_ET); } static inline bool CR0_NE_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_NE ); + return (cr0 & CR0_NE); } static inline bool CR0_WP_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_WP ); + return (cr0 & CR0_WP); } static inline bool CR0_AM_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_AM ); + return (cr0 & CR0_AM); } static inline bool CR0_NW_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_NW ); + return (cr0 & CR0_NW); } static inline bool CR0_CD_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_CD ); + return (cr0 & CR0_CD); } static inline bool CR0_PG_status(void) { uint32_t cr0 = cpu_read_cr0(); - return ( cr0 & CR0_PG ); + return (cr0 & CR0_PG); } #ifdef __cplusplus diff --git a/src/arch/x86_64/debug/debug.c b/src/arch/x86_64/debug/debug.c index 13c453ac390afe3c988305001449bcf5dc7b4c89..47c5bab4083d14a39d55eceea7ca444673d337cc 100644 --- a/src/arch/x86_64/debug/debug.c +++ b/src/arch/x86_64/debug/debug.c @@ -7,11 +7,17 @@ extern "C" { #endif +#include "stddef.h" +#include "stdio.h" +#include "intr/include/intr.h" +#include "cpu.hpp" #include "debug.h" void debug_init(ptr_t magic UNUSED, ptr_t addr UNUSED) { + cpu_cli(); printk_debug("debug_init\n"); // multiboot2_init(magic, addr); + cpu_sti(); return; } @@ -19,10 +25,10 @@ void print_cur_status() { static uint32_t round = 0; uint16_t reg1, reg2, reg3, reg4; asm volatile ("mov %%cs, %0;" - "mov %%ds, %1;" - "mov %%es, %2;" - "mov %%ss, %3;" - : "=m" (reg1), "=m" (reg2), "=m" (reg3), "=m" (reg4) ); + "mov %%ds, %1;" + "mov %%es, %2;" + "mov %%ss, %3;" + : "=m" (reg1), "=m" (reg2), "=m" (reg3), "=m" (reg4) ); // 打å°å½“å‰çš„è¿è¡Œçº§åˆ« printk_debug("%d: @ring %d\n", round, reg1 & 0x3); diff --git a/src/arch/x86_64/init/Makefile b/src/arch/x86_64/gdt/Makefile similarity index 100% rename from src/arch/x86_64/init/Makefile rename to src/arch/x86_64/gdt/Makefile diff --git a/src/arch/x86_64/init/gdt.c b/src/arch/x86_64/gdt/gdt.c similarity index 85% rename from src/arch/x86_64/init/gdt.c rename to src/arch/x86_64/gdt/gdt.c index 524f10b35c070aac85a049a35994298c9af5f059..5142afb15709782373d552bb4dca4a188e11fc1b 100644 --- a/src/arch/x86_64/init/gdt.c +++ b/src/arch/x86_64/gdt/gdt.c @@ -7,8 +7,19 @@ extern "C" { #endif +#include "stdio.h" +#include "debug.h" +#include "cpu.hpp" #include "include/gdt.h" +static gdt_ptr_t gdt_ptr; +// 全局æè¿°ç¬¦è¡¨å®šä¹‰ +static gdt_entry_t gdt_entries[GDT_LENGTH] __attribute__( (aligned(8) ) ); + +// TSS 段定义 +static tss_entry_t tss_entry __attribute__( (aligned(8) ) ); +static void tss_set_gate(int32_t num, uint16_t ss0, uint32_t esp0); + void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { gdt_entries[num].base_low = (base & 0xFFFF); gdt_entries[num].base_middle = (base >> 16) & 0xFF; @@ -21,7 +32,7 @@ void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, ui gdt_entries[num].access = access; } -static void tss_set_gate(int32_t num, uint16_t ss0, uint32_t esp0) { +void tss_set_gate(int32_t num, uint16_t ss0, uint32_t esp0) { // èŽ·å– TSS æè¿°ç¬¦çš„ä½ç½®å’Œé•¿åº¦ uint32_t base = (uint32_t)&tss_entry; uint32_t limit = base + sizeof(tss_entry); @@ -42,6 +53,7 @@ static void tss_set_gate(int32_t num, uint16_t ss0, uint32_t esp0) { // åˆå§‹åŒ–全局æè¿°ç¬¦è¡¨ void gdt_init(void) { + cpu_cli(); // 全局æè¿°ç¬¦è¡¨ç•Œé™ 从 0 å¼€å§‹ï¼Œæ‰€ä»¥æ€»é•¿è¦ - 1 gdt_ptr.limit = sizeof(gdt_entry_t) * GDT_LENGTH - 1; gdt_ptr.base = (uint32_t)&gdt_entries; @@ -61,6 +73,8 @@ void gdt_init(void) { tss_load(); printk_info("gdt_init\n"); + cpu_sti(); + return; } #ifdef __cplusplus diff --git a/src/arch/x86_64/init/gdt_s.s b/src/arch/x86_64/gdt/gdt_s.s similarity index 100% rename from src/arch/x86_64/init/gdt_s.s rename to src/arch/x86_64/gdt/gdt_s.s diff --git a/src/arch/x86_64/init/include/gdt.h b/src/arch/x86_64/gdt/include/gdt.h similarity index 58% rename from src/arch/x86_64/init/include/gdt.h rename to src/arch/x86_64/gdt/include/gdt.h index 935fe2604dfc9bc84cf435a55175ee974dc70b74..4a4d83695130c88ff75b9b2fc6f1156dee9c5e3a 100644 --- a/src/arch/x86_64/init/include/gdt.h +++ b/src/arch/x86_64/gdt/include/gdt.h @@ -11,8 +11,6 @@ extern "C" { #endif #include "stdint.h" -#include "stdio.h" -#include "debug.h" #define GDT_LENGTH 6 // 全局æè¿°ç¬¦è¡¨é•¿åº¦ // å„ä¸ªå†…å˜æ®µæ‰€åœ¨å…¨å±€æè¿°ç¬¦è¡¨ä¸‹æ ‡ @@ -43,30 +41,24 @@ extern "C" { #define UREAD_EXEC 0xFA #define UREAD_WRITE 0xF2 - // 全局æè¿°ç¬¦ç±»åž‹ typedef - struct gdt_entry_t { - uint16_t limit_low; // æ®µç•Œé™ 15~0 - uint16_t base_low; // æ®µåŸºåœ°å€ 15~0 - uint8_t base_middle; // æ®µåŸºåœ°å€ 23~16 - uint8_t access; // 段å˜åœ¨ä½ã€æè¿°ç¬¦ç‰¹æƒçº§ã€æè¿°ç¬¦ç±»åž‹ã€æè¿°ç¬¦å类别 - uint8_t granularity; // å…¶ä»–æ ‡å¿—ã€æ®µç•Œé™ 19~16 (unsigned limit_high: 4;unsigned flags: 4;) - uint8_t base_high; // æ®µåŸºåœ°å€ 31~24 + struct gdt_entry_t { + uint16_t limit_low; // æ®µç•Œé™ 15~0 + uint16_t base_low; // æ®µåŸºåœ°å€ 15~0 + uint8_t base_middle; // æ®µåŸºåœ°å€ 23~16 + uint8_t access; // 段å˜åœ¨ä½ã€æè¿°ç¬¦ç‰¹æƒçº§ã€æè¿°ç¬¦ç±»åž‹ã€æè¿°ç¬¦å类别 + uint8_t granularity; // å…¶ä»–æ ‡å¿—ã€æ®µç•Œé™ 19~16 (unsigned limit_high: 4;unsigned flags: 4;) + uint8_t base_high; // æ®µåŸºåœ°å€ 31~24 } __attribute__( (packed) ) gdt_entry_t; -// 全局æè¿°ç¬¦è¡¨å®šä¹‰ -static gdt_entry_t gdt_entries[GDT_LENGTH] __attribute__( (aligned(8) ) ); - // GDTR typedef - struct gdt_ptr_t { - uint16_t limit; // 全局æè¿°ç¬¦è¡¨é™é•¿ - uint32_t base; // 全局æè¿°ç¬¦è¡¨ 32ä½ åŸºåœ°å€ + struct gdt_ptr_t { + uint16_t limit; // 全局æè¿°ç¬¦è¡¨é™é•¿ + uint32_t base; // 全局æè¿°ç¬¦è¡¨ 32ä½ åŸºåœ°å€ } __attribute__( (packed) ) gdt_ptr_t; -static gdt_ptr_t gdt_ptr; - // TSS çŠ¶æ€æ®µç”±ä¸¤éƒ¨åˆ†ç»„æˆï¼š // 1. 动æ€éƒ¨åˆ†(处ç†å™¨åœ¨æ¯æ¬¡ä»»åŠ¡åˆ‡æ¢æ—¶ä¼šè®¾ç½®è¿™äº›å—段值) // 通用寄å˜å™¨(EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI) @@ -84,46 +76,46 @@ static gdt_ptr_t gdt_ptr; // TSS(ä»»åŠ¡çŠ¶æ€æ®µ) æè¿°ç¬¦ // TSS的使用是为了解决调用门ä¸ç‰¹æƒçº§å˜æ¢æ—¶å †æ ˆå‘生的å˜åŒ–. typedef - struct tss_entry_t { - uint32_t ts_link; // old ts selector - uint32_t ts_esp0; // stack pointers and segment selectors - uint32_t ts_ss0; // after an increase in privilege level - uint32_t ts_esp1; - uint32_t ts_ss1; - uint32_t ts_esp2; - uint32_t ts_ss2; - uint32_t ts_cr3; // page directory base - uint32_t ts_eip; // saved state from last task switch - uint32_t ts_eflags; - uint32_t ts_eax; // more saved state (registers) - uint32_t ts_ecx; - uint32_t ts_edx; - uint32_t ts_ebx; - uint32_t ts_esp; - uint32_t ts_ebp; - uint32_t ts_esi; - uint32_t ts_edi; - uint32_t ts_es; // even more saved state (segment selectors) - uint32_t ts_cs; - uint32_t ts_ss; - uint32_t ts_ds; - uint32_t ts_fs; - uint32_t ts_gs; - uint32_t ts_ldt; - uint32_t ts_t; // trap on task switch - uint32_t ts_iomb; // i/o map base address + struct tss_entry_t { + uint32_t ts_link; // old ts selector + uint32_t ts_esp0; // stack pointers and segment selectors + uint32_t ts_ss0; // after an increase in privilege level + uint32_t ts_esp1; + uint32_t ts_ss1; + uint32_t ts_esp2; + uint32_t ts_ss2; + uint32_t ts_cr3; // page directory base + uint32_t ts_eip; // saved state from last task switch + uint32_t ts_eflags; + uint32_t ts_eax; // more saved state (registers) + uint32_t ts_ecx; + uint32_t ts_edx; + uint32_t ts_ebx; + uint32_t ts_esp; + uint32_t ts_ebp; + uint32_t ts_esi; + uint32_t ts_edi; + uint32_t ts_es; // even more saved state (segment selectors) + uint32_t ts_cs; + uint32_t ts_ss; + uint32_t ts_ds; + uint32_t ts_fs; + uint32_t ts_gs; + uint32_t ts_ldt; + uint32_t ts_t; // trap on task switch + uint32_t ts_iomb; // i/o map base address } __attribute__( (packed) ) tss_entry_t; -// TSS 段定义 -static tss_entry_t tss_entry __attribute__( (aligned(8) ) ); - // 全局æè¿°ç¬¦è¡¨æž„é€ å‡½æ•°ï¼Œæ ¹æ®ä¸‹æ ‡æž„é€ // 傿•°: num-æ•°ç»„ä¸‹æ ‡ã€base-基地å€ã€limit-é™é•¿ã€access-è®¿é—®æ ‡å¿—ï¼Œgran-粒度 void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); -extern void gdt_load(uint32_t); // GDT åŠ è½½åˆ° GDTR 的函数 -extern void tss_load(); // TSS 刷新[汇编实现] -void gdt_init(void); // åˆå§‹åŒ–全局æè¿°ç¬¦è¡¨ +// åŠ è½½ GDTR +extern void gdt_load(uint32_t); +// 刷新 TSS +extern void tss_load(); +// åˆå§‹åŒ–全局æè¿°ç¬¦è¡¨ +void gdt_init(void); #ifdef __cplusplus } diff --git a/src/arch/x86_64/intr/include/intr.h b/src/arch/x86_64/intr/include/intr.h index 23df26c02aa3f856d2f935a087f68447e1cbd7b7..1c1147539c1660933b22ba7404a32661baa4879e 100644 --- a/src/arch/x86_64/intr/include/intr.h +++ b/src/arch/x86_64/intr/include/intr.h @@ -11,11 +11,6 @@ extern "C" { #endif #include "stdint.h" -#include "stdio.h" -#include "port.hpp" -#include "debug.h" -#include "../drv/8259A/include/8259A.h" -#include "cpu.hpp" #define INTERRUPT_MAX 256 // 䏿–表最大值 @@ -61,50 +56,50 @@ extern "C" { #define INT_VIRTUAL_EXCE 20 typedef - struct pt_regs_t { + struct pt_regs { // segment registers - uint32_t gs; // 16 bits - uint32_t fs; // 16 bits - uint32_t es; // 16 bits - uint32_t ds; // 16 bits + uint32_t gs; // 16 bits + uint32_t fs; // 16 bits + uint32_t es; // 16 bits + uint32_t ds; // 16 bits // registers save by pusha - uint32_t edi; - uint32_t esi; - uint32_t ebp; - uint32_t old_esp; - uint32_t ebx; - uint32_t edx; - uint32_t ecx; - uint32_t eax; - - uint32_t int_no; + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t old_esp; + uint32_t ebx; + uint32_t edx; + uint32_t ecx; + uint32_t eax; + + uint32_t int_no; // save by `int` instruction - uint32_t err_code; + uint32_t err_code; // 以下指令由cpu压入,å‚è§x86/x64 532页 - uint32_t eip; // 指å‘产生异常的指令 - uint32_t cs; // 16 bits - uint32_t eflags; + uint32_t eip; // 指å‘产生异常的指令 + uint32_t cs; // 16 bits + uint32_t eflags; // 如果å‘生了特æƒçº§åˆ‡æ¢ï¼ŒCPU ä¼šåŽ‹å…¥ä»¥ä¸‹ä¸¤ä¸ªå‚æ•° - uint32_t user_esp; - uint32_t user_ss; // 16 bits + uint32_t user_esp; + uint32_t user_ss; // 16 bits } pt_regs_t; // 䏿–æè¿°ç¬¦ typedef - struct idt_entry_t { - uint16_t base_low; // 䏿–处ç†å‡½æ•°åœ°å€ 15~0 ä½ - uint16_t selector; // ç›®æ ‡ä»£ç æ®µæè¿°ç¬¦é€‰æ‹©å - uint8_t zero; // ç½® 0 段 - uint8_t flags; // ä¸€äº›æ ‡å¿—ï¼Œæ–‡æ¡£æœ‰è§£é‡Š - uint16_t base_high; // 䏿–处ç†å‡½æ•°åœ°å€ 31~16 ä½ + struct idt_entry_t { + uint16_t base_low; // 䏿–处ç†å‡½æ•°åœ°å€ 15~0 ä½ + uint16_t selector; // ç›®æ ‡ä»£ç æ®µæè¿°ç¬¦é€‰æ‹©å + uint8_t zero; // ç½® 0 段 + uint8_t flags; // ä¸€äº›æ ‡å¿—ï¼Œæ–‡æ¡£æœ‰è§£é‡Š + uint16_t base_high; // 䏿–处ç†å‡½æ•°åœ°å€ 31~16 ä½ } __attribute__( (packed) ) idt_entry_t; // IDTR typedef - struct idt_ptr_t { - uint16_t limit; // é™é•¿ - uint32_t base; // åŸºå€ + struct idt_ptr_t { + uint16_t limit; // é™é•¿ + uint32_t base; // åŸºå€ } __attribute__( (packed) ) idt_ptr_t; // å£°æ˜Žä¸æ–处ç†å‡½æ•° 0 ~ 19 属于 CPU çš„å¼‚å¸¸ä¸æ– @@ -168,19 +163,23 @@ extern void irq15(); // IDE1 ä¼ è¾“æŽ§åˆ¶ä½¿ç”¨ void irq_handler(pt_regs_t * regs); // IRQ 处ç†å‡½æ•° -typedef void (* interrupt_handler_t)(pt_regs_t *); // å®šä¹‰ä¸æ–处ç†å‡½æ•°æŒ‡é’ˆ +// 䏿–处ç†å‡½æ•°æŒ‡é’ˆ +typedef void (* interrupt_handler_t)(pt_regs_t *); -void isr_handler(pt_regs_t * regs); // è°ƒç”¨ä¸æ–处ç†å‡½æ•° +// è°ƒç”¨ä¸æ–处ç†å‡½æ•° +void isr_handler(pt_regs_t * regs); -void register_interrupt_handler(uint8_t n, interrupt_handler_t h); // æ³¨å†Œä¸€ä¸ªä¸æ–处ç†å‡½æ•° +// æ³¨å†Œä¸€ä¸ªä¸æ–处ç†å‡½æ•° +void register_interrupt_handler(uint8_t n, interrupt_handler_t h); -extern void idt_load(uint32_t); // å£°æ˜ŽåŠ è½½ IDTR 的函数 +// å£°æ˜ŽåŠ è½½ IDTR 的函数 +extern void idt_load(uint32_t); -typedef void (* isr_irq_func_t)(); // 䏿–处ç†å‡½æ•°æŒ‡é’ˆç±»åž‹ +// 䏿–处ç†å‡½æ•°æŒ‡é’ˆ +typedef void (* isr_irq_func_t)(); -void idt_init(void); // idt åˆå§‹åŒ– - -extern void clear_interrupt_chip(uint32_t intr_no); // é‡ç½® 8259A +// intr åˆå§‹åŒ– +void intr_init(void); // ç³»ç»Ÿä¸æ– void divide_error(pt_regs_t * regs); diff --git a/src/arch/x86_64/intr/intr.c b/src/arch/x86_64/intr/intr.c index 2b54ac8fa27038b86dfbfafb462040bee49fbcb7..0cc29f102367fa2cdfc1b555ff9c70a9a50a5aa4 100644 --- a/src/arch/x86_64/intr/intr.c +++ b/src/arch/x86_64/intr/intr.c @@ -7,6 +7,11 @@ extern "C" { #endif +#include "stdio.h" +#include "port.hpp" +#include "debug.h" +#include "../drv/8259A/include/8259A.h" +#include "cpu.hpp" #include "include/intr.h" // 䏿–æè¿°ç¬¦è¡¨ @@ -25,10 +30,13 @@ static void idt_set_gate(uint8_t num, uint32_t base, uint16_t target, uint8_t fl // 0xEF: DPL=3 } +static void die(char * str, uint32_t oesp, uint32_t int_no); +static const char * intrname(uint32_t intrno); + // 䏿–处ç†å‡½æ•°æŒ‡é’ˆæ•°ç»„ static interrupt_handler_t interrupt_handlers[INTERRUPT_MAX] __attribute__( (aligned(4) ) ); -static const char * intrname(uint32_t intrno) { +const char * intrname(uint32_t intrno) { static const char * const intrnames[] = { "Divide error", "Debug", @@ -99,7 +107,8 @@ static isr_irq_func_t isr_irq_func[INTERRUPT_MAX] = { }; // idt åˆå§‹åŒ– -void idt_init(void) { +void intr_init(void) { + cpu_cli(); init_interrupt_chip(); idt_ptr.limit = sizeof(idt_entry_t) * INTERRUPT_MAX - 1; idt_ptr.base = (uint32_t)&idt_entries; @@ -137,9 +146,11 @@ void idt_init(void) { register_interrupt_handler(INT_GENERAL_PROTECT, &general_protection); printk_info("intr_init\n"); + cpu_sti(); + return; } -static void die(char * str, uint32_t oesp, uint32_t int_no) { +void die(char * str, uint32_t oesp, uint32_t int_no) { // uint32_t * old_esp = (uint32_t *)oesp; pt_regs_t * old_esp = (pt_regs_t *)oesp; printk_color(red, "%s\t: %d\n\r", str, int_no); @@ -153,15 +164,15 @@ static void die(char * str, uint32_t oesp, uint32_t int_no) { // printk_color(red, "EIP:\t%08x:%08X\nEFLAGS:\t%08x\nESP:\t%08x:%08X\n", // old_esp->cs, old_esp->eip, old_esp->eflags, old_esp->ss, old_esp->old_esp); printk_color(red, "gs: %08x\tfs: %08x\tes: %08x\tds: %08x\n", - old_esp->gs, old_esp->fs, old_esp->es, old_esp->ds); + old_esp->gs, old_esp->fs, old_esp->es, old_esp->ds); printk_color(red, "edi: %08x\tesi: %08x\tebp: %08x\told_esp: %08x\n", - old_esp->edi, old_esp->esi, old_esp->ebp, old_esp->old_esp); + old_esp->edi, old_esp->esi, old_esp->ebp, old_esp->old_esp); printk_color(red, "ebx: %08x\tedx: %08x\tecx: %08x\teax: %08x\n", - old_esp->ebx, old_esp->edx, old_esp->ecx, old_esp->eax); + old_esp->ebx, old_esp->edx, old_esp->ecx, old_esp->eax); printk_color(red, "int_no: %08X\terr_code: %08X\teip: %08x\tcs: %08x\n", - old_esp->int_no, old_esp->err_code, old_esp->eip, old_esp->cs); + old_esp->int_no, old_esp->err_code, old_esp->eip, old_esp->cs); printk_color(red, "eflags: %08x\tuser_esp: %08x\tss: %08x\n", - old_esp->eflags, old_esp->user_esp, old_esp->user_ss); + old_esp->eflags, old_esp->user_esp, old_esp->user_ss); printk_color(red, "addr: %08x, %08X\n", &old_esp->gs, &old_esp->user_ss); cpu_hlt(); @@ -178,19 +189,19 @@ void debug(pt_regs_t * regs) { // å–任务寄å˜å™¨å€¼->tr __asm__ volatile ("str %%ax" - : "=a" (tr) - : "0" (0) ); + : "=a" (tr) + : "0" (0) ); printk_color(light_red, "Unuseable.\n"); printk_color(red, "eax 0x%08X\tebx 0x%08X\tecx 0x%08X\tedx 0x%08X\n", - regs->eax, regs->ebx, regs->ecx, regs->edx); + regs->eax, regs->ebx, regs->ecx, regs->edx); printk_color(red, "esi 0x%08X\tedi 0x%08X\tebp 0x%08X\tesp 0x%08X\n", - regs->esi, regs->edi, regs->ebp, (uint32_t)regs->user_esp); + regs->esi, regs->edi, regs->ebp, (uint32_t)regs->user_esp); printk_color(red, "ds 0x%08X\tes 0x%08X\tfs 0x%08X\tgs 0x%08X\n", - regs->ds, regs->es, regs->fs, regs->gs); + regs->ds, regs->es, regs->fs, regs->gs); printk_color(red, "EIP: 0x%08X\tEFLAGS: 0x%08X\tCS: 0x%08X\n", // old_esp[0], old_esp[1], old_esp[2]); - old_esp[0], read_eflags(), old_esp[2]); + old_esp[0], read_eflags(), old_esp[2]); return; } diff --git a/src/arch/x86_64/mm/pmm.c b/src/arch/x86_64/mm/pmm.c index f2f1d9f6af1b64105baa44e86157db0aad1d8e69..660e630e551be377331c58e31adcf3780bcf8177 100644 --- a/src/arch/x86_64/mm/pmm.c +++ b/src/arch/x86_64/mm/pmm.c @@ -7,65 +7,86 @@ extern "C" { #endif -#include "mem/pmm.h" -#include "assert.h" +#include "stdio.h" + #include "string.h" +#include "assert.h" +#include "debug.h" +#include "cpu.hpp" +#include "mem/pmm.h" +#include "mem/firstfit.h" // 物ç†é¡µå¸§æ•°ç»„长度 static uint32_t phy_pages_count; -// 物ç†å†…å˜é¡µé¢ç®¡ç†çš„æ ˆ -static ptr_t pmm_stack[PMM_PAGE_MAX_SIZE + 1]; - -// 物ç†å†…å˜ç®¡ç†çš„æ ˆæŒ‡é’ˆ -static ptr_t pmm_stack_top; +static const pmm_manage_t * pmm_manager = &firstfit_manage; -void pmm_init() { +// 从 GRUB 读å–物ç†å†…å˜ä¿¡æ¯ +static void pmm_get_ram_info(e820map_t * e820map); +void pmm_get_ram_info(e820map_t * e820map) { for( ; (uint8_t *)mmap_entries < (uint8_t *)mmap_tag + mmap_tag->size ; - mmap_entries = (multiboot_memory_map_entry_t *) - ( (unsigned long)mmap_entries + - ( (struct multiboot_tag_mmap *)mmap_tag)->entry_size) ) { + mmap_entries = (multiboot_memory_map_entry_t *)( (uint32_t)mmap_entries + + ( (struct multiboot_tag_mmap *)mmap_tag)->entry_size) ) { // 如果是å¯ç”¨å†…å˜ if( (unsigned)mmap_entries->type == MULTIBOOT_MEMORY_AVAILABLE - && (unsigned)(mmap_entries->addr & 0xffffffff) == 0x100000) { - // æŠŠå†…æ ¸ä½ç½®åˆ°ç»“æŸä½ç½®çš„å†…å˜æ®µï¼ŒæŒ‰é¡µå˜å‚¨åˆ°é¡µç®¡ç†æ ˆé‡Œ - ptr_t page_addr = (mmap_entries->addr); - uint32_t length = (mmap_entries->len); - while(page_addr < length && page_addr <= PMM_MAX_SIZE) { - pmm_free_page(page_addr); - page_addr += PMM_PAGE_SIZE; - phy_pages_count++; - } + && (unsigned)(mmap_entries->addr & 0xFFFFFFFF) == 0x100000) { + e820map->map[e820map->nr_map].addr = mmap_entries->addr; + e820map->map[e820map->nr_map].length = mmap_entries->len; + e820map->map[e820map->nr_map].type = mmap_entries->type; + e820map->nr_map++; + } + } + return; +} + +void pmm_phy_init(e820map_t * e820map) { + // 计算物ç†é¡µæ€»æ•° + for(uint32_t i = 0 ; i < e820map->nr_map ; i++) { + for(uint64_t addr = e820map->map[i].addr ; + addr < e820map->map[i].addr + e820map->map[i].length ; + addr += PMM_PAGE_SIZE) { + phy_pages_count++; } } + return; +} + +void pmm_mamage_init(e820map_t * e820map) { + // å› ä¸ºåªæœ‰ä¸€ä¸ªå¯ç”¨å†…å˜åŒºåŸŸï¼Œæ‰€ä»¥ç›´æŽ¥ä¼ 递 + pmm_manager->pmm_manage_init( (ptr_t)e820map->map[0].addr, phy_pages_count); + return; +} + +void pmm_init() { + cpu_cli(); + e820map_t e820map; + bzero(&e820map, sizeof(e820map_t) ); + pmm_get_ram_info(&e820map); + pmm_phy_init(&e820map); + pmm_mamage_init(&e820map); + printk_info("pmm_init\n"); printk_info("phy_pages_count: %d\n", phy_pages_count); + printk_info("phy_pages_allow_count: %d\n", pmm_free_pages_count() ); + cpu_sti(); return; } ptr_t pmm_alloc(uint32_t byte) { - assert(pmm_stack_top != 0); - uint32_t count = byte / PMM_PAGE_SIZE; - // å°† size å‘ä¸Šå–æ•´ 4KB - if(byte % PMM_PAGE_SIZE != 0) { - count += 1; - } ptr_t page; - do { - assert(pmm_stack_top != 0); - page = pmm_stack[pmm_stack_top--]; - count--; - } while(count > 0); - memset( (void *)page, 0, PMM_PAGE_SIZE * count); + page = pmm_manager->pmm_manage_alloc(byte); return page; } -void pmm_free_page(ptr_t page) { - assert(pmm_stack_top != PMM_PAGE_MAX_SIZE); - pmm_stack[++pmm_stack_top] = page; +void pmm_free_page(ptr_t addr, uint32_t byte) { + pmm_manager->pmm_manage_free(addr, byte); return; } +uint32_t pmm_free_pages_count(void) { + return pmm_manager->pmm_manage_free_pages_count(); +} + #ifdef __cplusplus } #endif diff --git a/src/arch/x86_64/mm/vmm.c b/src/arch/x86_64/mm/vmm.c index 040257a92839a28e9cc6b90dac1008bbd2da2b7b..33b4db68c1ca31008d309255c0d45098ba344852 100644 --- a/src/arch/x86_64/mm/vmm.c +++ b/src/arch/x86_64/mm/vmm.c @@ -7,30 +7,38 @@ extern "C" { #endif -#include "mem/vmm.h" -#include "mem/pmm.h" -#include "debug.h" #include "stdio.h" #include "string.h" #include "cpu.hpp" +#include "debug.h" +#include "intr/include/intr.h" +#include "mem/vmm.h" // å†…æ ¸é¡µç›®å½•åŒºåŸŸ -static pgd_t pgd_kernel[VMM_PAGE_TABLES_PRE_PAGE_DIRECTORY] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); +pgd_t pgd_kernel[VMM_PAGE_TABLES_PRE_PAGE_DIRECTORY] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); // å†…æ ¸é¡µè¡¨åŒºåŸŸ static pte_t pte_kernel[VMM_PAGE_TABLES_KERNEL][VMM_PAGES_PRE_PAGE_TABLE] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); +static inline ptr_t vmm_la_to_pa(ptr_t la); +static inline ptr_t vmm_pa_to_la(ptr_t pa); + +ptr_t vmm_la_to_pa(ptr_t la) { + return la - KERNEL_BASE; +} + +ptr_t vmm_pa_to_la(ptr_t pa) { + return pa + KERNEL_BASE; +} + void vmm_init(void) { + cpu_cli(); register_interrupt_handler(INT_PAGE_FAULT, &page_fault); - // å†…æ ¸æ®µ pgd_tmp[0x300], 4MB + // æ˜ å°„å…¨éƒ¨å†…æ ¸ uint32_t pgd_idx = VMM_PGD_INDEX(KERNEL_BASE); for(uint32_t i = pgd_idx, j = 0 ; i < VMM_PAGE_DIRECTORIES_KERNEL + pgd_idx ; i++, j++) { - pgd_kernel[i] = (vmm_la_to_pa( (ptr_t)pte_kernel[j]) | VMM_PAGE_PRESENT | VMM_PAGE_RW); + pgd_kernel[i] = ( (ptr_t)vmm_la_to_pa( (ptr_t)pte_kernel[j]) | VMM_PAGE_PRESENT | VMM_PAGE_RW); } - - // å°†æ¯ä¸ªé¡µè¡¨é¡¹èµ‹å€¼ - // æ˜ å°„ kernel 段 4MB - // æ˜ å°„ 0x00000000-0x00400000 的物ç†åœ°å€åˆ°è™šæ‹Ÿåœ°å€ 0xC0000000-0xC0400000 ptr_t * pte = (ptr_t *)pte_kernel; for(uint32_t i = 0 ; i < VMM_PAGE_TABLES_KERNEL * VMM_PAGES_PRE_PAGE_TABLE ; i++) { pte[i] = (i << 12) | VMM_PAGE_PRESENT | VMM_PAGE_RW; @@ -39,52 +47,47 @@ void vmm_init(void) { switch_pgd(vmm_la_to_pa( (ptr_t)pgd_kernel) ); printk_info("vmm_init\n"); - + cpu_sti(); return; } void map(pgd_t * pgd_now, ptr_t va, ptr_t pa, uint32_t flags) { - uint32_t pgd_idx = VMM_PGD_INDEX(va); - uint32_t pte_idx = VMM_PTE_INDEX(va); - + uint32_t pgd_idx = VMM_PGD_INDEX(va);// 0x200 + uint32_t pte_idx = VMM_PTE_INDEX(va);// 0x0 + // printk_debug("pgd_now = %X\n", pgd_now); + // printk_debug("pgd_idx = %X\n", pgd_idx); + // printk_debug("pte_idx = %X\n", pte_idx); pte_t * pte = (pte_t *)(pgd_now[pgd_idx] & VMM_PAGE_MASK); - if(!pte) { - pte = (pte_t *)pmm_alloc(1); - pgd_now[pgd_idx] = (ptr_t)pte | VMM_PAGE_PRESENT | VMM_PAGE_RW; - - // 转æ¢åˆ°å†…æ ¸çº¿æ€§åœ°å€å¹¶æ¸… 0 - pte = (pte_t *)( (ptr_t)pte + KERNEL_BASE); - bzero(pte, VMM_PAGE_SIZE); + // printk_debug("pte1 = %X\n", pte); + // 转æ¢åˆ°å†…æ ¸çº¿æ€§åœ°å€ + if(pte != NULL) { + // printk_debug("pte20 = %X\n", pte); + pte = (pte_t *)vmm_pa_to_la( (ptr_t)pte); + // printk_debug("pte21 = %X\n", pte); } else { - // 转æ¢åˆ°å†…æ ¸çº¿æ€§åœ°å€ - pte = (pte_t *)( (ptr_t)pte + KERNEL_BASE); + pte = (pte_t *)vmm_pa_to_la( (ptr_t)pte); + // printk_debug("pte2 = %X\n", pte); + pgd_now[pgd_idx] = (uint32_t)pte | flags; + // printk_debug("pgd_now[pgd_idx] = %X\n", pgd_now[pgd_idx]); } pte[pte_idx] = (pa & VMM_PAGE_MASK) | flags; - - // 通知 CPU æ›´æ–°é¡µè¡¨ç¼“å˜ - __asm__ volatile ("invlpg (%0)" : : "a" (va) ); - // __native_flush_tlb_single(va); + // printk_debug("pte[pte_idx] = %X\n", pte[pte_idx]); + // // 通知 CPU æ›´æ–°é¡µè¡¨ç¼“å˜ + CPU_INVLPG(va); + return; } void unmap(pgd_t * pgd_now, ptr_t va) { uint32_t pgd_idx = VMM_PGD_INDEX(va); uint32_t pte_idx = VMM_PTE_INDEX(va); - pte_t * pte = (pte_t *)(pgd_now[pgd_idx] & VMM_PAGE_MASK); - - if(!pte) { - return; - } - // 转æ¢åˆ°å†…æ ¸çº¿æ€§åœ°å€ - pte = (pte_t *)( (ptr_t)pte + KERNEL_BASE); - + pte = (pte_t *)vmm_pa_to_la( (ptr_t)pte); pte[pte_idx] = 0; - // 通知 CPU æ›´æ–°é¡µè¡¨ç¼“å˜ - __asm__ volatile ("invlpg (%0)" : : "a" (va) ); - // __native_flush_tlb_single(va); + CPU_INVLPG(va); + return; } uint32_t get_mapping(pgd_t * pgd_now, ptr_t va, ptr_t pa) { @@ -95,16 +98,14 @@ uint32_t get_mapping(pgd_t * pgd_now, ptr_t va, ptr_t pa) { if(!pte) { return 0; } - // 转æ¢åˆ°å†…æ ¸çº¿æ€§åœ°å€ - pte = (pte_t *)( (ptr_t)pte + KERNEL_BASE); + pte = (pte_t *)vmm_pa_to_la( (ptr_t)pte); // å¦‚æžœåœ°å€æœ‰æ•ˆè€Œä¸”指针ä¸ä¸ºNULLï¼Œåˆ™è¿”å›žåœ°å€ if(pte[pte_idx] != 0 && pa) { pa = pte[pte_idx] & VMM_PAGE_MASK; return 1; } - return 0; } @@ -115,10 +116,10 @@ void switch_pgd(ptr_t pd) { void page_fault(pt_regs_t * regs) { #ifdef __x86_64__ uint64_t cr2; - asm volatile ("movq %%cr2,%0" : "=r" (cr2) ); + __asm__ volatile ("movq %%cr2,%0" : "=r" (cr2) ); #else uint32_t cr2; - asm volatile ("mov %%cr2,%0" : "=r" (cr2) ); + __asm__ volatile ("mov %%cr2,%0" : "=r" (cr2) ); #endif printk("Page fault at 0x%08X, virtual faulting address 0x%08X\n", regs->eip, cr2); printk_err("Error code: 0x%08X\n", regs->err_code); diff --git a/src/arch/x86_64/port.hpp b/src/arch/x86_64/port.hpp index e1cd8f81f7e6a00315cd8d137bc4e8092a564889..665f69db67936cbaa6de7277ffe9c8dd3f25fc51 100644 --- a/src/arch/x86_64/port.hpp +++ b/src/arch/x86_64/port.hpp @@ -15,20 +15,20 @@ extern "C" { // 端å£å†™ä¸€ä¸ªå—节 static inline void outb(uint16_t port, uint8_t value) { __asm__ volatile ( - "outb %1, %0" - : : "dN" ( port ), - "a" ( value ) - ); + "outb %1, %0" + : : "dN" (port), + "a" (value) + ); } // 端å£è¯»ä¸€ä¸ªå—节 static inline uint8_t inb(uint16_t port) { uint8_t ret; __asm__ volatile ( - "inb %1, %0" - : "=a" ( ret ) - : "dN" ( port ) - ); + "inb %1, %0" + : "=a" (ret) + : "dN" (port) + ); return ret; } @@ -36,10 +36,10 @@ static inline uint8_t inb(uint16_t port) { static inline uint16_t inw(uint16_t port) { uint16_t ret; __asm__ volatile ( - "inw %1, %0" - : "=a" ( ret ) - : "dN" ( port ) - ); + "inw %1, %0" + : "=a" (ret) + : "dN" (port) + ); return ret; } diff --git a/src/drv/clock/clock.c b/src/drv/clock/clock.c index 01edde693bba88e0f0530d5b7b116a33513517b1..43af643d9b7df3ce232f6998d7cb0c0aba3f6fba 100644 --- a/src/drv/clock/clock.c +++ b/src/drv/clock/clock.c @@ -6,8 +6,10 @@ extern "C" { #endif -#include "include/clock.h" #include "stddef.h" +#include "cpu.hpp" +#include "include/clock.h" + void clock_handler(pt_regs_t * regs UNUSED) { static uint32_t tick UNUSED = 0; @@ -15,6 +17,7 @@ void clock_handler(pt_regs_t * regs UNUSED) { } void clock_init(void) { + cpu_cli(); uint32_t divisor = TIMER_FREQ / FREQUENCY; outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); // 0x34 // 拆分低å—节和高å—节 @@ -28,6 +31,8 @@ void clock_init(void) { enable_irq(IRQ0); printk_info("clock_init\n"); + cpu_sti(); + return; } #ifdef __cplusplus diff --git a/src/drv/console/console.c b/src/drv/console/console.c index 2f9e63538db8a828801aea78792e865a87162768..5860b829b0f9dfe907aa8b63398450a040013423 100644 --- a/src/drv/console/console.c +++ b/src/drv/console/console.c @@ -7,15 +7,23 @@ extern "C" { #endif +#include "stddef.h" +#include "string.h" +#include "stdio.h" +#include "cpu.hpp" #include "include/console.h" -extern uint16_t * console_buffer; - -size_t console_row; // 命令行行数 -size_t console_column; // 当å‰å‘½ä»¤è¡Œåˆ—æ•° -uint8_t console_color; // 当å‰å‘½ä»¤è¡Œé¢œè‰² +// 命令行行数 +static size_t console_row; +// 当å‰å‘½ä»¤è¡Œåˆ—æ•° +static size_t console_column; +// 当å‰å‘½ä»¤è¡Œé¢œè‰² +static uint8_t console_color; +// 显å˜åœ°å€ +static uint16_t * console_buffer __attribute__( (unused) ) = (uint16_t *)VGA_MEM_BASE; void console_init(void) { + cpu_cli(); // 从左上角开始 console_row = 0; console_column = 0; @@ -31,6 +39,8 @@ void console_init(void) { console_setcursorpos(0, 0); printk_info("console_init\n"); + cpu_sti(); + return; } // 设置命令行颜色 diff --git a/src/drv/console/include/console.h b/src/drv/console/include/console.h index 5ef7967697f9ec4330f6a5f0b89f682c6c4ce7b4..9564c986701bff3199ac0bc9b87d9604222e90aa 100644 --- a/src/drv/console/include/console.h +++ b/src/drv/console/include/console.h @@ -11,17 +11,8 @@ extern "C" { #endif #include "stdint.h" -#include "stddef.h" -#include "string.h" -#include "stdio.h" #include "vga/include/vga.hpp" -// size_t console_row; // 命令行行数 -// size_t console_column; // 当å‰å‘½ä»¤è¡Œåˆ—æ•° -// uint8_t console_color; // 当å‰å‘½ä»¤è¡Œé¢œè‰² - -static uint16_t * console_buffer __attribute__( (unused) ) = (uint16_t *)VGA_MEM_BASE; - void console_init(void); void console_scroll(void); uint16_t console_getcursorpos(void); diff --git a/src/drv/keyboard/include/keyboard.h b/src/drv/keyboard/include/keyboard.h index 14851b4523dfc67b7f70475eb50ffeb190f3a009..3a9e62bde11fe37b2791fa23e19023c3d0d388ed 100644 --- a/src/drv/keyboard/include/keyboard.h +++ b/src/drv/keyboard/include/keyboard.h @@ -10,14 +10,7 @@ extern "C" { #endif -#include "stddef.h" -#include "string.h" -#include "stdio.h" #include "stdint.h" -#include "stdbool.h" -#include "debug.h" -#include "intr/include/intr.h" -#include "cpu.hpp" // é”®ç›˜ç¼“å†²åŒºå¤§å° #define KB_BUFSIZE 128 @@ -135,8 +128,6 @@ extern "C" { #define PAD_MID PAD_5 // Middle key #define PAD_DEL PAD_DOT // Del -extern void init_interrupt_chip(void); -extern void clear_interrupt_chip(uint32_t intr_no); // é‡ç½® 8259A void keyboard_init(void); void keyboard_handler(void); void keyboard_read(pt_regs_t * regs); @@ -144,11 +135,11 @@ void keyboard_read(pt_regs_t * regs); uint8_t keyboard_read_from_buff(void); typedef - struct kb_input { - uint8_t * head; - uint8_t * tail; - size_t count; - uint8_t buff[KB_BUFSIZE]; + struct kb_input { + uint8_t * head; + uint8_t * tail; + size_t count; + uint8_t buff[KB_BUFSIZE]; } kb_input_t; #ifdef __cplusplus diff --git a/src/drv/keyboard/keyboard.c b/src/drv/keyboard/keyboard.c index 71b012fd72cefb55a9969c06ccfd4a91d86d633f..1395dfc724856f664451023af49b752679429845 100644 --- a/src/drv/keyboard/keyboard.c +++ b/src/drv/keyboard/keyboard.c @@ -7,8 +7,13 @@ extern "C" { #endif -#include "include/keyboard.h" +#include "stddef.h" +#include "stdio.h" +#include "stdbool.h" +#include "intr/include/intr.h" #include "port.hpp" +#include "cpu.hpp" +#include "include/keyboard.h" static uint8_t keymap[NR_SCAN_CODES * MAP_COLS] = { /* scan-code !Shift Shift E0 XX */ @@ -252,11 +257,14 @@ void keyboard_read(pt_regs_t * regs UNUSED) { } void keyboard_init(void) { + cpu_cli(); kb_in.count = 0; kb_in.head = kb_in.tail = kb_in.buff; register_interrupt_handler(IRQ1, &keyboard_read); enable_irq(IRQ1); printk_info("keyboard_init\n"); + cpu_sti(); + return; } #ifdef __cplusplus diff --git a/src/drv/mouse/include/mouse.h b/src/drv/mouse/include/mouse.h index 6c364ef497f712bb2169aff1240ce31018c8e387..cb6fd9c7c54ac8384dd45244ef2b8e6f10dee91a 100644 --- a/src/drv/mouse/include/mouse.h +++ b/src/drv/mouse/include/mouse.h @@ -19,10 +19,10 @@ extern "C" { #define KBCMD_EN_MOUSE_INTFACE 0xA8 typedef - struct mouse_desc_t { - uint8_t buf[3]; - uint8_t phase; - uint32_t x, y, btn; + struct mouse_desc_t { + uint8_t buf[3]; + uint8_t phase; + uint32_t x, y, btn; } mouse_desc_t; #ifdef __cplusplus diff --git a/src/drv/vga/include/vga.hpp b/src/drv/vga/include/vga.hpp index 635e8f89da91e8ae3de76d5f04d1db921146cb5a..1fd1cdebe8c86aa15da009bf10eb6d9a92446b41 100644 --- a/src/drv/vga/include/vga.hpp +++ b/src/drv/vga/include/vga.hpp @@ -49,13 +49,13 @@ static const size_t VGA_HEIGHT = 25; // fg-font // bg-back static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) { - return fg | ( bg << 4 ); + return fg | (bg << 4); } // uc-å—符 // color-颜色 static inline uint16_t vga_entry(uint8_t uc, uint8_t color) { - return (uint16_t) uc | (uint16_t) color << 8; + return (uint16_t)uc | (uint16_t)color << 8; } #ifdef __cplusplus diff --git a/src/ds_alg/LinkedList.c b/src/ds_alg/LinkedList.c index 125506a2f81e8e14f958eecb0344ff5c8824102e..f5cf56ec30bf8b2eb049be73979d5e5f0c6a86a5 100644 --- a/src/ds_alg/LinkedList.c +++ b/src/ds_alg/LinkedList.c @@ -7,363 +7,362 @@ extern "C" { #endif - -#include "stddef.h" -#include "stdlib.h" -#include "include/linkedlist.h" - -struct _ListEntry { - ListValue data; - ListEntry * prev; - ListEntry * next; -}; - -void list_free(ListEntry * list) { - ListEntry * entry; - /* Iterate over each entry, freeing each list entry, until the - * end is reached */ - entry = list; - ListEntry * next; - while(entry != NULL) { - next = entry->next; - kfree(entry); - entry = next; - } -} - -ListEntry * list_prepend(ListEntry * * list, ListValue data) { - ListEntry * newentry; - if(list == NULL) - /* not a valid list */ - return NULL; - /* Create new entry */ - newentry = kmalloc(sizeof(ListEntry) ); - if(newentry == NULL) - return NULL; - newentry->data = data; - /* Hook into the list start */ - if(*list != NULL) - (*list)->prev = newentry; - newentry->prev = NULL; - newentry->next = *list; - *list = newentry; - return newentry; -} - -ListEntry * list_append(ListEntry * * list, ListValue data) { - ListEntry * rover; - ListEntry * newentry; - if(list == NULL) - return NULL; - /* Create new list entry */ - newentry = kmalloc(sizeof(ListEntry) ); - if(newentry == NULL) - return NULL; - newentry->data = data; - newentry->next = NULL; - /* Hooking into the list is different if the list is empty */ - if(*list == NULL) { - /* Create the start of the list */ - *list = newentry; - newentry->prev = NULL; - } else { - /* Find the end of list */ - for(rover = *list ; rover->next != NULL ; rover = rover->next); - /* Add to the end of list */ - newentry->prev = rover; - rover->next = newentry; - } - return newentry; -} - - -ListValue list_data(ListEntry * listentry) { - if(listentry == NULL) - return LIST_NULL; - return listentry->data; -} - -void list_set_data(ListEntry * listentry, ListValue value) { - if(listentry != NULL) - listentry->data = value; - return; -} - -ListEntry * list_prev(ListEntry * listentry) { - if(listentry == NULL) - return NULL; - return listentry->prev; -} - -ListEntry * list_next(ListEntry * listentry) { - if(listentry == NULL) - return NULL; - return listentry->next; -} - -ListEntry * list_nth_entry(ListEntry * list, unsigned int n) { - ListEntry * entry; - unsigned int i; - /* Iterate through n list entries to reach the desired entry. - * Make sure we do not reach the end of the list. */ - entry = list; - for(i = 0 ; i < n ; ++i) { - if(entry == NULL) - return NULL; - entry = entry->next; - } - return entry; -} - -ListValue list_nth_data(ListEntry * list, unsigned int n) { - ListEntry * entry; - /* Find the specified entry */ - entry = list_nth_entry(list, n); - /* If out of range, return NULL, otherwise return the data */ - if(entry == NULL) - return LIST_NULL; - else - return entry->data; -} - -unsigned int list_length(ListEntry * list) { - ListEntry * entry; - unsigned int length; - length = 0; - entry = list; - while(entry != NULL) { - /* Count the number of entries */ - ++length; - entry = entry->next; - } - return length; -} - -ListValue * list_to_array(ListEntry * list) { - ListEntry * rover; - ListValue * array; - unsigned int length; - unsigned int i; - /* Allocate an array equal in size to the list length */ - length = list_length(list); - array = kmalloc(sizeof(ListValue) * length); - if(array == NULL) - return NULL; - /* Add all entries to the array */ - rover = list; - for(i = 0 ; i < length ; ++i) { - /* Add this node's data */ - array[i] = rover->data; - /* Jump to the next list node */ - rover = rover->next; - } - return array; -} - -bool list_remove_entry(ListEntry * * list, ListEntry * entry) { - /* If the list is empty, or entry is NULL, always fail */ - if(list == NULL || *list == NULL || entry == NULL) - return false; - /* Action to take is different if the entry is the first in the list */ - if(entry->prev == NULL) { - /* Unlink the first entry and update the starting pointer */ - *list = entry->next; - /* Update the second entry's prev pointer, if there is a second - * entry */ - if(entry->next != NULL) - entry->next->prev = NULL; - } else { - - /* This is not the first in the list, so we must have a - * previous entry. Update its 'next' pointer to the new - * value */ - entry->prev->next = entry->next; - /* If there is an entry following this one, update its 'prev' - * pointer to the new value */ - if(entry->next != NULL) - entry->next->prev = entry->prev; - } - /* Free the list entry */ - kfree(entry); - /* Operation successful */ - return true; -} - -unsigned int list_remove_data(ListEntry * * list, ListEqualFunc callback, - ListValue data) { - unsigned int entries_removed; - ListEntry * rover; - ListEntry * next; - if(list == NULL || callback == NULL) - return 0; - entries_removed = 0; - /* Iterate over the entries in the list */ - rover = *list; - while(rover != NULL) { - next = rover->next; - if(callback(rover->data, data) ) { - /* This data needs to be removed. Unlink this entry - * from the list. */ - if(rover->prev == NULL) - /* This is the first entry in the list */ - *list = rover->next; - else - /* Point the previous entry at its new - * location */ - rover->prev->next = rover->next; - if(rover->next != NULL) - rover->next->prev = rover->prev; - /* Free the entry */ - kfree(rover); - ++entries_removed; - } - /* Advance to the next list entry */ - rover = next; - } - return entries_removed; -} - -/* Function used internally for sorting. Returns the last entry in the - * new sorted list */ -static ListEntry * list_sort_internal(ListEntry * * list, - ListCompareFunc compare_func) { - ListEntry * pivot; - ListEntry * rover; - ListEntry * less_list, * more_list; - ListEntry * less_list_end, * more_list_end; - if(list == NULL || compare_func == NULL) - return NULL; - - /* If there are less than two entries in this list, it is - * already sorted */ - - if(*list == NULL || (*list)->next == NULL) - return *list; - /* The first entry is the pivot */ - pivot = *list; - /* Iterate over the list, starting from the second entry. Sort - * all entries into the less and more lists based on comparisons - * with the pivot */ - less_list = NULL; - more_list = NULL; - rover = (*list)->next; - while(rover != NULL) { - ListEntry * next = rover->next; - if(compare_func(rover->data, pivot->data) < 0) { - /* Place this in the less list */ - rover->prev = NULL; - rover->next = less_list; - if(less_list != NULL) - less_list->prev = rover; - less_list = rover; - } else { - /* Place this in the more list */ - rover->prev = NULL; - rover->next = more_list; - if(more_list != NULL) - more_list->prev = rover; - more_list = rover; - } - rover = next; - } - /* Sort the sublists recursively */ - less_list_end = list_sort_internal(&less_list, compare_func); - more_list_end = list_sort_internal(&more_list, compare_func); - /* Create the new list starting from the less list */ - *list = less_list; - /* Append the pivot to the end of the less list. If the less list - * was empty, start from the pivot */ - if(less_list == NULL) { - pivot->prev = NULL; - *list = pivot; - } else { - pivot->prev = less_list_end; - less_list_end->next = pivot; - } - /* Append the more list after the pivot */ - pivot->next = more_list; - if(more_list != NULL) - more_list->prev = pivot; - /* Work out what the last entry in the list is. If the more list was - * empty, the pivot was the last entry. Otherwise, the end of the - * more list is the end of the total list. */ - if(more_list == NULL) - return pivot; - else - return more_list_end; -} - -void list_sort(ListEntry * * list, ListCompareFunc compare_func) { - list_sort_internal(list, compare_func); -} - -ListEntry * list_find_data(ListEntry * list, - ListEqualFunc callback, - ListValue data) { - ListEntry * rover; - /* Iterate over entries in the list until the data is found */ - for(rover = list ; rover != NULL ; rover = rover->next) { - if(callback(rover->data, data) != 0) - return rover; - } - /* Not found */ - return NULL; -} - -void list_iterate(ListEntry * * list, ListIterator * iter) { - /* Start iterating from the beginning of the list. */ - iter->prev_next = list; - /* We have not yet read the first item. */ - iter->current = NULL; -} - -int list_iter_has_more(ListIterator * iter) { - if(iter->current == NULL || iter->current != *iter->prev_next) - /* Either we have not read the first entry, the current - * item was removed or we have reached the end of the - * list. Use prev_next to determine if we have a next - * value to iterate over. */ - return *iter->prev_next != NULL; - else - /* The current entry as not been deleted since the last - * call to list_iter_next: there is a next entry if - * current->next is not NULL */ - return iter->current->next != NULL; -} - -ListValue list_iter_next(ListIterator * iter) { - if(iter->current == NULL || iter->current != *iter->prev_next) - /* Either we are reading the first entry, we have reached - * the end of the list, or the previous entry was removed. - * Get the next entry with iter->prev_next. */ - iter->current = *iter->prev_next; - else { - /* Last value returned from list_iter_next was not deleted. - * Advance to the next entry. */ - iter->prev_next = &iter->current->next; - iter->current = iter->current->next; - } - /* Have we reached the end of the list? */ - if(iter->current == NULL) - return LIST_NULL; - else - return iter->current->data; -} - -void list_iter_remove(ListIterator * iter) { - if(iter->current == NULL || iter->current != *iter->prev_next) { - /* Either we have not yet read the first item, we have - * reached the end of the list, or we have already removed - * the current value. Either way, do nothing. */ - } else { - /* Remove the current entry */ - *iter->prev_next = iter->current->next; - if(iter->current->next != NULL) - iter->current->next->prev = iter->current->prev; - kfree(iter->current); - iter->current = NULL; - } -} +// #include "stddef.h" +// #include "heap/heap.h" +// #include "include/linkedlist.h" +// +// struct _ListEntry { +// ListValue data; +// ListEntry * prev; +// ListEntry * next; +// }; +// +// void list_free(ListEntry * list) { +// ListEntry * entry; +// /* Iterate over each entry, freeing each list entry, until the +// * end is reached */ +// entry = list; +// ListEntry * next; +// while(entry != NULL) { +// next = entry->next; +// kfree( (ptr_t)entry); +// entry = next; +// } +// } +// +// ListEntry * list_prepend(ListEntry * * list, ListValue data) { +// ListEntry * newentry; +// if(list == NULL) +// /* not a valid list */ +// return NULL; +// /* Create new entry */ +// newentry = (ListEntry *)kmalloc(sizeof(ListEntry) ); +// if(newentry == NULL) +// return NULL; +// newentry->data = data; +// /* Hook into the list start */ +// if(*list != NULL) +// (*list)->prev = newentry; +// newentry->prev = NULL; +// newentry->next = *list; +// *list = newentry; +// return newentry; +// } +// +// ListEntry * list_append(ListEntry * * list, ListValue data) { +// ListEntry * rover; +// ListEntry * newentry; +// if(list == NULL) +// return NULL; +// /* Create new list entry */ +// newentry = (ListEntry *)kmalloc(sizeof(ListEntry) ); +// if(newentry == NULL) +// return NULL; +// newentry->data = data; +// newentry->next = NULL; +// /* Hooking into the list is different if the list is empty */ +// if(*list == NULL) { +// /* Create the start of the list */ +// *list = newentry; +// newentry->prev = NULL; +// } else { +// /* Find the end of list */ +// for(rover = *list ; rover->next != NULL ; rover = rover->next); +// /* Add to the end of list */ +// newentry->prev = rover; +// rover->next = newentry; +// } +// return newentry; +// } +// +// +// ListValue list_data(ListEntry * listentry) { +// if(listentry == NULL) +// return LIST_NULL; +// return listentry->data; +// } +// +// void list_set_data(ListEntry * listentry, ListValue value) { +// if(listentry != NULL) +// listentry->data = value; +// return; +// } +// +// ListEntry * list_prev(ListEntry * listentry) { +// if(listentry == NULL) +// return NULL; +// return listentry->prev; +// } +// +// ListEntry * list_next(ListEntry * listentry) { +// if(listentry == NULL) +// return NULL; +// return listentry->next; +// } +// +// ListEntry * list_nth_entry(ListEntry * list, unsigned int n) { +// ListEntry * entry; +// unsigned int i; +// /* Iterate through n list entries to reach the desired entry. +// * Make sure we do not reach the end of the list. */ +// entry = list; +// for(i = 0 ; i < n ; ++i) { +// if(entry == NULL) +// return NULL; +// entry = entry->next; +// } +// return entry; +// } +// +// ListValue list_nth_data(ListEntry * list, unsigned int n) { +// ListEntry * entry; +// /* Find the specified entry */ +// entry = list_nth_entry(list, n); +// /* If out of range, return NULL, otherwise return the data */ +// if(entry == NULL) +// return LIST_NULL; +// else +// return entry->data; +// } +// +// unsigned int list_length(ListEntry * list) { +// ListEntry * entry; +// unsigned int length; +// length = 0; +// entry = list; +// while(entry != NULL) { +// /* Count the number of entries */ +// ++length; +// entry = entry->next; +// } +// return length; +// } +// +// ListValue * list_to_array(ListEntry * list) { +// ListEntry * rover; +// ListValue * array; +// unsigned int length; +// unsigned int i; +// /* Allocate an array equal in size to the list length */ +// length = list_length(list); +// array = (ListValue *)kmalloc(sizeof(ListValue) * length); +// if(array == NULL) +// return NULL; +// /* Add all entries to the array */ +// rover = list; +// for(i = 0 ; i < length ; ++i) { +// /* Add this node's data */ +// array[i] = rover->data; +// /* Jump to the next list node */ +// rover = rover->next; +// } +// return array; +// } +// +// bool list_remove_entry(ListEntry * * list, ListEntry * entry) { +// /* If the list is empty, or entry is NULL, always fail */ +// if(list == NULL || *list == NULL || entry == NULL) +// return false; +// /* Action to take is different if the entry is the first in the list */ +// if(entry->prev == NULL) { +// /* Unlink the first entry and update the starting pointer */ +// *list = entry->next; +// /* Update the second entry's prev pointer, if there is a second +// * entry */ +// if(entry->next != NULL) +// entry->next->prev = NULL; +// } else { +// +// /* This is not the first in the list, so we must have a +// * previous entry. Update its 'next' pointer to the new +// * value */ +// entry->prev->next = entry->next; +// /* If there is an entry following this one, update its 'prev' +// * pointer to the new value */ +// if(entry->next != NULL) +// entry->next->prev = entry->prev; +// } +// /* Free the list entry */ +// kfree( (ptr_t)entry); +// /* Operation successful */ +// return true; +// } +// +// unsigned int list_remove_data(ListEntry * * list, ListEqualFunc callback, +// ListValue data) { +// unsigned int entries_removed; +// ListEntry * rover; +// ListEntry * next; +// if(list == NULL || callback == NULL) +// return 0; +// entries_removed = 0; +// /* Iterate over the entries in the list */ +// rover = *list; +// while(rover != NULL) { +// next = rover->next; +// if(callback(rover->data, data) ) { +// /* This data needs to be removed. Unlink this entry +// * from the list. */ +// if(rover->prev == NULL) +// /* This is the first entry in the list */ +// *list = rover->next; +// else +// /* Point the previous entry at its new +// * location */ +// rover->prev->next = rover->next; +// if(rover->next != NULL) +// rover->next->prev = rover->prev; +// /* Free the entry */ +// kfree( (ptr_t)rover); +// ++entries_removed; +// } +// /* Advance to the next list entry */ +// rover = next; +// } +// return entries_removed; +// } +// +// /* Function used internally for sorting. Returns the last entry in the +// * new sorted list */ +// static ListEntry * list_sort_internal(ListEntry * * list, +// ListCompareFunc compare_func) { +// ListEntry * pivot; +// ListEntry * rover; +// ListEntry * less_list, * more_list; +// ListEntry * less_list_end, * more_list_end; +// if(list == NULL || compare_func == NULL) +// return NULL; +// +// /* If there are less than two entries in this list, it is +// * already sorted */ +// +// if(*list == NULL || (*list)->next == NULL) +// return *list; +// /* The first entry is the pivot */ +// pivot = *list; +// /* Iterate over the list, starting from the second entry. Sort +// * all entries into the less and more lists based on comparisons +// * with the pivot */ +// less_list = NULL; +// more_list = NULL; +// rover = (*list)->next; +// while(rover != NULL) { +// ListEntry * next = rover->next; +// if(compare_func(rover->data, pivot->data) < 0) { +// /* Place this in the less list */ +// rover->prev = NULL; +// rover->next = less_list; +// if(less_list != NULL) +// less_list->prev = rover; +// less_list = rover; +// } else { +// /* Place this in the more list */ +// rover->prev = NULL; +// rover->next = more_list; +// if(more_list != NULL) +// more_list->prev = rover; +// more_list = rover; +// } +// rover = next; +// } +// /* Sort the sublists recursively */ +// less_list_end = list_sort_internal(&less_list, compare_func); +// more_list_end = list_sort_internal(&more_list, compare_func); +// /* Create the new list starting from the less list */ +// *list = less_list; +// /* Append the pivot to the end of the less list. If the less list +// * was empty, start from the pivot */ +// if(less_list == NULL) { +// pivot->prev = NULL; +// *list = pivot; +// } else { +// pivot->prev = less_list_end; +// less_list_end->next = pivot; +// } +// /* Append the more list after the pivot */ +// pivot->next = more_list; +// if(more_list != NULL) +// more_list->prev = pivot; +// /* Work out what the last entry in the list is. If the more list was +// * empty, the pivot was the last entry. Otherwise, the end of the +// * more list is the end of the total list. */ +// if(more_list == NULL) +// return pivot; +// else +// return more_list_end; +// } +// +// void list_sort(ListEntry * * list, ListCompareFunc compare_func) { +// list_sort_internal(list, compare_func); +// } +// +// ListEntry * list_find_data(ListEntry * list, +// ListEqualFunc callback, +// ListValue data) { +// ListEntry * rover; +// /* Iterate over entries in the list until the data is found */ +// for(rover = list ; rover != NULL ; rover = rover->next) { +// if(callback(rover->data, data) != 0) +// return rover; +// } +// /* Not found */ +// return NULL; +// } +// +// void list_iterate(ListEntry * * list, ListIterator * iter) { +// /* Start iterating from the beginning of the list. */ +// iter->prev_next = list; +// /* We have not yet read the first item. */ +// iter->current = NULL; +// } +// +// int list_iter_has_more(ListIterator * iter) { +// if(iter->current == NULL || iter->current != *iter->prev_next) +// /* Either we have not read the first entry, the current +// * item was removed or we have reached the end of the +// * list. Use prev_next to determine if we have a next +// * value to iterate over. */ +// return *iter->prev_next != NULL; +// else +// /* The current entry as not been deleted since the last +// * call to list_iter_next: there is a next entry if +// * current->next is not NULL */ +// return iter->current->next != NULL; +// } +// +// ListValue list_iter_next(ListIterator * iter) { +// if(iter->current == NULL || iter->current != *iter->prev_next) +// /* Either we are reading the first entry, we have reached +// * the end of the list, or the previous entry was removed. +// * Get the next entry with iter->prev_next. */ +// iter->current = *iter->prev_next; +// else { +// /* Last value returned from list_iter_next was not deleted. +// * Advance to the next entry. */ +// iter->prev_next = &iter->current->next; +// iter->current = iter->current->next; +// } +// /* Have we reached the end of the list? */ +// if(iter->current == NULL) +// return LIST_NULL; +// else +// return iter->current->data; +// } +// +// void list_iter_remove(ListIterator * iter) { +// if(iter->current == NULL || iter->current != *iter->prev_next) { +// /* Either we have not yet read the first item, we have +// * reached the end of the list, or we have already removed +// * the current value. Either way, do nothing. */ +// } else { +// /* Remove the current entry */ +// *iter->prev_next = iter->current->next; +// if(iter->current->next != NULL) +// iter->current->next->prev = iter->current->prev; +// kfree( (ptr_t)iter->current); +// iter->current = NULL; +// } +// } #ifdef __cplusplus } diff --git a/src/ds_alg/include/linkedlist.h b/src/ds_alg/include/linkedlist.h index 341ec747936e42476dc52c1733d8691aa0ddcc57..4abfe36a2f0a89b54a3597fb3bf65a0bcc0cf460 100644 --- a/src/ds_alg/include/linkedlist.h +++ b/src/ds_alg/include/linkedlist.h @@ -12,6 +12,8 @@ extern "C" { #include "stddef.h" #include "stdbool.h" +// NOTE!!! +// åªèƒ½åœ¨ heap_init() 返回åŽä½¿ç”¨ // linkedlist /** @@ -40,8 +42,8 @@ typedef void * ListValue; */ struct _ListIterator { - ListEntry * * prev_next; - ListEntry * current; + ListEntry * * prev_next; + ListEntry * current; }; /* A doubly-linked list */ @@ -214,7 +216,7 @@ bool list_remove_entry(ListEntry * * list, ListEntry * entry); */ unsigned int list_remove_data(ListEntry * * list, ListEqualFunc callback, - ListValue data); + ListValue data); /** * Sort a list. @@ -237,8 +239,8 @@ void list_sort(ListEntry * * list, ListCompareFunc compare_func); */ ListEntry * list_find_data(ListEntry * list, - ListEqualFunc callback, - ListValue data); + ListEqualFunc callback, + ListValue data); /** * Initialise a @ref ListIterator structure to iterate over a list. diff --git a/src/include/arch_init.h b/src/include/arch_init.h new file mode 100644 index 0000000000000000000000000000000000000000..ffd832262feb9207082b61231ad15276cde90472 --- /dev/null +++ b/src/include/arch_init.h @@ -0,0 +1,19 @@ + +// This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). +// +// arch_init.h for MRNIU/SimpleKernel. + +#ifndef _ARCH_INIT_H_ +#define _ARCH_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void arch_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _ARCH_INIT_H_ */ diff --git a/src/include/debug.h b/src/include/debug.h index aee500fd3d6cd960bc2c39f919e9b6ca246c1790..5eaa68963530a00ae2c9e2f4d5fa49252321589e 100644 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -10,10 +10,6 @@ extern "C" { #endif -#include "stddef.h" -#include "stdio.h" -#include "string.h" -#include "intr/include/intr.h" #include "elf.h" #define DEBUG 1 diff --git a/src/include/mem/buddy.h b/src/include/mem/buddy.h new file mode 100644 index 0000000000000000000000000000000000000000..e73e2cde4427a34f4bd96b15161c22eb2ff462ab --- /dev/null +++ b/src/include/mem/buddy.h @@ -0,0 +1,17 @@ + +// This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). +// +// buddy.h for MRNIU/SimpleKernel. + +#ifndef _BUDDY_H_ +#define _BUDDY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _BUDDY_H_ */ diff --git a/src/include/mem/e820.h b/src/include/mem/e820.h new file mode 100644 index 0000000000000000000000000000000000000000..07e1ef797a6c71194be5bd4771bb5af24c697b5a --- /dev/null +++ b/src/include/mem/e820.h @@ -0,0 +1,30 @@ + +// This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). +// +// e820.h for MRNIU/SimpleKernel. + + +#ifndef _E820_H_ +#define _E820_H_ + +#define E820_MAX 8 +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 +#define E820_NVS 4 +#define E820_UNUSABLE 5 + +typedef + struct e820entry { + uint64_t addr; + uint64_t length; + uint32_t type; +} __attribute__( (packed) ) e820entry_t; + +typedef + struct e820map { + uint32_t nr_map; + e820entry_t map[E820_MAX]; +} e820map_t; + +#endif /* _E820_H_ */ diff --git a/src/include/mem/firstfit.h b/src/include/mem/firstfit.h new file mode 100644 index 0000000000000000000000000000000000000000..bc5d440f0e59932c9b249f1a16d868d1f234e068 --- /dev/null +++ b/src/include/mem/firstfit.h @@ -0,0 +1,22 @@ + +// This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). +// +// firstfit.h for MRNIU/SimpleKernel. + +#ifndef _FIRTSTFIT_H_ +#define _FIRTSTFIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mem/pmm.h" + +// 用于管ç†ç‰©ç†åœ°å€ +extern pmm_manage_t firstfit_manage; + +#ifdef __cplusplus +} +#endif + +#endif /* _FIRTSTFIT_H_ */ diff --git a/src/include/mem/pmm.h b/src/include/mem/pmm.h index 9d0971dbad2059b130e20f55bbb19313838ce286..dd03d700adcae8b23e65192b4af1fabebe18fd66 100644 --- a/src/include/mem/pmm.h +++ b/src/include/mem/pmm.h @@ -10,19 +10,18 @@ extern "C" { #endif -#include "stdint.h" -#include "stdio.h" #include "stddef.h" -#include "debug.h" +#include "stdint.h" +#include "e820.h" #include "multiboot2.h" -#define STACK_SIZE (0x1000UL) // 4096 +#define STACK_SIZE (0x4000UL) // 16KB #define PMM_MAX_SIZE (0x20000000UL) // 512 MB // å†…æ ¸çš„åç§»åœ°å€ #define KERNEL_BASE (0xC0000000UL) -// å†…æ ¸å ç”¨å¤§å° 4MB -#define KERNEL_SIZE (0x400000UL) +// å†…æ ¸å ç”¨å¤§å° 8MB +#define KERNEL_SIZE (0x800000UL) // æ˜ å°„å†…æ ¸éœ€è¦çš„页数 #define PMM_PAGES_KERNEL (KERNEL_SIZE / PMM_PAGE_SIZE) @@ -45,19 +44,27 @@ extern "C" { #define PMM_PAGE_MAX_SIZE (PMM_MAX_SIZE / PMM_PAGE_SIZE)// 物ç†é¡µæ•°é‡ 131072, 0x20000 -extern ptr_t kernel_init_start[]; -extern ptr_t kernel_init_text_start[]; -extern ptr_t kernel_init_text_end[]; -extern ptr_t kernel_init_data_start[]; -extern ptr_t kernel_init_data_end[]; -extern ptr_t kernel_init_end[]; - -extern ptr_t kernel_start[]; -extern ptr_t kernel_text_start[]; -extern ptr_t kernel_text_end[]; -extern ptr_t kernel_data_start[]; -extern ptr_t kernel_data_end[]; -extern ptr_t kernel_end[]; +// A common problem is getting garbage data when trying to use a value defined in a linker script. +// This is usually because they're dereferencing the symbol. A symbol defined in a linker script (e.g. _ebss = .;) +// is only a symbol, not a variable. If you access the symbol using extern uint32_t _ebss; +// and then try to use _ebss the code will try to read a 32-bit integer from the address indicated by _ebss. +// The solution to this is to take the address of _ebss either by using it as & _ebss or by defining it as +// an unsized array(extern char _ebss[]; ) and casting to an integer.(The array notation prevents accidental +// reads from _ebss as arrays must be explicitly dereferenced) +// ref: http://wiki.osdev.org/Using_Linker_Script_Values +extern ptr_t * kernel_init_start; +extern ptr_t * kernel_init_text_start; +extern ptr_t * kernel_init_text_end; +extern ptr_t * kernel_init_data_start; +extern ptr_t * kernel_init_data_end; +extern ptr_t * kernel_init_end; + +extern ptr_t * kernel_start; +extern ptr_t * kernel_text_start; +extern ptr_t * kernel_text_end; +extern ptr_t * kernel_data_start; +extern ptr_t * kernel_data_end; +extern ptr_t * kernel_end; // å¼€å¯åˆ†é¡µæœºåˆ¶ä¹‹åŽçš„å†…æ ¸æ ˆ extern uint8_t kernel_stack[STACK_SIZE]; @@ -67,12 +74,33 @@ extern ptr_t kernel_stack_top; extern multiboot_memory_map_entry_t * mmap_entries; extern multiboot_mmap_tag_t * mmap_tag; +// 内å˜ç®¡ç†ç»“构体 +typedef + struct pmm_manage { + // 管ç†ç®—法的åç§° + const char * name; + // åˆå§‹åŒ– + void (* pmm_manage_init)(ptr_t page_start, uint32_t page_count); + // 申请物ç†å†…å˜ï¼Œå•ä½ä¸º Byte + ptr_t (* pmm_manage_alloc)(uint32_t bytes); + // 释放内å˜é¡µ + void (* pmm_manage_free)(ptr_t addr_start, uint32_t bytes); + // 返回当å‰å¯ç”¨å†…å˜é¡µæ•°é‡ + uint32_t (* pmm_manage_free_pages_count)(void); +} pmm_manage_t; + +// 物ç†å†…å˜åˆå§‹åŒ– +void pmm_phy_init(e820map_t * e820map); +// 物ç†å†…å˜ç®¡ç†åˆå§‹åŒ– +void pmm_mamage_init(e820map_t * e820map); // åˆå§‹åŒ–内å˜ç®¡ç† void pmm_init(void); -ptr_t pmm_alloc(uint32_t byte); +ptr_t pmm_alloc(size_t byte); + +void pmm_free_page(ptr_t addr, uint32_t byte); -void pmm_free_page(ptr_t page); +uint32_t pmm_free_pages_count(void); #ifdef __cplusplus } diff --git a/src/include/mem/slab.h b/src/include/mem/slab.h new file mode 100644 index 0000000000000000000000000000000000000000..4e6c69615e7cf72166ca676b29d39e12149e176c --- /dev/null +++ b/src/include/mem/slab.h @@ -0,0 +1,17 @@ + +// This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). +// +// slab.h for MRNIU/SimpleKernel. + +#ifndef _SLAB_H_ +#define _SLAB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SLAB_H_ */ diff --git a/src/include/mem/vmm.h b/src/include/mem/vmm.h index a7e0ffabad4dd63ee657f87a8b6220c0f98e11f6..635f8cbd39b0a4a306b43030e0a1c33cc04e4136 100644 --- a/src/include/mem/vmm.h +++ b/src/include/mem/vmm.h @@ -10,7 +10,6 @@ extern "C" { #endif -#include "intr/include/intr.h" #include "pmm.h" // 页大å°ï¼Œä¸€é¡µèƒ½æ˜ 射多少 Byte å†…å˜ 2^12 @@ -52,7 +51,6 @@ extern "C" { // æ˜ å°„å†…æ ¸éœ€è¦çš„页目录数 #define VMM_PAGE_DIRECTORIES_KERNEL ( (KERNEL_SIZE / VMM_PAGE_DIRECTORY_SIZE) + 1UL) - // P = 1 表示有效; P = 0 è¡¨ç¤ºæ— æ•ˆã€‚ #define VMM_PAGE_PRESENT (0x00000001) @@ -65,17 +63,6 @@ extern "C" { // 如果为 0 那么页é¢åªèƒ½è¢«è¿è¡Œåœ¨è¶…级用户特æƒçº§ (0,1 或 2) 的程åºè®¿é—®ã€‚ #define VMM_PAGE_KERNEL (0x00000000) -// 线性地å€è½¬æ¢ä¸ºç‰©ç†åœ°å€ -#define VMM_LA_TO_PA(la) (la - KERNEL_BASE) - -static inline ptr_t vmm_la_to_pa(ptr_t la) { - return la - KERNEL_BASE; -} - -static inline ptr_t vmm_pa_to_la(ptr_t pa) { - return pa + KERNEL_BASE; -} - // 获å–一个地å€çš„页目录,高 10 ä½ #define VMM_PGD_INDEX(x) ( ( (x) >> 22) & 0x03FF) @@ -85,10 +72,6 @@ static inline ptr_t vmm_pa_to_la(ptr_t pa) { // 获å–一个地å€çš„页內å移,低 12 ä½ #define VMM_OFFSET_INDEX(x) ( (x) & 0x0FFF) -// æ˜ å°„å†…æ ¸é¡µéœ€è¦çš„页数 0x40000 -// #define VMM_KERNEL_PAGE_COUNT (0x40000000/VMM_PAGE_SIZE) -#define VMM_KERNEL_PAGE_COUNT (0x20000000 / VMM_PAGE_SIZE) - // 页全局目录项 typedef ptr_t pgd_t; @@ -101,6 +84,9 @@ typedef ptr_t pud_t; // 页表项 typedef ptr_t pte_t; +// å†…æ ¸é¡µç›®å½•åŒºåŸŸ +extern pgd_t pgd_kernel[VMM_PAGE_TABLES_PRE_PAGE_DIRECTORY] __attribute__( (aligned(VMM_PAGE_SIZE) ) ); + // åˆå§‹åŒ–虚拟内å˜ç®¡ç† void vmm_init(void); @@ -117,6 +103,12 @@ uint32_t get_mapping(pgd_t * pgd_now, ptr_t va, ptr_t pa); // æ›´æ¢å½“å‰é¡µç›®å½• void switch_pgd(ptr_t pd); +// æ˜ å°„å†…æ ¸è¿›ç¨‹ + +// æ˜ å°„ç”¨æˆ·è¿›ç¨‹ +// 把从 0x00 到 0x80000000 的所有内å˜ï¼ˆåŒ…å«å†…æ ¸ï¼Œæœªåˆ†é…å†…å˜ å’Œ ä¸å˜åœ¨çš„内å˜ï¼‰æ˜ å°„åˆ°é¡µè¡¨ä¸ +void map_user_task_init(pgd_t * pgd); + #ifdef __cplusplus } #endif diff --git a/src/include/multiboot2.h b/src/include/multiboot2.h index e3bcde60643fa046e33b2d8d6cd1846fa47d5947..8920dd22c38ff01438fa4b191b00a24317aaa270 100644 --- a/src/include/multiboot2.h +++ b/src/include/multiboot2.h @@ -22,10 +22,6 @@ extern "C" { #include "stdint.h" #include "stdbool.h" -#include "stdio.h" -#include "stddef.h" -#include "debug.h" -#include "elf64.h" /* How many bytes from the start of the file we search for the header. */ #define MULTIBOOT_SEARCH 32768 @@ -100,78 +96,78 @@ typedef uint32_t multiboot_uint32_t; typedef uint64_t multiboot_uint64_t; struct multiboot_header { - multiboot_uint32_t magic; // Must be MULTIBOOT_MAGIC - see above. - multiboot_uint32_t architecture; // ISA - multiboot_uint32_t header_length; // Total header length. - multiboot_uint32_t checksum; // The above fields plus this one must equal 0 mod 2^32. + multiboot_uint32_t magic; // Must be MULTIBOOT_MAGIC - see above. + multiboot_uint32_t architecture; // ISA + multiboot_uint32_t header_length; // Total header length. + multiboot_uint32_t checksum; // The above fields plus this one must equal 0 mod 2^32. }; struct multiboot_header_tag { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; }; struct multiboot_header_tag_information_request { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t requests[0]; + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t requests[0]; }; struct multiboot_header_tag_address { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t header_addr; - multiboot_uint32_t load_addr; - multiboot_uint32_t load_end_addr; - multiboot_uint32_t bss_end_addr; + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; }; struct multiboot_header_tag_entry_address { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t entry_addr; + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t entry_addr; }; struct multiboot_header_tag_console_flags { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t console_flags; + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t console_flags; }; struct multiboot_header_tag_framebuffer { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t width; - multiboot_uint32_t height; - multiboot_uint32_t depth; + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; }; struct multiboot_header_tag_module_align { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; }; struct multiboot_header_tag_relocatable { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t min_addr; - multiboot_uint32_t max_addr; - multiboot_uint32_t align; - multiboot_uint32_t preference; + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t min_addr; + multiboot_uint32_t max_addr; + multiboot_uint32_t align; + multiboot_uint32_t preference; }; struct multiboot_color { - multiboot_uint8_t red; - multiboot_uint8_t green; - multiboot_uint8_t blue; + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; }; #define MULTIBOOT_MEMORY_AVAILABLE 1 @@ -180,168 +176,166 @@ struct multiboot_color { #define MULTIBOOT_MEMORY_NVS 4 #define MULTIBOOT_MEMORY_BADRAM 5 struct multiboot_mmap_entry { - multiboot_uint64_t addr; - multiboot_uint64_t len; - multiboot_uint32_t type; - multiboot_uint32_t zero; + multiboot_uint64_t addr; + multiboot_uint64_t len; + multiboot_uint32_t type; + multiboot_uint32_t zero; }; typedef struct multiboot_mmap_entry multiboot_memory_map_entry_t; struct multiboot_tag { - multiboot_uint32_t type; - multiboot_uint32_t size; + multiboot_uint32_t type; + multiboot_uint32_t size; }; typedef struct multiboot_tag multiboot_tag_t; typedef struct multiboot_tag multiboot_mmap_tag_t; struct multiboot_tag_string { - multiboot_uint32_t type; - multiboot_uint32_t size; + multiboot_uint32_t type; + multiboot_uint32_t size; char string[0]; }; struct multiboot_tag_module { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t mod_start; - multiboot_uint32_t mod_end; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; char cmdline[0]; }; struct multiboot_tag_basic_meminfo { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t mem_lower; - multiboot_uint32_t mem_upper; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; }; struct multiboot_tag_bootdev { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t biosdev; - multiboot_uint32_t slice; - multiboot_uint32_t part; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; }; struct multiboot_tag_mmap { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t entry_size; - multiboot_uint32_t entry_version; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; struct multiboot_mmap_entry entries[0]; }; struct multiboot_vbe_info_block { - multiboot_uint8_t external_specification[512]; + multiboot_uint8_t external_specification[512]; }; struct multiboot_vbe_mode_info_block { - multiboot_uint8_t external_specification[256]; + multiboot_uint8_t external_specification[256]; }; struct multiboot_tag_vbe { - multiboot_uint32_t type; - multiboot_uint32_t size; + multiboot_uint32_t type; + multiboot_uint32_t size; - multiboot_uint16_t vbe_mode; - multiboot_uint16_t vbe_interface_seg; - multiboot_uint16_t vbe_interface_off; - multiboot_uint16_t vbe_interface_len; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; struct multiboot_vbe_info_block vbe_control_info; struct multiboot_vbe_mode_info_block vbe_mode_info; }; struct multiboot_tag_elf_sections { - multiboot_uint32_t type; // 0x09 - multiboot_uint32_t size; - multiboot_uint32_t num; - multiboot_uint32_t entsize; - multiboot_uint32_t shndx; // 段å—符串表索引 + multiboot_uint32_t type; // 0x09 + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; // 段å—符串表索引 char sections[0]; }; struct multiboot_tag_apm { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint16_t version; - multiboot_uint16_t cseg; - multiboot_uint32_t offset; - multiboot_uint16_t cseg_16; - multiboot_uint16_t dseg; - multiboot_uint16_t flags; - multiboot_uint16_t cseg_len; - multiboot_uint16_t cseg_16_len; - multiboot_uint16_t dseg_len; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; }; struct multiboot_tag_efi32 { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; }; struct multiboot_tag_efi64 { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; }; struct multiboot_tag_smbios { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t major; - multiboot_uint8_t minor; - multiboot_uint8_t reserved[6]; - multiboot_uint8_t tables[0]; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t major; + multiboot_uint8_t minor; + multiboot_uint8_t reserved[6]; + multiboot_uint8_t tables[0]; }; struct multiboot_tag_old_acpi { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; }; struct multiboot_tag_new_acpi { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; }; struct multiboot_tag_network { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t dhcpack[0]; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t dhcpack[0]; }; struct multiboot_tag_efi_mmap { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t descr_size; - multiboot_uint32_t descr_vers; - multiboot_uint8_t efi_mmap[0]; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t descr_size; + multiboot_uint32_t descr_vers; + multiboot_uint8_t efi_mmap[0]; }; struct multiboot_tag_efi32_ih { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; }; struct multiboot_tag_efi64_ih { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; }; struct multiboot_tag_load_base_addr { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t load_base_addr; + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t load_base_addr; }; -// multiboot_memory_map_entry_t * mmap_entries; - bool is_multiboot2_header(ptr_t magic, ptr_t addr); void multiboot2_init(ptr_t magic, ptr_t addr); void print_MULTIBOOT_TAG_TYPE_CMDLINE(struct multiboot_tag * tag); diff --git a/src/kernel.bin b/src/kernel.bin index a9a4bf91e3fa3ac9ff8a84cc3c850dcfc3c68068..24b9384eba7f17401a121a5596ecd3443bbe7b4c 100755 Binary files a/src/kernel.bin and b/src/kernel.bin differ diff --git a/src/kernel/heap.c b/src/kernel/heap.c deleted file mode 100644 index 02ecd4a660f721e9a476e8faaddc8db6e94d6122..0000000000000000000000000000000000000000 --- a/src/kernel/heap.c +++ /dev/null @@ -1,23 +0,0 @@ - -// This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). -// -// heap.c for MRNIU/SimpleKernel. - -#ifdef __cplusplus -extern "C" { -#endif - -#include "stdlib.h" -#include "mem/pmm.h" - -void * kmalloc(size_t byte) { - return (void *)pmm_alloc(byte); -} -void kfree(void * page) { - pmm_free_page( (ptr_t)page); - return; -} - -#ifdef __cplusplus -} -#endif diff --git a/src/kernel/include/kernel.h b/src/kernel/include/kernel.h index 832d9def5cce7fa75507cca1e9c52084edb20ef2..aee031ce3efecb07533660997d030807a97c24dc 100644 --- a/src/kernel/include/kernel.h +++ b/src/kernel/include/kernel.h @@ -24,36 +24,31 @@ extern "C" { #include "stdbool.h" #include "stdio.h" #include "stdlib.h" +#include "console/include/console.h" #include "multiboot2.h" +#include "arch_init.h" #include "mem/pmm.h" #include "mem/vmm.h" void kernel_main(uint32_t magic, uint32_t addr); -void console_init(void); -void gdt_init(void); -void idt_init(void); -void clock_init(void); -void keyboard_init(void); -void mouse_init(void); -void debug_init(uint32_t magic, uint32_t addr); -void pmm_init(void); -void vmm_init(void); -void showinfo(void); +// void gdt_init(void); + +void showinfo(void); void showinfo(void) { // è¾“å‡ºä¸€äº›åŸºæœ¬ä¿¡æ¯ printk_color(magenta, "SimpleKernel\n"); - printk_info("kernel init in memory(VMA==LMA) start: 0x%08X, end 0x%08X\n", kernel_init_start, kernel_init_end); - printk_info(".init.text in memory(VMA==LMA) start: 0x%08X, end 0x%08X\n", kernel_init_text_start, kernel_init_text_end); - printk_info(".init.data in memory(VMA==LMA) start: 0x%08X, end 0x%08X\n", kernel_init_data_start, kernel_init_data_end); + printk_info("kernel init in memory(VMA==LMA) start: 0x%08X, end 0x%08X\n", &kernel_init_start, &kernel_init_end); + printk_info(".init.text in memory(VMA==LMA) start: 0x%08X, end 0x%08X\n", &kernel_init_text_start, &kernel_init_text_end); + printk_info(".init.data in memory(VMA==LMA) start: 0x%08X, end 0x%08X\n", &kernel_init_data_start, &kernel_init_data_end); printk_info("kernel init in memory size: %d KB, %d pages\n", - (kernel_init_end - kernel_init_start) / 1024, (kernel_init_end - kernel_init_start) / 1024 / 4); + (&kernel_init_end - &kernel_init_start) / 1024, (&kernel_init_end - &kernel_init_start) / 1024 / 4); - printk_info("kernel in memory(VMA=LMA-0xC0000000) start: 0x%08X, end 0x%08X\n", kernel_start, kernel_end); - printk_info(".text in memory(VMA=LMA-0xC0000000) start: 0x%08X, end 0x%08X\n", kernel_text_start, kernel_text_end); - printk_info(".data in memory(VMA=LMA-0xC0000000) start: 0x%08X, end 0x%08X\n", kernel_data_start, kernel_data_end); + printk_info("kernel in memory(VMA=LMA+0xC0000000) start: 0x%08X, end 0x%08X\n", &kernel_start, &kernel_end); + printk_info(".text in memory(VMA=LMA+0xC0000000) start: 0x%08X, end 0x%08X\n", &kernel_text_start, &kernel_text_end); + printk_info(".data in memory(VMA=LMA+0xC0000000) start: 0x%08X, end 0x%08X\n", &kernel_data_start, &kernel_data_end); printk_info("kernel in memory size: %d KB, %d pages\n", - (kernel_end - kernel_start) / 1024, (kernel_end - kernel_start) / 1024 / 4); + (&kernel_end - &kernel_start) / 1024, (&kernel_end - &kernel_start) / 1024 / 4); } #ifdef __cplusplus diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 19158c232c82e9c80dabf2f9a3a5b8b81c7fea9e..590d18a630b37f1c858663d9ae618336706bc9be 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -9,18 +9,24 @@ extern "C" { #include "include/kernel.h" #include "../test/include/test.h" +#include "debug.h" // å†…æ ¸å…¥å£ -// 指针是 32 ä½çš„ void kernel_main(ptr_t magic, ptr_t addr) { - console_init(); // 控制å°åˆå§‹åŒ– - multiboot2_init(magic, addr); // 从 multiboot 获得系统åˆå§‹ä¿¡æ¯ - gdt_init(); // GDT åˆå§‹åŒ– - idt_init(); // IDT åˆå§‹åŒ– - clock_init(); // æ—¶é’Ÿåˆå§‹åŒ– - keyboard_init(); // 键盘åˆå§‹åŒ– + // 控制å°åˆå§‹åŒ– + console_init(); + // 从 multiboot 获得系统åˆå§‹ä¿¡æ¯ + multiboot2_init(magic, addr); + // GDTã€IDT åˆå§‹åŒ– + arch_init(); + // æ—¶é’Ÿåˆå§‹åŒ– + clock_init(); + // 键盘åˆå§‹åŒ– + keyboard_init(); debug_init(magic, addr); + // 物ç†å†…å˜åˆå§‹åŒ– pmm_init(); + // 虚拟内å˜åˆå§‹åŒ– vmm_init(); showinfo(); diff --git a/src/kernel/mem/Makefile b/src/kernel/mem/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..980275f977895f317481bbb7dd0d3fd4bde155d1 --- /dev/null +++ b/src/kernel/mem/Makefile @@ -0,0 +1,58 @@ + +# This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). + +# Makefile for MRNIU/SimpleKernel. + +CURR_DIR := $(shell pwd) +PAR_DIR := $(CURR_DIR)/.. +ROOT_DIR := $(CURR_DIR)/../.. +include $(ROOT_DIR)/Makefile.env + +exclude_dirs := include +subdirs := $(shell find . -maxdepth 1 -type d) +subdirs := $(basename $(patsubst ./%, %, $(subdirs))) +subdirs := $(filter-out $(exclude_dirs), $(subdirs)) +SUB_DIR := $(subdirs) + +.PHONY: default +default: + @echo Entry $(CURR_DIR) + @$(MAKE) all + @echo Leave $(CURR_DIR) + +.PHONY: all +all: $(SUB_DIR) + @echo Entry $(CURR_DIR) + @for subdir in $(SUB_DIR); \ + do $(MAKE) -C $$subdir all || exit 1; \ + done + @# $(MAKE) info + @$(MAKE) $(patsubst %.c, %.o, $(wildcard *.c)) + @echo Leave $(CURR_DIR) + +%.o: %.c + @echo 编译 C 文件 $< ... + @$(CC) $(CFLAGS) $< -o $@ + @echo ç¼–è¯‘å®Œæˆ + +.PHONY: clean +clean: + @echo Entry $(CURR_DIR) + @echo æ£åœ¨åˆ 除... $< + @echo åˆ é™¤å®Œæ¯• + @echo Leave $(CURR_DIR) + +.PHONY: info +info: + @echo Current dir: $(CURR_DIR) + @echo ARCH: $(ARCH) + @echo CC: $(CC) + @echo CFLAGS: $(CFLAGS) + @echo CXX: $(CXX) + @echo CXXFLAGS: $(CXXFLAGS) + @echo LD: $(LD) + @echo LDFLAGS: $(LDFLAGS) + @echo AS: $(AS) + @echo ASFLAGS: $(ASFLAGS) + @echo exclude_dirs: $(exclude_dirs) + @echo SUBDIRS: $(SUB_DIR) diff --git a/src/kernel/mem/buddy.c b/src/kernel/mem/buddy.c new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/kernel/mem/fitst_fit.c b/src/kernel/mem/fitst_fit.c new file mode 100644 index 0000000000000000000000000000000000000000..3fb43c3943de8081a2ae53ec68c7ec5212c9cbc9 --- /dev/null +++ b/src/kernel/mem/fitst_fit.c @@ -0,0 +1,250 @@ + +// This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). +// +// first_fit.c for MRNIU/SimpleKernel. + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdio.h" +#include "string.h" +#include "assert.h" +#include "mem/firstfit.h" + +#define FF_USED 0x00 +#define FF_UNUSED 0x01 + +static void init(ptr_t page_start, uint32_t page_count); +static ptr_t alloc(uint32_t bytes); +static void free(ptr_t addr_start, uint32_t bytes); +static uint32_t free_pages_count(void); + +pmm_manage_t firstfit_manage = { + "Fitst Fit", + &init, + &alloc, + &free, + &free_pages_count +}; + +// å— +typedef + struct chunk_info { + // 当å‰é¡µçš„åœ°å€ + ptr_t addr; + // 拥有多少个连ç»çš„页 + uint32_t npages; + // 物ç†é¡µè¢«å¼•用的次数 + int32_t ref; + // 当å‰é¡µçŠ¶æ€ + uint32_t flag; +} chunk_info_t; + +// 一个仅在这里使用的简å•循环链表 +typedef + struct list_entry { + chunk_info_t chunk_info; + struct list_entry * next; + struct list_entry * prev; +} list_entry_t; + +static inline void list_init_head(list_entry_t * list); + +// 在ä¸é—´æ·»åŠ å…ƒç´ +static inline void list_add_middle(list_entry_t * prev, list_entry_t * next, list_entry_t * new); + +// 在 prev åŽæ·»åР项 +static inline void list_add_after(list_entry_t * prev, list_entry_t * new); + +// 在 next 剿·»åР项 +static inline void list_add_before(list_entry_t * next, list_entry_t * new); + +// åˆ é™¤å…ƒç´ +static inline void list_del(list_entry_t * list); + +// 返回å‰é¢çš„å…ƒç´ +static inline list_entry_t * list_prev(list_entry_t * list); + +// 返回åŽé¢çš„çš„å…ƒç´ +static inline list_entry_t * list_next(list_entry_t * list); + +// 返回 chunk_info +static inline chunk_info_t * list_chunk_info(list_entry_t * list); + +// åˆå§‹åŒ– +void list_init_head(list_entry_t * list) { + list->next = list; + list->prev = list; + return; +} + +// 在ä¸é—´æ·»åŠ å…ƒç´ +void list_add_middle(list_entry_t * prev, list_entry_t * next, list_entry_t * new) { + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +// 在 prev åŽæ·»åР项 +void list_add_after(list_entry_t * prev, list_entry_t * new) { + list_add_middle(prev, prev->next, new); + return; +} + +// 在 next 剿·»åР项 +void list_add_before(list_entry_t * next, list_entry_t * new) { + list_add_middle(next->prev, next, new); + return; +} + +// åˆ é™¤å…ƒç´ +void list_del(list_entry_t * list) { + list->next->prev = list->prev; + list->prev->next = list->next; + return; +} + +// 返回å‰é¢çš„å…ƒç´ +list_entry_t * list_prev(list_entry_t * list) { + return list->prev; +} + +// 返回åŽé¢çš„çš„å…ƒç´ +list_entry_t * list_next(list_entry_t * list) { + return list->next; +} + +// 返回 chunk_info +chunk_info_t * list_chunk_info(list_entry_t * list) { + return &(list->chunk_info); +} + +typedef + struct firstfit_manage { + // 物ç†å†…å˜èµ·å§‹åœ°å€ + ptr_t pmm_addr_start; + // 物ç†å†…å˜ç»“æŸåœ°å€ + ptr_t pmm_addr_end; + // 物ç†å†…å˜é¡µçš„æ€»æ•°é‡ + uint32_t phy_page_count; + // 物ç†å†…å˜é¡µçš„当剿•°é‡ + uint32_t phy_page_now_count; + // 空闲链表 + list_entry_t * free_list; +} firstfit_manage_t; + +// First Fit 算法需è¦çš„ä¿¡æ¯ +static firstfit_manage_t ff_manage; + +// 物ç†é¡µä¿¡æ¯ä¿å˜åœ°å€ +static list_entry_t * pmm_info = NULL; + +void init(ptr_t page_start, uint32_t page_count) { + // ä½äºŽå†…æ ¸ç»“æŸåŽï¼Œå¤§å°ä¸º (PMM_MAX_SIZE / PMM_PAGE_SIZE)*sizeof(list_entry_t) + // åŽé¢çš„æ“ä½œæ˜¯è¿›è¡Œé¡µå¯¹é½ + pmm_info = (list_entry_t *)( ( (ptr_t)(&kernel_end + PMM_PAGE_SIZE) & PMM_PAGE_MASK) ); + uint32_t pmm_info_size = (PMM_MAX_SIZE / PMM_PAGE_SIZE) * sizeof(list_entry_t); + bzero(pmm_info, pmm_info_size); + + // è¶Šè¿‡å†…æ ¸ä½¿ç”¨çš„å†…å˜ + pmm_info->chunk_info.addr = page_start + KERNEL_SIZE; + pmm_info->chunk_info.npages = page_count - PMM_PAGES_KERNEL; + pmm_info->chunk_info.ref = 0; + pmm_info->chunk_info.flag = FF_UNUSED; + + ff_manage.phy_page_count = page_count; + ff_manage.phy_page_now_count = page_count - PMM_PAGES_KERNEL; + // 0x100000 + ff_manage.pmm_addr_start = page_start + KERNEL_SIZE; + // 0x1FFF0000 + ff_manage.pmm_addr_end = page_start + page_count * PMM_PAGE_SIZE; + ff_manage.free_list = pmm_info; + list_init_head(ff_manage.free_list); + return; +} + +ptr_t alloc(uint32_t bytes) { + // 计算需è¦çš„页数 + uint32_t pages = bytes / PMM_PAGE_SIZE; + // ä¸è¶³ä¸€é¡µçš„+1 + if(bytes % PMM_PAGE_SIZE != 0) { + pages++; + } + list_entry_t * entry = ff_manage.free_list; + while(entry != NULL) { + // 查找符åˆé•¿åº¦ä¸”æœªä½¿ç”¨çš„å†…å˜ + if( (list_chunk_info(entry)->npages >= pages) && (list_chunk_info(entry)->flag == FF_UNUSED) ) { + // 如果剩余大å°è¶³å¤Ÿ + if(list_chunk_info(entry)->npages - pages > 1) { + // æ·»åŠ æ–°çš„é“¾è¡¨é¡¹ + list_entry_t * tmp = (list_entry_t *)(entry + sizeof(list_entry_t) ); + list_chunk_info(tmp)->addr = entry->chunk_info.addr + pages * PMM_PAGE_SIZE; + list_chunk_info(tmp)->npages = entry->chunk_info.npages - pages; + list_chunk_info(tmp)->ref = 0; + list_chunk_info(tmp)->flag = FF_UNUSED; + list_add_after(entry, tmp); + } + // ä¸å¤Ÿçš„è¯ç›´æŽ¥åˆ†é… + list_chunk_info(entry)->npages = pages; + list_chunk_info(entry)->ref = 1; + list_chunk_info(entry)->flag = FF_USED; + ff_manage.phy_page_now_count -= pages; + return list_chunk_info(entry)->addr; + } + // 没找到的è¯å°±æŸ¥æ‰¾ä¸‹ä¸€ä¸ª + else if(list_next(entry) != ff_manage.free_list) { + entry = list_next(entry); + } + else { + printk_err("Error at firstfit.c: ptr_t alloc(uint32_t)\n"); + break; + } + } + printk_err("Error at firstfit.c: ptr_t alloc(uint32_t)\n"); + return (ptr_t)NULL; +} + +void free(ptr_t addr_start, uint32_t bytes) { + // 计算需è¦çš„页数 + uint32_t pages = bytes / PMM_PAGE_SIZE; + // ä¸è¶³ä¸€é¡µçš„+1 + if(bytes % PMM_PAGE_SIZE != 0) { + pages++; + } + // 首先找到地å€å¯¹åº”的管ç†èŠ‚ç‚¹ + list_entry_t * entry = ff_manage.free_list; + while( ( (entry = list_next(entry) ) != ff_manage.free_list) && (list_chunk_info(entry)->addr != addr_start) ); + + // 释放所有页 + list_chunk_info(entry)->ref = 0; + list_chunk_info(entry)->flag = FF_UNUSED; + + // 如果于相邻链表有空闲的则åˆå¹¶ + // åŽé¢ + if(entry->next != entry && list_chunk_info(entry->next)->flag == FF_UNUSED) { + list_entry_t * next = entry->next; + list_chunk_info(entry)->npages += list_chunk_info(next)->npages; + list_chunk_info(next)->npages = 0; + list_del(next); + } + // å‰é¢ + if(entry->prev != entry && list_chunk_info(entry->prev)->flag == FF_UNUSED) { + list_entry_t * prev = entry->prev; + list_chunk_info(prev)->npages += list_chunk_info(entry)->npages; + list_chunk_info(entry)->npages = 0; + list_del(entry); + } + ff_manage.phy_page_now_count += pages; + return; +} + +uint32_t free_pages_count() { + return ff_manage.phy_page_now_count; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/kernel/mem/slab.c b/src/kernel/mem/slab.c new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/kernel/multiboot2.c b/src/kernel/multiboot2.c index 351b0edaf9499d992eaf7d6b5908443d332776e9..4578ba8d8e0f0f149fcc9b16a4f7e8d82e7a4c14 100644 --- a/src/kernel/multiboot2.c +++ b/src/kernel/multiboot2.c @@ -7,59 +7,61 @@ extern "C" { #endif +#include "stdio.h" +#include "debug.h" +#include "cpu.hpp" #include "multiboot2.h" -#include "string.h" void print_MULTIBOOT_TAG_TYPE_CMDLINE(multiboot_tag_t * tag) { printk_info("Command line = %s\n", - ( (struct multiboot_tag_string *)tag)->string); + ( (struct multiboot_tag_string *)tag)->string); return; } void print_MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME(multiboot_tag_t * tag) { printk_info("Boot loader name = %s\n", - ( (struct multiboot_tag_string *)tag)->string); + ( (struct multiboot_tag_string *)tag)->string); return; } void print_MULTIBOOT_TAG_TYPE_MODULE(multiboot_tag_t * tag) { printk_info("Module at 0x%X-0x%X. Command line %s\n", - ( (struct multiboot_tag_module *)tag)->mod_start, - ( (struct multiboot_tag_module *)tag)->mod_end, - ( (struct multiboot_tag_module *)tag)->cmdline); + ( (struct multiboot_tag_module *)tag)->mod_start, + ( (struct multiboot_tag_module *)tag)->mod_end, + ( (struct multiboot_tag_module *)tag)->cmdline); return; } void print_MULTIBOOT_TAG_TYPE_BASIC_MEMINFO(multiboot_tag_t * tag) { printk_info("mem_lower = %uKB, mem_upper = %uKB\n", - ( (struct multiboot_tag_basic_meminfo *)tag)->mem_lower, - ( (struct multiboot_tag_basic_meminfo *)tag)->mem_upper); + ( (struct multiboot_tag_basic_meminfo *)tag)->mem_lower, + ( (struct multiboot_tag_basic_meminfo *)tag)->mem_upper); return; } void print_MULTIBOOT_TAG_TYPE_BOOTDEV(multiboot_tag_t * tag) { printk_info("Boot device 0x%X,%u,%u\n", - ( (struct multiboot_tag_bootdev *)tag)->biosdev, - ( (struct multiboot_tag_bootdev *)tag)->slice, - ( (struct multiboot_tag_bootdev *)tag)->part); + ( (struct multiboot_tag_bootdev *)tag)->biosdev, + ( (struct multiboot_tag_bootdev *)tag)->slice, + ( (struct multiboot_tag_bootdev *)tag)->part); return; } void print_MULTIBOOT_TAG_TYPE_MMAP(multiboot_tag_t * tag) { mmap_entries = ( (struct multiboot_tag_mmap *)tag)->entries; mmap_tag = tag; +#if DEBUG multiboot_memory_map_entry_t * mmap; mmap = ( (struct multiboot_tag_mmap *)tag)->entries; -#if DEBUG printk_info("mmap\n"); for( ; (uint8_t *)mmap < (uint8_t *)tag + tag->size ; mmap = (multiboot_memory_map_entry_t *)( (uint32_t)mmap + ( (struct multiboot_tag_mmap *)tag)->entry_size) ) { printk_info("base_addr = 0x%X%X, length = 0x%X%X, type = 0x%X\n", - (unsigned)(mmap->addr >> 32),// high - (unsigned)(mmap->addr & 0xffffffff),// low - (unsigned)(mmap->len >> 32),// high - (unsigned)(mmap->len & 0xffffffff),// low - (unsigned)mmap->type); + (unsigned)(mmap->addr >> 32),// high + (unsigned)(mmap->addr & 0xffffffff),// low + (unsigned)(mmap->len >> 32),// high + (unsigned)(mmap->len & 0xffffffff),// low + (unsigned)mmap->type); } #endif return; @@ -68,37 +70,37 @@ void print_MULTIBOOT_TAG_TYPE_MMAP(multiboot_tag_t * tag) { void print_MULTIBOOT_TAG_TYPE_ELF_SECTIONS(multiboot_tag_t * tag) { #if DEBUG printk_info("Elf type 0x%X, Size 0x%X, num 0x%X, entsize 0x%X, shndx 0x%X.\n", - ( (struct multiboot_tag_elf_sections *)tag)->type, - ( (struct multiboot_tag_elf_sections *)tag)->size, - ( (struct multiboot_tag_elf_sections *)tag)->num, - ( (struct multiboot_tag_elf_sections *)tag)->entsize, - ( (struct multiboot_tag_elf_sections *)tag)->shndx); + ( (struct multiboot_tag_elf_sections *)tag)->type, + ( (struct multiboot_tag_elf_sections *)tag)->size, + ( (struct multiboot_tag_elf_sections *)tag)->num, + ( (struct multiboot_tag_elf_sections *)tag)->entsize, + ( (struct multiboot_tag_elf_sections *)tag)->shndx); #endif return; } void print_MULTIBOOT_TAG_TYPE_APM(multiboot_tag_t * tag) { printk_info("APM type 0x%X, Size 0x%X, version 0x%X, cseg 0x%X, offset 0x%X, cseg_16 0x%X, " - "dseg 0x%X, flags 0x%X, cseg_len 0x%X, cseg_16_len 0x%X, dseg_len 0x%X\n", - ( (struct multiboot_tag_apm *)tag)->type, - ( (struct multiboot_tag_apm *)tag)->size, - ( (struct multiboot_tag_apm *)tag)->version, - ( (struct multiboot_tag_apm *)tag)->cseg, - ( (struct multiboot_tag_apm *)tag)->offset, - ( (struct multiboot_tag_apm *)tag)->cseg_16, - ( (struct multiboot_tag_apm *)tag)->dseg, - ( (struct multiboot_tag_apm *)tag)->flags, - ( (struct multiboot_tag_apm *)tag)->cseg_len, - ( (struct multiboot_tag_apm *)tag)->cseg_16_len, - ( (struct multiboot_tag_apm *)tag)->dseg_len); + "dseg 0x%X, flags 0x%X, cseg_len 0x%X, cseg_16_len 0x%X, dseg_len 0x%X\n", + ( (struct multiboot_tag_apm *)tag)->type, + ( (struct multiboot_tag_apm *)tag)->size, + ( (struct multiboot_tag_apm *)tag)->version, + ( (struct multiboot_tag_apm *)tag)->cseg, + ( (struct multiboot_tag_apm *)tag)->offset, + ( (struct multiboot_tag_apm *)tag)->cseg_16, + ( (struct multiboot_tag_apm *)tag)->dseg, + ( (struct multiboot_tag_apm *)tag)->flags, + ( (struct multiboot_tag_apm *)tag)->cseg_len, + ( (struct multiboot_tag_apm *)tag)->cseg_16_len, + ( (struct multiboot_tag_apm *)tag)->dseg_len); return; } void print_MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR(multiboot_tag_t * tag) { printk_info("Image load base physical address type 0x%X, size 0x%X, addr 0x%X.\n", - ( (struct multiboot_tag_load_base_addr *)tag)->type, - ( (struct multiboot_tag_load_base_addr *)tag)->size, - ( (struct multiboot_tag_load_base_addr *)tag)->load_base_addr); + ( (struct multiboot_tag_load_base_addr *)tag)->type, + ( (struct multiboot_tag_load_base_addr *)tag)->size, + ( (struct multiboot_tag_load_base_addr *)tag)->load_base_addr); return; } @@ -116,6 +118,7 @@ bool is_multiboot2_header(ptr_t magic, ptr_t addr) { // å¤„ç† multiboot ä¿¡æ¯ void multiboot2_init(ptr_t magic, ptr_t addr) { + cpu_cli(); // Am I booted by a Multiboot-compliant boot loader? is_multiboot2_header(magic, addr); uint32_t size = *(uint32_t *)addr; @@ -197,6 +200,7 @@ void multiboot2_init(ptr_t magic, ptr_t addr) { // tag = (multiboot_tag_t *) ((uint8_t *) tag + ((tag->size + 7) & ~7)); // printk_info ("Total mbi size 0x%X\n", (unsigned) tag - addr); // printk_info("multiboot2_init\n"); + cpu_sti(); return; } diff --git a/src/libc/assert.h b/src/libc/assert.h index 6ba5696435478f4a5f695d14b0987e7dd475f81d..a456eb244e28a4cc1dd953b065bc8096a3b8ada2 100644 --- a/src/libc/assert.h +++ b/src/libc/assert.h @@ -12,11 +12,11 @@ extern "C" { #include "stdio.h" -#define assert(test) \ - if(!(test)) { \ - printk_err("ASSERT ERROR!"); \ - while(1); \ - } +#define assert(test, info) \ + if(!(test) ) { \ + printk_err(info); \ + while(1) { }; \ + } #ifdef __cplusplus } diff --git a/src/libc/stdio/printk.c b/src/libc/stdio/printk.c index a474f897b1c61519fa3259fa914584a39f8c5b78..922612dbc0d018ff862bd24565c765794290c805 100644 --- a/src/libc/stdio/printk.c +++ b/src/libc/stdio/printk.c @@ -10,6 +10,7 @@ extern "C" { #include "stdio.h" #include "stdarg.h" #include "stdint.h" +#include "debug.h" static char buf[1024]; @@ -28,7 +29,7 @@ int32_t printk(const char * fmt, ...) { return i; } -int32_t printk_color(uint8_t color, const char * fmt, ...){ +int32_t printk_color(uint8_t color, const char * fmt, ...) { va_list args; int i; va_start(args, fmt); @@ -56,6 +57,7 @@ int32_t printk_info(const char * fmt, ...) { } int32_t printk_debug(const char * fmt, ...) { +#ifdef DEBUG printk_color(COL_DEBUG, "[DEBUG] "); va_list args; int i; @@ -64,6 +66,9 @@ int32_t printk_debug(const char * fmt, ...) { va_end(args); console_writestring(buf); return i; +#else + return 0; +#endif } int32_t printk_test(const char * fmt, ...) { diff --git a/src/libc/stdlib.h b/src/libc/stdlib.h index 63756bba838891a2d5cfb2b4db556578ee6d26fe..b37dd4a57435815096e10b0dd44c022fa4ebc500 100644 --- a/src/libc/stdlib.h +++ b/src/libc/stdlib.h @@ -17,8 +17,8 @@ int atoi(const char *); long atol(const char *); long long atoll(const char *); -void * kmalloc(uint32_t); -void kfree(void *); +void * malloc(uint32_t); +void free(void *); #ifdef __cplusplus } diff --git a/src/libc/string/string.c b/src/libc/string/string.c index 1b60ab7cec5c9cd5abff12c4dad3f1702086d112..7cf8bf850a241c75d78b2a4cdcbdda834c965219 100644 --- a/src/libc/string/string.c +++ b/src/libc/string/string.c @@ -10,7 +10,7 @@ extern "C" { #include "string.h" // 获å–å—符串长度 -size_t strlen(const char* str){ +size_t strlen(const char * str) { size_t len = 0; while(str[len]) len++; @@ -19,32 +19,32 @@ size_t strlen(const char* str){ // 如果 src > dest, 则返回值大于 0,如果 src = dest, 则返回值ç‰äºŽ 0, // 如果 srd < dest ,则返回值å°äºŽ 0。 -int8_t strcmp(const char * src, const char * dest){ - while ( *src && *dest && (*src == *dest) ) { +int8_t strcmp(const char * src, const char * dest) { + while(*src && *dest && (*src == *dest) ) { src++; dest++; } return *src - *dest; } -char * strcpy(char * dest, const char * src){ +char * strcpy(char * dest, const char * src) { char * address = dest; - while( (*dest++ = *src++) != '\0' ); + while( (*dest++ = *src++) != '\0'); return address; } -void backspace(char * src){ +void backspace(char * src) { size_t len = strlen(src); src[len - 1] = '\0'; } -void append(char * src, char dest){ +void append(char * src, char dest) { size_t len = strlen(src); src[len] = dest; src[len + 1] = '\0'; } -char * strcat(char * dest, const char * src){ +char * strcat(char * dest, const char * src) { uint8_t * add_d = (uint8_t *)dest; if(dest != NULL && src != NULL) { while(*add_d) @@ -57,16 +57,16 @@ char * strcat(char * dest, const char * src){ return dest; } -void memcpy(void * dest, void * src, uint32_t len){ +void memcpy(void * dest, void * src, uint32_t len) { uint8_t * sr = (uint8_t *)src; uint8_t * dst = (uint8_t *)dest; - while (len != 0) { + while(len != 0) { *dst++ = *sr++; len--; } } -void memset(void * dest, uint8_t val, uint32_t len){ - for (uint8_t * dst = (uint8_t *)dest; len != 0; len--) { +void memset(void * dest, uint8_t val, uint32_t len) { + for(uint8_t * dst = (uint8_t *)dest ; len != 0 ; len--) { *dst++ = val; } } diff --git a/src/libc/types.h b/src/libc/types.h new file mode 100644 index 0000000000000000000000000000000000000000..e26c1770b5c81d5e9d2cab69f92d96901f1d106d --- /dev/null +++ b/src/libc/types.h @@ -0,0 +1,21 @@ + +// This file is a part of MRNIU/SimpleKernel (https://github.com/MRNIU/SimpleKernel). +// +// types.h for MRNIU/SimpleKernel. + +#ifndef _TYPES_H_ +#define _TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" + +typedef int32_t pid_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _TYPES_H_ */ diff --git a/src/test/include/test.h b/src/test/include/test.h index a2bd95bd7a23f6d1ac8605f9a2e0f78dc537b3e6..6e2de08ddbe38de42dcb4cdfd5b82c4a76fe7413 100644 --- a/src/test/include/test.h +++ b/src/test/include/test.h @@ -23,7 +23,6 @@ bool test(void); bool test_pmm(void); bool test_vmm(void); bool test_libc(void); -bool test_heap(void); #ifdef __cplusplus } diff --git a/src/test/test.c b/src/test/test.c index b5f27fd91c35c319eba28bc4525d56bb35bba766..c7ff4be8a068855ae76e834d2eb107f037aa59e8 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -8,7 +8,6 @@ extern "C" { #endif #include "include/test.h" -#include "stdlib.h" bool test_pmm(void) { ptr_t allc_addr = 0; @@ -16,12 +15,16 @@ bool test_pmm(void) { allc_addr = pmm_alloc(1); printk_test("Alloc Physical Addr: 0x%08X\n", allc_addr); allc_addr = pmm_alloc(9000); - pmm_free_page(allc_addr); printk_test("Alloc Physical Addr: 0x%08X\n", allc_addr); + printk_test("Free pages count: %d\n", pmm_free_pages_count() ); + pmm_free_page(allc_addr, 9000); + printk_test("Free!\n"); + printk_test("Free pages count: %d\n", pmm_free_pages_count() ); allc_addr = pmm_alloc(1); printk_test("Alloc Physical Addr: 0x%08X\n", allc_addr); allc_addr = pmm_alloc(1); printk_test("Alloc Physical Addr: 0x%08X\n", allc_addr); + printk_test("Free pages count: %d\n", pmm_free_pages_count() ); return true; } @@ -33,30 +36,10 @@ bool test_libc() { return true; } -bool test_heap() { - printk_test("Test Heap kmalloc :\n"); - ptr_t allc_addr1 = (ptr_t)kmalloc(9000); - printk_test("Alloc Physical Addr: 0x%08X\n", allc_addr1); - ptr_t allc_addr2 = (ptr_t)kmalloc(1); - printk_test("Alloc Physical Addr: 0x%08X\n", allc_addr2); - ptr_t allc_addr3 = (ptr_t)kmalloc(1); - printk_test("Alloc Physical Addr: 0x%08X\n", allc_addr3); - ptr_t allc_addr4 = (ptr_t)kmalloc(1); - printk_test("Alloc Physical Addr: 0x%08X\n", allc_addr4); - printk_test("Test Heap kfree :\n"); - kfree( (void *)allc_addr1); - kfree( (void *)allc_addr2); - kfree( (void *)allc_addr3); - kfree( (void *)allc_addr4); - ptr_t new_addr = (ptr_t)kmalloc(9000); - printk_test("New Alloc Physical Addr: 0x%08X\n", new_addr); - - return true; -} - bool test(void) { test_pmm(); - test_heap(); + test_vmm(); + // test_libc(); return true; } diff --git a/tools/codestyle.cfg b/tools/codestyle.cfg index 1a43a2a11bd94aa1154fd8befe5f4a9f08b3d7af..1bbfea7913760a64f616417c1830bc0e5c949d04 100644 --- a/tools/codestyle.cfg +++ b/tools/codestyle.cfg @@ -43,7 +43,7 @@ indent_columns = 8 # number # The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents. # For FreeBSD, this is set to 4. Negative value is absolute and not increased for each ( level -indent_continue = 0 # number +indent_continue = 4 # number # How to use tabs when indenting code # 0=spaces only @@ -94,7 +94,7 @@ indent_namespace_limit = 0 # number indent_extern = false # false/true # Whether the 'class' body is indented -indent_class = false # false/true +indent_class = true # false/true # Whether to indent the stuff after a leading class colon indent_class_colon = false # false/true @@ -130,10 +130,10 @@ indent_func_def_param = true # false/true indent_func_proto_param = true # false/true # Same as indent_func_call_param, but for class declarations -indent_func_class_param = false # false/true +indent_func_class_param = true # false/true # Same as indent_func_call_param, but for class variable constructors -indent_func_ctor_var_param = false # false/true +indent_func_ctor_var_param = true # false/true # Same as indent_func_call_param, but for templates indent_template_param = false # false/true @@ -331,22 +331,22 @@ sp_before_template_paren = ignore # ignore/add/remove/force # Add or remove space in 'template <' vs 'template<'. # If set to ignore, sp_before_angle is used. -sp_template_angle = ignore # ignore/add/remove/force +sp_template_angle = add # ignore/add/remove/force # Add or remove space before '<>' -sp_before_angle = ignore # ignore/add/remove/force +sp_before_angle = remove # ignore/add/remove/force # Add or remove space inside '<' and '>' -sp_inside_angle = ignore # ignore/add/remove/force +sp_inside_angle = remove # ignore/add/remove/force # Add or remove space after '<>' -sp_after_angle = ignore # ignore/add/remove/force +sp_after_angle = add # ignore/add/remove/force # Add or remove space between '<>' and '(' as found in 'new List<byte>();' -sp_angle_paren = ignore # ignore/add/remove/force +sp_angle_paren = remove # ignore/add/remove/force # Add or remove space between '<>' and a word as in 'List<byte> m;' -sp_angle_word = ignore # ignore/add/remove/force +sp_angle_word = add # ignore/add/remove/force # Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add sp_angle_shift = add # ignore/add/remove/force @@ -431,10 +431,10 @@ sp_before_class_colon = add # ignore/add/remove/force sp_before_case_colon = remove # ignore/add/remove/force # Add or remove space between 'operator' and operator sign -sp_after_operator = ignore # ignore/add/remove/force +sp_after_operator = remove # ignore/add/remove/force # Add or remove space between the operator symbol and the open paren, as in 'operator ++(' -sp_after_operator_sym = ignore # ignore/add/remove/force +sp_after_operator_sym = add # ignore/add/remove/force # Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a' sp_after_cast = remove # ignore/add/remove/force @@ -503,7 +503,7 @@ sp_func_call_paren_empty = ignore # ignore/add/remove/force sp_func_call_user_paren = ignore # ignore/add/remove/force # Add or remove space between a constructor/destructor and the open paren -sp_func_class_paren = ignore # ignore/add/remove/force +sp_func_class_paren = remove # ignore/add/remove/force # Add or remove space between 'return' and '(' sp_return_paren = add # ignore/add/remove/force @@ -566,10 +566,10 @@ sp_try_brace = ignore # ignore/add/remove/force sp_getset_brace = ignore # ignore/add/remove/force # Add or remove space before the '::' operator -sp_before_dc = ignore # ignore/add/remove/force +sp_before_dc = remove # ignore/add/remove/force # Add or remove space after the '::' operator -sp_after_dc = ignore # ignore/add/remove/force +sp_after_dc = remove # ignore/add/remove/force # Add or remove around the D named array initializer ':' operator sp_d_array_colon = add # ignore/add/remove/force @@ -767,13 +767,13 @@ align_enum_equ_span = 0 # number align_enum_equ_thresh = 0 # number # The span for aligning struct/union (0=don't align) -align_var_struct_span = 0 # number +align_var_struct_span = 8 # number # The threshold for aligning struct/union member definitions (0=no limit) -align_var_struct_thresh = 0 # number +align_var_struct_thresh = 8 # number # The gap for aligning struct/union member definitions -align_var_struct_gap = 0 # number +align_var_struct_gap = 8 # number # The span for aligning struct initializer values (0=don't align) align_struct_init_span = 0 # number @@ -822,7 +822,7 @@ align_func_proto_span = 0 # number align_func_proto_gap = 0 # number # Align function protos on the 'operator' keyword instead of what follows -align_on_operator = false # false/true +align_on_operator = true # false/true # Whether to mix aligning prototype and variable declarations. # If true, align_var_def_XXX options are used instead of align_func_proto_XXX options. @@ -1044,13 +1044,13 @@ nl_case_colon_brace = ignore # ignore/add/remove/force nl_namespace_brace = ignore # ignore/add/remove/force # Add or remove newline between 'template<>' and whatever follows. -nl_template_class = ignore # ignore/add/remove/force +nl_template_class = add # ignore/add/remove/force # Add or remove newline between 'class' and '{' -nl_class_brace = ignore # ignore/add/remove/force +nl_class_brace = remove # ignore/add/remove/force # Add or remove newline after each ',' in the constructor member initialization -nl_class_init_args = ignore # ignore/add/remove/force +nl_class_init_args = remove # ignore/add/remove/force # Add or remove newline between return type and function name in a function definition nl_func_type_name = ignore # ignore/add/remove/force @@ -1147,7 +1147,7 @@ nl_after_vbrace_close = false # false/true # Control the newline between the close brace and 'b' in: ' { int a; } b;' # Affects enums, unions, and structures. If set to ignore, uses nl_after_brace_close -nl_brace_struct_var = ignore # ignore/add/remove/force +nl_brace_struct_var = remove # ignore/add/remove/force # Whether to alter newlines in '#define' macros nl_define_macro = false # false/true @@ -1299,11 +1299,11 @@ nl_after_class = 0 # number # The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # Will not change the newline count if after a brace open. # 0 = No change. -nl_before_access_spec = 0 # number +nl_before_access_spec = 2 # number # The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # 0 = No change. -nl_after_access_spec = 0 # number +nl_after_access_spec = 1 # number # The number of newlines between a function def and the function comment. # 0 = No change.