ucore-project5: mm(4)

时隔近20天,终于搞定了一个问题。使用linker script设置内核起始地址为0xC0000000后,在没有启用分页的情况下,终于让加载到0x100000的内核成功运行起来了。内核代码正常运行,时钟中断正常。

 

ucore lab2 project5中首先设置了一个临时gdt,将base地址设置为-0xC0000000,这样在后续所有地址访问中,地址都会与这个base地址相加,相当于减去了0xC0000000,应该可以正常运行。

 

开始时qemu虚拟机直接宕掉,原因是把DS、ES、FS、GS、CS的内容都改了,忘了改SS,而ESP的值设置了一个0xC0xxxxxx的值,从而执行出错。

 

将SS也改为用新段地址后,虚拟机的确是正常运行了,不过一运行cpu就不断重启。为此使用gdb调试跟踪。调试过程中发现gdb处理这种情况会有些问题:段基地址不再是0了,也就意味着EIP中的地址不再是下一条指令的物理地址了。此时看后续汇编指令必须用如下gdb命令看:

x/10i $pc - 0xC0000000

 

另外,断点仍然有用,但断点停下来后,continue命令就再也不起作用了,怀疑continue时gdb没有正确把trap指令去掉。而nexti指令的效果也变得和stepi一样,对于call指令总会跳进去。

 

不过除了这些问题,gdb仍然不可或缺,通过gdb仍然发现了问题的出处:初始化内存时出错。

 

初始化内存时重新设置gdt,然后重新更新了各个段寄存器。把段寄存器的基址改为-0xC0000000,cpu仍然重启。调试时发现gdt中加载出来的数据可能是错的,记起来lgdt命令中,gdt的基址指针是一个线性指针,而非逻辑指针。这就意味着gdt的基址指针不会进行段运算,所以gdt基址指针应该减去0xC0000000。

 

减去后,终于成功初始化内存了,但sti恢复中断后,又开始不断出错。不恢复中断时都是好的,说明中断执行出错了。想了好几天,才想起lidt命令中,idt的基址指令也是线性地址。将idt基址指针减去0xC0000000后,终于一切ok了。

 

接下来就是内存分页处理了。

你可能感兴趣的:(project)