跳至主要内容

muxOS 开发日志(二)—— PMM、VMM 和键盘驱动

PMM

1.1 什么是PMM?

PMM(Physical Memory Manager)是操作系统内核中负责对物理内存进行页级管理的子系统,通过维护内存分配状态(如位图、链表等),为内核及其他子系统提供物理页的分配与回收能力,是虚拟内存管理(VMM)的基础。

1.2 介绍

muxOS 首先从multiboot获取内存信息,然后从物理内存起始分配页(4kb/页),大约在512页处分配第一页,取决于 _kernel_end 的位置。PMM内部由bitmap单元管理(8页/bitmap),同时,1MB到_kernel_end前的bitmap标记占用。

例如

  • bitmap 0x00000001 -> 表示bitmap单元第一个bit被分配

  • 第一次调用 pmm_alloc() 返回 _kernel_end 之后第一个空闲页的物理地址

muxOS 提供一些基础函数用来操作 PMM

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef PMM_H
#define PMM_H
#include "kernel.h"
#include <stdint.h>
#define PAGE_SIZE 4096
#define MAX_PAGES 1048576  /* 1M 页 × 4KB = 4GB */
void pmm_init(multiboot_info_t *mbi);
uint32_t pmm_alloc();
void pmm_free(uint32_t addr);
void pmm_mark_used(uint32_t start, uint32_t length);
void pmm_mark_free(uint32_t start, uint32_t length);
#endif

关于 PMM 的介绍,请参考 内存分配 - OSDev 维基

VMM

2.1 什么是VMM?

是操作系统中负责 虚拟地址到物理地址转换 的核心模块

VMM(Virtual Memory Manager,虚拟内存管理器) 是操作系统中负责:

管理虚拟地址空间,并实现虚拟地址到物理地址映射的核心模块。

2.2 介绍

muxOS 当 VMM 初始化时,虚拟地址 0x00000000–0x00FFFFFF(前 16MB)对应的页表项标志为 PAGE_PRESENT | PAGE_WRITE(值后缀 0x3),不含 PAGE_USER,用户态(ring 3)访问会触发 #PF。通过 pd_idx < 4 的判断,告诉虚拟地址 0x01000000 起始,含 PAGE_USER(值后缀 0x7),用户进程可访问。

关于 VMM 的介绍,请参考 内存分配 - OSDev 维基

键盘驱动

3.1  介绍

muxOS 键盘驱动通过 IRQ1(中断向量 0x21)处理键盘输入。pic_init() 已解除 IRQ1 屏蔽(outb(0x21, 0xFD)),每次按键时 CPU 跳转到 irq1_handler。中断处理流程:

  1. 从端口 0x60 读取扫描码(scan code)

  2. 若扫描码为 0x2A(左 Shift)或 0x36(右 Shift),设置 shift_pressed = 1;若为 0xAA 或 0xB6(释放 Shift),清零

  3. 根据 shift_pressed 选择 shift_map 或 scancode_map,将扫描码转换为 ASCII 字符

  4. 调用 kb_buf_push(c) 将字符推入环形缓冲区

  5. 发送 EOI(outb(0x20, 0x20))通知 PIC 中断处理完毕 muxOS

muxOS提供一些基础函数操作键盘缓冲区

1
2
3
// keyboard.h
void kb_buf_push(char c);
char kb_getchar();

关于键盘驱动的介绍,请参考 键盘 - OSDev 维基

关于本文

由 Latos 撰写,采用 CC BY-NC 4.0 许可协议。

#OS #muxOS #C