[OS64位][020]源码阅读:程序4-7 计算可用的物理内存页数

学习笔记

使用教材(配书源码以及使用方法)
《一个64位操作系统的设计与实现》
http://www.ituring.com.cn/book/2450
https://www.jianshu.com/p/28f9713a9171

源码结构

  • 配书代码包 :第4章 \ 程序 \ 程序4-6
  • 配书代码包 :第4章 \ 程序 \ 程序4-7

运行调试

[anno@localhost bootloader]$ make
nasm boot.asm -o boot.bin
nasm loader.asm -o loader.bin

[anno@localhost kernel]$ make
gcc -E  head.S > head.s
as --64 -o head.o head.s
gcc -E  entry.S > entry.s
as --64 -o entry.o entry.s
gcc  -mcmodel=large -fno-builtin -m64 -c main.c
gcc  -mcmodel=large -fno-builtin -m64 -c printk.c
gcc  -mcmodel=large -fno-builtin -m64 -c trap.c
gcc  -mcmodel=large -fno-builtin -m64 -c memory.c
ld -b elf64-x86-64 -z muldefs -o system head.o entry.o main.o printk.o trap.o memory.o -T Kernel.lds 
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary system kernel.bin

[anno@localhost 4-7]$ ls
bochsrc  boot.img  bootloader  kernel  media

[anno@localhost 4-7]$ sudo mount boot.img media -t vfat -o loop
[anno@localhost 4-7]$ sudo cp bootloader/loader.bin media
[anno@localhost 4-7]$ sync
[anno@localhost 4-7]$ sudo cp bootloader/boot.bin media
[anno@localhost 4-7]$ sync
[anno@localhost 4-7]$ sudo cp kernel/kernel.bin media
[anno@localhost 4-7]$ sync

[anno@localhost 4-7]$ bochs -f ./bochsrc

程序4-6 获得物理内存的信息

  • 每条物理地址空间信息占用 20B

    10191360-819318f314477545.png
    物理地址空间结构体

  • 可用内存Type=0x0000 00019f000h + 7fef0000hB = 7ff8f000h B2047.55 MB2 GB

10191360-4b8e5926f42ab26a.png
程序4-6 获得物理内存信息 可用内存(9f000h + 7fef0000h)B = 7ff8f000h B ≈ 2047.55 MB约2 GB

10191360-0d59f9dfc410d3a8.png
bochsrc 配置文件设置的虚拟机内存为 2GB

程序4-7 计算可用的物理内存页数

  • 物理页大小为2MB,可用的物理页个数为1022(十进制)
10191360-1e5e348a48522bac.png
程序4-7 计算可用的物理内存页数

10191360-11a7afc9f8c9a382.png
程序4-7 结构体 extern struct Global_Memory_Descriptor memory_management_struct.png
  • 程序4-7 对e820结构体数组中的可用物理内存段进行2MB物理页边界对齐
10191360-11a03292613bf216.png
程序4-7 对e820结构体数组中的可用物理内存段进行2MB物理页边界对齐.png
  • 对齐的效果
#include <stdio.h>

#define PAGE_2M_SHIFT   21
#define PAGE_4K_SHIFT   12

#define PAGE_2M_SIZE    (1UL << PAGE_2M_SHIFT)
#define PAGE_4K_SIZE    (1UL << PAGE_4K_SHIFT)

#define PAGE_2M_MASK    (~ (PAGE_2M_SIZE - 1))
#define PAGE_4K_MASK    (~ (PAGE_4K_SIZE - 1))

#define PAGE_2M_ALIGN(addr) (((unsigned long)(addr) + PAGE_2M_SIZE - 1) & PAGE_2M_MASK)
#define PAGE_4K_ALIGN(addr) (((unsigned long)(addr) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)

int main()
{
    printf("unsigned long : %d byte\n", sizeof(unsigned long));
    unsigned long add___ = 0x10AB;
    
    unsigned long add_4K = PAGE_4K_ALIGN(add___);
    printf("add___:%lx\n", add___); 
    printf("add_4K:%lx\n", add_4K); 
    
    
    unsigned long add_2M = PAGE_2M_ALIGN(add___);
    printf("add___:%lx\n", add___); 
    printf("add_2M:%lx\n", add_2M); 
    
    return 0;
}

C语言在线编译器 compile_c_online

10191360-2d4841816035dcdb.PNG
对齐的效果.PNG

参考资料

  • INT 15h AX=e820h 保存物理地址空间信息到内存物理地址0x7E00h

[OS64位][014]源码阅读:代码清单3-18 ~ 3-22 将内核kernel.bin读至内存0x100000
https://www.jianshu.com/p/e9ed9f10bad6

猜你喜欢

转载自blog.csdn.net/weixin_33674437/article/details/90968827