bookstack

性能优化

你需要通过谷歌预先了解的概念:freestanding, uint32_t, size_t

目标:修复代码中各种各样的问题

OSDev wiki有一节描述了JameM’s教程存在的一些问题。因为我们在18-22节课(interrupts through malloc)是参考他的教程的,我们在继续之前,必须修复这些问题

1.错误标志(Wrong CFLAGS)

当编译.o文件的时候,我们添加了-ffreestanding,这个操作包括kernel_entry.o 从而影响了kernel.binos-image.bin

之前,我们通过使用-nostdlib禁用了libgcc(不是libc),我们在链接的时候,没有重新启用它。由于这个很棘手,我们将删除-nostdlib

-nostdinc也会传递给gcc,但是我们在第三步需要,所以现在就先删掉它

2.内核main函数(kernel.c main() function)

修改kernel/kernel.c,把main()改成kernel_main()。因为gcc把”main”当作一个特殊的关键字,我们不想弄混

修改boot/kernel_entry.asm直接指向新的名称

为了修复i386-elf-ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000 告警信息,添加一个global_start;, 然后在boot/kernel_entry.asm定义一个label_start:

3.重构数据类型(Reinvented datatypes)

定义非标准数据类型比如u32是一个糟糕的主意,从C99开始,引入了一个标准修复长度数据类型如uint32_t

我们需要包含<stdint.h>,它甚至可以在-ffreestanding(但是需要stdlibs)工作,使用这些数据类型,而不是自定义的,删掉type.h里面的自定义的数据类型

删除__asm____volatile__旁边的下划线,因为他们不需要了

4.不合适对齐kmalloc(Improperly aligned kmalloc)

首先,因为kmalloc使用一个长度参数,我们将使用正确的数据类型size_t而不是u32int_tsize_t应该被用来计算物品个数的所有参数,并且是非负数。包含在<stddef.h>

我们后面会修复kmalloc,让它作为一个合适的内存管理单元和对齐的数据类型。但是现在,它总是返回一个新的页对齐内存块

5.缺失的函数(Missing functions)

我们在接下来的课程中,实现缺失的mem*函数

6.中断处理(Interrupt handlers)

cli是多余的,因为我们已经建立了IDT入口,在处理程序中使用idt_gate_t标志,就可以启用中断

sti也是多余的,当iret从栈中加载标志位的时候,里面有个标志位可以知道是否启用了中断。换句话说,在中断之前,中断处理程序自动保存中断是否启用

cpu/isr.h中,struct registers_t有一些问题。首先,esp被重命名为了useless。这个值是有用的,因为它必须处理当前栈的上下文信息,而不是被中断。然而把useresp重命名为esp

osdev wiki建议在cpu/interrupt.asmcall_isr_handler之前添加cld

最后, cpu/interrupt.asm中一些重要的问题。通用根在堆栈上创建结构寄存器实例,然后调用C处理程序。但是这破坏了ABI,因为堆栈属于被调用的函数,并且可以根据需要修改。需要将其作为指针进行结构传递

为了实现这个,编辑cpu/isr.hcpu/isr.c, 把registers_t r修改成registers_t *t, 然后使用->访问成员而不是.。最后,在cpu/interrupt.asm中,在调用isr_handler和`irq_handler之前都添加一个push esp。 记住后面也要pop eax用于清理指针

所有当前回调,定时器和键盘,也要使用指针修改registers_t