性能优化
你需要通过谷歌预先了解的概念:freestanding, uint32_t, size_t
目标:修复代码中各种各样的问题
OSDev wiki有一节描述了JameM’s教程存在的一些问题。因为我们在18-22节课(interrupts through malloc)是参考他的教程的,我们在继续之前,必须修复这些问题
1.错误标志(Wrong CFLAGS)
当编译.o文件的时候,我们添加了-ffreestanding,这个操作包括kernel_entry.o 从而影响了kernel.bin和os-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_t。size_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.asm的call_isr_handler之前添加cld
最后, cpu/interrupt.asm中一些重要的问题。通用根在堆栈上创建结构寄存器实例,然后调用C处理程序。但是这破坏了ABI,因为堆栈属于被调用的函数,并且可以根据需要修改。需要将其作为指针进行结构传递
为了实现这个,编辑cpu/isr.h和cpu/isr.c, 把registers_t r修改成registers_t *t, 然后使用->访问成员而不是.。最后,在cpu/interrupt.asm中,在调用isr_handler和``irq_handler之前都添加一个push esp。 记住后面也要pop eax`用于清理指针
所有当前回调,定时器和键盘,也要使用指针修改registers_t