码迷,mamicode.com
首页 > 其他好文 > 详细

跟我一起写操作系统(四)——获取物理内存

时间:2015-12-20 17:30:48      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

转载注明出处:http://www.cnblogs.com/lucasysfeng/p/4847662.html

上一讲地址:http://www.cnblogs.com/lucasysfeng/p/5036562.html

项目地址:https://github.com/lucasysfeng/lucasOS

 

  我们知道,内存管理是操作系统的重要组成部分,在学习内存管理之前,首先要解决一个问题:如何获取物理内存?在前几讲我们谈到,内核是由GRUB启动的,因此要在内核中获取物理内存时,我们可以通过GRUB获取。

multiboot_t结构体


   GRUB将内存的分布放到了multiboot_t结构体里,关于该结构体的相关信息和字段介绍可以看这里http://www.uruk.org/orig-grub/boot-proposal.html,该结构体如下:

typedef struct multiboot_t
{
	uint32_t flags; 
	uint32_t mem_lower;
	uint32_t mem_upper;
	uint32_t boot_device;  
	uint32_t cmdline;  
	uint32_t mods_count;    
	uint32_t mods_addr;
	uint32_t num;
	uint32_t size;
	uint32_t addr;
	uint32_t shndx;
	uint32_t mmap_length;
	uint32_t mmap_addr;
	uint32_t drives_length; 
	uint32_t drives_addr;  
	uint32_t config_table;    
	uint32_t boot_loader_name; 
	uint32_t apm_table;          
	uint32_t vbe_control_info;
	uint32_t vbe_mode_info;
	uint32_t vbe_mode;
	uint32_t vbe_interface_seg;
	uint32_t vbe_interface_off;
	uint32_t vbe_interface_len;
}__attribute__((packed)) multiboot_t;

  我们没有必要了解每个字段,重点来关注下mmap_addr和mmap_length, mmap_addr是缓冲区的地址,mmap_length是缓冲区的总大小。缓冲区由一个或者多个下面的结构对组成:

typedef struct mmap_entry_t
{
	uint32_t size;  
	uint32_t base_addr_low;
	uint32_t base_addr_high;
	uint32_t length_low;
	uint32_t length_high;
	uint32_t type;
}__attribute__((packed)) mmap_entry_t;

  size是相关结构的大小,单位是字节,它可能大于最小值20. base_addr_low是启动地址的低32位,base_addr_high是高32位,启动地址总共有64位。length_low是内存区域大小的低32位,length_high是内存区域大小的高32位,总共是64位。type是相应地址区间的类型,1代表可用RAM,所有其它的值代表保留区域

 

获取物理内存


  我们在内核代码里打印出地址,如下:

void show_memory_map()
{
	uint32_t mmap_addr = glb_mboot_ptr->mmap_addr;
	uint32_t mmap_length = glb_mboot_ptr->mmap_length;

	mmap_entry_t *mmap = (mmap_entry_t *) mmap_addr;
	for (mmap = (mmap_entry_t *) mmap_addr;
			(uint32_t) mmap < mmap_addr + mmap_length; mmap++)
	{
		print_hex((uint32_t) mmap->base_addr_low);
		print_char(‘\n‘);
	}
}

  

编译和运行


   我们使用qemu启动虚拟机。

$ make

$ make qemu 

  make后会生成kernel内核,并将内核拷贝到lucasOS.img中,运行make qemu就会加载lucasOS.img,并出现下面窗口,表示成功了:

技术分享

代码获取


  本系列GitHub地址 https://github.com/lucasysfeng/lucasOS,本讲的代码是code/chapter4.

 

跟我一起写操作系统(四)——获取物理内存

标签:

原文地址:http://www.cnblogs.com/lucasysfeng/p/5059767.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!