深圳,深圳

我还依稀记得在高考填报志愿的时候,我和我的父亲正在讨论去哪个地方的学校,当时正在考虑上海,我的父亲说了这么一段话:

“上海不行,上海压力太大了,到处都是高楼,抬头都望不见天的,很压抑。”

“抬头望不见天”是一个压力具象化的极其震撼的描绘,但高三刚毕业的我显然对这个描绘理解不够,但填报志愿还是避开了上海的高校,留在了武汉。现在三年过去了,我来到了深圳,打了第一份工,我才能真实地理解“抬头望不见天”,对于上班族而言是何等的绝望。

Read more

ucore lab 2

物理内存管理

基本流程

为了完成物理内存管理,首先要探测可用的物理内存资源,了解物理内存位于什么地方,有多大,再以固定页面大小划分整个物理内存空间,准备以此为最小内存分配单位来管理整个物理内存,设置其可用状态为free,used,reserved。再建立页表,启动分页机制,让MMU将预先建好的页表项读到TLB中,根据页表项描述的虚拟页和物理页的对应关系完成CPU对内存的读写执行操作。

在实验中主要关注pmm_init函数,完成的工作包括:

  1. 初始化物理内存页管理器框架pmm_manager
  2. 建立空闲的page链表,分配以4KB为单位的空闲内存
  3. 检查物理内存页分配算法
  4. 为确保切换到分页机制后可执行,建立临时二级页表
  5. 建立一一映射关系的二级页表
  6. 开启分页机制
  7. 重新设置全局段描述符表
  8. 取消临时二级页表
  9. 检查页表建立是否正确
  10. 通过自映射机制完成页表打印输出(扩展内容)

探测系统物理内存布局

获取内存大小方法由BIOS中断调用和直接探测两种。BIOS中断调用一般只能在实模式下完成,直接探测方法必须在保护模式下完成。终端获取内存布局有三种方法,基于INT 15h中断,分别为88h,e801h和e820h,并非所有情况三种都生效,在linux中是依次尝试三种方法。在本实验中采用e820h来实现。因为在实模式下,因此写在了bootloader中,调用该中断,将映射结构保存在0x8000处。

INT 15h能完成一系列功能,这里调用参数为e820h的INT 15h BIOS中断,获取内存映射地址描述符。

INT 15h中断这里的调用参数如下

1
2
3
4
5
eax: e820h
edx: 534D4150h (即4个ASCII字符“SMAP”) 一个签名
ebx: 如果第一次调用或者内存区域扫描完毕,则为0,否则存放上次调用之后的计数值
ecx: 保存地址范围描述符的内存大小,应该大于等于20字节
es:di:指向保存地址范围描述符结构的缓冲区,BIOS把信息写入这个结构的起始地址

返回值如下:

1
2
3
4
5
6
eflags CF位:中断执行成功则不置位,否则置位
eax:'SMAP'
es:di: 指向保存地址范围描述符的缓冲区,数据由BIOS填写完毕
ebx:下一个地址范围描述符的计数地址
ecx:地址范围描述符的字节大小
ah: 失败时候保存出错代码

我们便可以通过此中断调用,递增di的值(20的倍数),从而找到内存布局的entry,放到保存地址范围描述副结构的缓冲区中,便于后续ucore管理。该缓冲区结构体定义如下:

1
2
3
4
5
6
7
8
struct e820map {
int nr_map;
struct {
uint64_t addr;
uint64_t size;
uint32_t type;
} __attribute__((packed)) map[E820MAX];
};

接下来我们来观察在bootloader中的汇编码实现探测内存,汇编代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
probe_memory:
movl $0, 0x8000 # 置0
xorl %ebx, %ebx # 置0
movw $0x8004, %di # 设置起始地址
start_probe:
movl $0xE820, %eax # 设置参数
movl $20, %ecx # 设置长度20字节
movl $SMAP, %edx # 签名
int $0x15 # 调用中断
jnc cont # 没有问题则跳转,出现问题则finish
movw $12345, 0x8000
jmp finish_probe
cont:
addw $20, %di # 设置下一个起始地址
incl 0x8000 #递增结构体成员变量nr_map
cmpl $0, %ebx # 如果为0则探测结束,否则继续
jnz start_probe
finish_probe:

以页为单位管理物理内存

获得可用内存范围后,需要建立想对应数据结构来完成管理操作,4KB对齐。这里每个物理页采用Page的数据结构来实现,Page设计需要尽量小

练习

准备

练习1 实现first-fit连续物理内存分配算法(需要编程)

练习2 实现寻找虚拟地址对应的页表项(需要编程)

练习3 释放某虚拟地址所在页并取消对应二级页表项的映射(需要编程)

扩展练习 伙伴系统分配算法

扩展练习 任意大小内存单元slub分配算法

Hackthon实战 ——经验与教训

当对自己的真实实力没有真正的认识,期望便成为了负担。本文是一篇随笔,记录与总结我个人在第一次参加hackthon之后的经验与教训。

Read more

uCore lab 1

本系列旨在完成uCore实验,通过实验了解操作系统的概念,从汇编,c语言编程的角度,以微观的视角了解操作系统的运行过程。
本文为本系列第一篇,介绍机器启动到启动os的过程。

Read more
Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×