• 【实现】物理内存探测

    【实现】物理内存探测

    物理内存探测是在bootasm.S中实现的,相关代码很短,如下所示:

    1. probe_memory:
    2. //对0x8000处的32位单元清零,即给位于0x8000处的
    3. //struct e820map的结构域nr_map清零
    4. movl $0, 0x8000
    5. xorl %ebx, %ebx
    6. //表示设置调用INT 15h BIOS中断后,BIOS返回的映射地址描述符的起始地址
    7. movw $0x8004, %di
    8. start_probe:
    9. movl $0xE820, %eax // INT 15的中断调用参数
    10. //设置地址范围描述符的大小为20字节,其大小等于struct e820map的结构域map的大小
    11. movl $20, %ecx
    12. //设置edx为534D4150h (即4个ASCII字符“SMAP”),这是一个约定
    13. movl $SMAP, %edx
    14. //调用int 0x15中断,要求BIOS返回一个用地址范围描述符表示的内存段信息
    15. int $0x15
    16. //如果eflags的CF位为0,则表示还有内存段需要探测
    17. jnc cont
    18. //探测有问题,结束探测
    19. movw $12345, 0x8000
    20. jmp finish_probe
    21. cont:
    22. //设置下一个BIOS返回的映射地址描述符的起始地址
    23. addw $20, %di
    24. //递增struct e820map的结构域nr_map
    25. incl 0x8000
    26. //如果INT0x15返回的ebx为零,表示探测结束,否则继续探测
    27. cmpl $0, %ebx
    28. jnz start_probe
    29. finish_probe:

    上述代码正常执行完毕后,在0x8000地址处保存了从BIOS中获得的内存分布信息,此信息按照struct e820map的设置来进行填充。这部分信息将在bootloader启动ucore后,由ucore的page_init函数来根据struct e820map的memmap(定义了起始地址为0x8000)来完成对整个机器中的物理内存的总体管理。