物理内存管理 - 练习题

练习 1:内存使用统计

实现一个函数打印详细的内存使用报告:

void pmm_dump_stats(void) {
    // 打印: 总内存、已用内存、空闲内存、使用百分比
    // 打印: 第一个空闲帧地址、最后一个空闲帧地址
}

练习 2:连续帧分配

有时需要分配多个连续的物理页帧(例如DMA缓冲区)。实现:

uint32_t pmm_alloc_frames(uint32_t count);
void pmm_free_frames(uint32_t phys_addr, uint32_t count);

提示:需要在位图中查找连续count个空闲位。

练习 3:BIOS内存检测

修改bootloader,在实模式下使用INT 0x15, AX=0xE820获取内存映射,然后传递给内核。

; 在boot.asm中,进入保护模式前调用
detect_memory:
    mov di, 0x8000      ; 结果存放位置
    xor ebx, ebx        ; 续传标记
    mov edx, 0x534D4150  ; "SMAP"签名
.loop:
    mov eax, 0xE820
    mov ecx, 24          ; 每条记录大小
    int 0x15
    ; ...处理结果...

练习 4:实现简单的kfree

为bump allocator添加一个简单的释放机制(使用空闲链表):

struct free_block {
    uint32_t size;
    struct free_block *next;
};
 
void kfree(void *ptr);

思考题

  1. 位图分配器分配一个帧的时间复杂度是多少?有什么优化方法?
  2. 为什么不能直接用malloc/free?freestanding环境有什么限制?
  3. 如果物理内存有空洞(不连续),位图分配器如何处理?