build/
playground/
.vscode/settings.json
+.VSCodeCounter/
\ No newline at end of file
/*
_hhk_init用来初始化我们高半核:
- 1. 设置GDT表
- 2. 设置IDT表(暂时,以后会拿到 kernel_init 里面)
- 3. 初始化最简单的PTD与PT(重新映射我们的内核至3GiB处,以及对相应的地方进行Identity Map)
+ 1. 初始化最简单的PD与PT(重新映射我们的内核至3GiB处,以及对相应的地方进行Identity Map)
*/
movl $(KPG_SIZE), 4(%esp)
movl $mb_info, (%esp)
call _kernel_init
+ /*
+ 加载新的栈指针,位于0xffbfffff,但因为16字节对齐的需求,低四位清零。
+ 为什么不是0xffffffff? 因为0xffc00000 - 0xffffffff 这4MiB的空间用于
+ 对页表与页目录的循环映射。
+ */
+ mov $0xffbffff0, %esp
+
+ call _kernel_post_init
+
+ subl $6, %esp
+
# 加载 IDT
movl $_idt, 2(%esp)
movw _idt_limit, %ax
movw %ax, (%esp)
lidt (%esp)
- /*
- 加载新的栈指针,位于0xffbfffff,但因为16字节对齐的需求,低四位清零。
- 为什么不是0xffffffff? 因为0xffc00000 - 0xffffffff 这4MiB的空间用于
- 对页表与页目录的循环映射。
- */
- mov $0xffbffff0, %esp
+ addl $6, %esp
/* 进入内核 */
call _kernel_main
// ( ) + 映射 memory map (APCI,APIC,IO映射) (以后)
// (v) + 释放 hhk_init 所占据的空间
+#pragma region INIT_MM
// 初始化物理内存管理器
pmm_init(MEM_1MB + mb_info->mem_upper << 10);
vmm_init();
- tty_init(VGA_BUFFER_PADDR);
+#pragma endregion
+ // 初始化VGA
+ tty_init(VGA_BUFFER_PADDR);
tty_set_theme(VGA_COLOR_GREEN, VGA_COLOR_BLACK);
- printf("[KERNEL] Initializing Memory ...\n");
+ printf("[KERNEL] === Initialization === \n");
unsigned int map_size =
mb_info->mmap_length / sizeof(multiboot_memory_map_t);
printf("[MM] Mem: %d KiB, Extended Mem: %d KiB\n",
mb_info->mem_lower,
mb_info->mem_upper);
+#pragma region MMAP_SCAN_RESERVING_KERNEL_PGS
// 按照 Memory map 标识可用的物理页
for (unsigned int i = 0; i < map_size; i++) {
multiboot_memory_map_t mmap = map[i];
size_t pg_count = (uintptr_t)(&__kernel_end - &__kernel_start) >> 12;
pmm_mark_chunk_occupied(V2P(&__kernel_start) >> 12, pg_count);
printf("[MM] Allocated %d pages for kernel.\n", pg_count);
-
-
- size_t hhk_init_pg_count = ((uintptr_t)(&__init_hhk_end)) >> 12;
- printf("[MM] Releaseing %d pages from 0x0.\n", hhk_init_pg_count);
-
- // 清除 hhk_init 与前1MiB的映射
- // 从这里开始,到新的vga缓存地址设置前,不能够进行任何的打印操作
- for (size_t i = 0; i < hhk_init_pg_count; i++) {
- vmm_unmap_page((i << 12));
- }
-
+#pragma endregion
+
size_t vga_buf_pgs = VGA_BUFFER_SIZE >> 12;
// 首先,标记VGA部分为已占用
}
printf("[MM] Allocated %d pages for stack start at %p\n", K_STACK_SIZE>>12, K_STACK_START);
- printf("[KERNEL] Done!\n\n");
+ printf("[KERNEL] === Initialization Done === \n\n");
+}
+
+void
+_kernel_post_init() {
+ printf("[KERNEL] === Post Initialization === \n");
+ size_t hhk_init_pg_count = ((uintptr_t)(&__init_hhk_end)) >> 12;
+ printf("[MM] Releaseing %d pages from 0x0.\n", hhk_init_pg_count);
+
+ // 清除 hhk_init 与前1MiB的映射
+ for (size_t i = 0; i < hhk_init_pg_count; i++) {
+ vmm_unmap_page((i << 12));
+ }
+ printf("[KERNEL] === Post Initialization Done === \n\n");
}
void
uintptr_t max_pg;
+// ... |xxxx xxxx |
+// ... |-->|
void
pmm_mark_page_free(uintptr_t ppn)
{
void
pmm_init(uintptr_t mem_upper_lim)
{
- max_pg = (PG_ALIGN(mem_upper_lim) >> 12) + 1;
+ max_pg = (PG_ALIGN(mem_upper_lim) >> 12);
pg_lookup_ptr = LOOKUP_START;
uintptr_t pd_offset = PD_INDEX(va);
uintptr_t pt_offset = PT_INDEX(va);
- ptd_t* ptd = PTD_BASE_VADDR;
+ ptd_t* ptd = (ptd_t*)PTD_BASE_VADDR;
// 在页表与页目录中找到一个可用的空位进行映射(位于va或其附近)
ptd_t* pde = ptd[pd_offset];
- pt_t* pt = (uintptr_t)(PT_BASE_VADDR | (pd_offset << 12));
+ pt_t* pt = (uintptr_t)PT_VADDR(pd_offset);
while (pde && pd_offset < 1024) {
if (pt_offset == 1024) {
pd_offset++;
}
ptd[pd_offset] = PDE(dattr, new_pt_pa);
- memset((void*)PT_VADDR(pd_offset), 0, PM_PAGE_SIZE);
+ memset((void*)PT_VADDR(pd_offset), 0, PM_PAGE_SIZE);
pt[pt_offset] = PTE(tattr, pa);
return V_ADDR(pd_offset, pt_offset, PG_OFFSET(va));
tty_scroll_up()
{
size_t last_line = TTY_WIDTH * (TTY_HEIGHT - 1);
- memcpy(tty_vga_buffer, tty_vga_buffer + TTY_WIDTH, last_line);
+ memcpy(tty_vga_buffer, tty_vga_buffer + TTY_WIDTH, last_line * 2);
for (size_t i = 0; i < TTY_WIDTH; i++) {
*(tty_vga_buffer + i + last_line) = tty_theme_color;
}
- tty_y = tty_y == 0 ? 0 : tty_y - 1;
+ tty_y = tty_y == 0 ? 0 : TTY_HEIGHT - 1;
}
void
ENTRY(start_)
/*
- FUTURE: Use dynamic linker to separate kernel and boot code
+ FUTURE: Use disk reader
A bit of messy here.
We will pull our higher half kernel out of this shit
- and load it separately once we have our dynamic linker ready.
+ and load it separately once we have our disk reader.
*/
SECTIONS {
.hhk_init_rodata BLOCK(4K) : {
build/obj/arch/x86/*.o (.rodata)
}
- __init_hhk_end = .;
+ __init_hhk_end = ALIGN(4K);
/* Relocation of our higher half kernel */
. += 0xC0000000;
.text BLOCK(4K) : AT ( ADDR(.text) - 0xC0000000 ) {
__kernel_start = .;
build/obj/kernel/*.o (.text)
+ build/obj/hal/*.o (.text)
}
.bss BLOCK(4K) : AT ( ADDR(.bss) - 0xC0000000 ) {
build/obj/kernel/*.o (.bss)
+ build/obj/hal/*.o (.bss)
}
.data BLOCK(4k) : AT ( ADDR(.data) - 0xC0000000 ) {
build/obj/kernel/*.o (.data)
+ build/obj/hal/*.o (.data)
}
.rodata BLOCK(4K) : AT ( ADDR(.rodata) - 0xC0000000 ) {
build/obj/kernel/*.o (.rodata)
+ build/obj/hal/*.o (.rodata)
}
.kpg BLOCK(4K) : AT ( ADDR(.kpg) - 0xC0000000 ) {
build/obj/arch/x86/*.o (.kpg)
}
- __kernel_end = ALIGN(.);
- __heap_start = ALIGN(.); /* 内核结束的地方即堆开始的地方 */
+ __kernel_end = ALIGN(4K);
+ __heap_start = ALIGN(4K); /* 内核结束的地方即堆开始的地方 */
}
\ No newline at end of file