kbd&mou.zip
大小:90.68KB
价格:14积分
下载量:0
评分:
5.0
上传者:weixin_74417251
更新日期:2025-09-22

《操作系统真象还原》第9~10章+鼠标驱动源代码

资源文件列表(大概)

文件名
大小
kbd&mou/boot/
-
kbd&mou/boot/include/
-
kbd&mou/boot/include/boot.inc
2.12KB
kbd&mou/boot/loader.bin
1.37KB
kbd&mou/boot/loader.S
15.75KB
kbd&mou/boot/mbr.bin
512B
kbd&mou/boot/mbr.S
3.48KB
kbd&mou/build/
-
kbd&mou/build/bitmap.o
2.3KB
kbd&mou/build/console.o
2.27KB
kbd&mou/build/debug.o
1.67KB
kbd&mou/build/init.o
1.48KB
kbd&mou/build/interrupt.o
5.01KB
kbd&mou/build/ioqueue.o
3.62KB
kbd&mou/build/kernel.bin
31.55KB
kbd&mou/build/kernel.map
25.39KB
kbd&mou/build/kernel.o
4.27KB
kbd&mou/build/keyboard.o
3.09KB
kbd&mou/build/list.o
2.71KB
kbd&mou/build/main.o
1.99KB
kbd&mou/build/memory.o
4.71KB
kbd&mou/build/mouse.o
4.12KB
kbd&mou/build/print.o
1.83KB
kbd&mou/build/string.o
3.81KB
kbd&mou/build/switch.o
448B
kbd&mou/build/sync.o
3.76KB
kbd&mou/build/thread.o
6.03KB
kbd&mou/build/timer.o
2.41KB
kbd&mou/device/
-
kbd&mou/device/console.c
800B
kbd&mou/device/console.h
275B
kbd&mou/device/ioqueue.c
2.56KB
kbd&mou/device/ioqueue.h
947B
kbd&mou/device/keyboard.c
7.87KB
kbd&mou/device/keyboard.h
122B
kbd&mou/device/mouse.c
3.64KB
kbd&mou/device/mouse.h
82B
kbd&mou/device/timer.c
1.97KB
kbd&mou/device/timer.h
98B
kbd&mou/kernel/
-
kbd&mou/kernel/debug.c
633B
kbd&mou/kernel/debug.h
903B
kbd&mou/kernel/global.h
942B
kbd&mou/kernel/init.c
591B
kbd&mou/kernel/init.h
76B
kbd&mou/kernel/interrupt.c
7.61KB
kbd&mou/kernel/interrupt.h
586B
kbd&mou/kernel/kernel.S
2.76KB
kbd&mou/kernel/main.c
1.03KB
kbd&mou/kernel/memory.c
10.32KB
kbd&mou/kernel/memory.h
1.07KB
kbd&mou/lib/
-
kbd&mou/lib/kernel/
-
kbd&mou/lib/kernel/bitmap.c
2.85KB
kbd&mou/lib/kernel/bitmap.h
525B
kbd&mou/lib/kernel/io.h
2.15KB
kbd&mou/lib/kernel/list.c
3.19KB
kbd&mou/lib/kernel/list.h
1.45KB
kbd&mou/lib/kernel/print.h
238B
kbd&mou/lib/kernel/print.S
8.48KB
kbd&mou/lib/stdint.h
322B
kbd&mou/lib/string.c
3.27KB
kbd&mou/lib/string.h
571B
kbd&mou/lib/user/
-
kbd&mou/makefile
4.34KB
kbd&mou/thread/
-
kbd&mou/thread/switch.S
982B
kbd&mou/thread/sync.c
2.75KB
kbd&mou/thread/sync.h
692B
kbd&mou/thread/thread.c
6.33KB
kbd&mou/thread/thread.h
3.4KB

资源内容介绍

和《操作系统真象还原》第9~10章+鼠标驱动的报告配套
#include "memory.h"#include "bitmap.h"#include "stdint.h"#include "global.h"#include "debug.h"#include "print.h"#include "string.h"#define PG_SIZE 4096/*************** 位图地址 ******************** * 因为0xc009f000是内核主线程栈顶,0xc009e000是内核主线程的pcb. * 一个页框大小的位图可表示128M内存, 位图位置安排在地址0xc009a000, * 这样本系统最大支持4个页框的位图,即512M */#define MEM_BITMAP_BASE 0xc009a000/*************************************/#define PDE_IDX(addr) ((addr & 0xffc00000) >> 22)#define PTE_IDX(addr) ((addr & 0x003ff000) >> 12)#define K_HEAP_START 0xc0100000struct pool { struct bitmap pool_bitmap; // 本内存池用到的位图结构,用于管理物理内存 uint32_t phy_addr_start; // 本内存池所管理物理内存的起始地址 uint32_t pool_size; // 本内存池字节容量};struct pool kernel_pool, user_pool; // 生成内核内存池和用户内存池struct virtual_addr kernel_vaddr; // 此结构是用来给内核分配虚拟地址/* 在pf表示的虚拟内存池中申请pg_cnt个虚拟页, * 成功则返回虚拟页的起始地址, 失败则返回NULL */static void* vaddr_get(enum pool_flags pf, uint32_t pg_cnt) { int vaddr_start = 0, bit_idx_start = -1; uint32_t cnt = 0; if (pf == PF_KERNEL) { bit_idx_start = bitmap_scan(&kernel_vaddr.vaddr_bitmap, pg_cnt); if (bit_idx_start == -1) { return NULL; } while(cnt < pg_cnt) { bitmap_set(&kernel_vaddr.vaddr_bitmap, bit_idx_start + cnt++, 1); } vaddr_start = kernel_vaddr.vaddr_start + bit_idx_start * PG_SIZE; } else { // 用户内存池,将来实现用户进程再补充 } return (void*)vaddr_start;}uint32_t* pte_ptr(uint32_t vaddr) { /* 先访问到页表自己 + \ * 再用页目录项pde(页目录内页表的索引)做为pte的索引访问到页表 + \ * 再用pte的索引做为页内偏移*/ uint32_t* pte = (uint32_t*)(0xffc00000 + \ ((vaddr & 0xffc00000) >> 10) + \ PTE_IDX(vaddr) * 4); return pte;}uint32_t* pde_ptr(uint32_t vaddr) { uint32_t* pde = (uint32_t*)((0xfffff000) + PDE_IDX(vaddr) * 4); return pde;}/* 在m_pool指向的物理内存池中分配1个物理页, * 成功则返回页框的物理地址,失败则返回NULL */static void* palloc(struct pool* m_pool) { int bit_idx = bitmap_scan(&m_pool->pool_bitmap, 1); // 找一个物理页面 if (bit_idx == -1 ) { return NULL; } bitmap_set(&m_pool->pool_bitmap, bit_idx, 1);// 将此位bit_idx置1 uint32_t page_phyaddr = ((bit_idx * PG_SIZE) + m_pool->phy_addr_start); return (void*)page_phyaddr;}static void page_table_add(void* _vaddr, void* _page_phyaddr) { uint32_t vaddr = (uint32_t)_vaddr, page_phyaddr = (uint32_t)_page_phyaddr; uint32_t* pde = pde_ptr(vaddr); uint32_t* pte = pte_ptr(vaddr);/************************ 注意 ************************* * 执行*pte,会访问到空的pde。所以确保pde创建完成后才能执行*pte, * 否则会引发page_fault。因此在*pde为0时,*pte只能出现在下面else语句块中的*pde后面。 * *********************************************************/ if (*pde & 0x00000001) { // 页目录项和页表项的第0位为P,此处判断目录项是否存在 ASSERT(!(*pte & 0x00000001)); if (!(*pte & 0x00000001)) { // 只要是创建页表,pte就应该不存在,多判断一下放心 *pte = (page_phyaddr | PG_US_U | PG_RW_W | PG_P_1); // US=1,RW=1,P=1 } else { //应该不会执行到这,因为上面的ASSERT会先执行。 PANIC("pte repeat"); *pte = (page_phyaddr | PG_US_U | PG_RW_W | PG_P_1); // US=1,RW=1,P=1 } } else { // 页目录项不存在,所以要先创建页目录再创建页表项. uint32_t pde_phyaddr = (uint32_t)palloc(&kernel_pool); *pde = (pde_phyaddr | PG_US_U | PG_RW_W | PG_P_1); /* 分配到的物理页地址pde_phyaddr对应的物理内存清0, * 避免里面的陈旧数据变成了页表项,从而让页表混乱. * 访问到pde对应的物理地址,用pte取高20位便可. * 因为pte是基于该pde对应的物理地址内再寻址, * 把低12位置0便是该pde对应的物理页的起始*/ memset((void*)((int)pte & 0xfffff000), 0, PG_SIZE); ASSERT(!(*pte & 0x00000001)); *pte = (page_phyaddr | PG_US_U | PG_RW_W | PG_P_1); // US=1,RW=1,P=1 }}void* malloc_page(enum pool_flags pf, uint32_t pg_cnt) { ASSERT(pg_cnt > 0 && pg_cnt < 3840);/*********** malloc_page的原理是三个动作的合成: *********** 1通过vaddr_get在虚拟内存池中申请虚拟地址 2通过palloc在物理内存池中申请物理页 3通过page_table_add将以上得到的虚拟地址和物理地址在页表中完成映射***************************************************************/ void* vaddr_start = vaddr_get(pf, pg_cnt); if (vaddr_start == NULL) { return NULL; } uint32_t vaddr = (uint32_t)vaddr_start, cnt = pg_cnt; struct pool* mem_pool = pf & PF_KERNEL ? &kernel_pool : &user_pool; while (cnt-- > 0) { void* page_phyaddr = palloc(mem_pool); if (page_phyaddr == NULL) { // 失败时要将曾经已申请的虚拟地址和物理页全部回滚,在将来完成内存回收时再补充 return NULL; } page_table_add((void*)vaddr, page_phyaddr); // 在页表中做映射 vaddr += PG_SIZE; // 下一个虚拟页 } return vaddr_start;}void* get_kernel_pages(uint32_t pg_cnt) { void* vaddr = malloc_page(PF_KERNEL, pg_cnt); if (vaddr != NULL) { // 若分配的地址不为空,将页框清0后返回 memset(vaddr, 0, pg_cnt * PG_SIZE); } return vaddr;}static void mem_pool_init(uint32_t all_mem) { put_str(" mem_pool_init start\n"); uint32_t page_table_size = PG_SIZE * 256; // 页表大小= 1页的页目录表+第0和第768个页目录项指向同一个页表+ // 第769~1022个页目录项共指向254个页表,共256个页框 uint32_t used_mem = page_table_size + 0x100000; // 0x100000为低端1M内存 uint32_t free_mem = all_mem - used_mem; uint16_t all_free_pages = free_mem / PG_SIZE; // 1页为4k,不管总内存是不是4k的倍数, // 对于以页为单位的内存分配策略,不足1页的内存不用考虑了。 uint16_t kernel_free_pages = all_free_pages / 2; uint16_t user_free_pages = all_free_pages - kernel_free_pages; uint32_t kbm_length = kernel_free_pages / 8; // Kernel BitMap的长度,位图中的一位表示一页,以字节为单位 uint32_t ubm_length = user_free_pages / 8; // User BitMap的长度. uint32_t kp_start = used_mem; // Kernel Pool start,内核内存�

用户评论 (0)

发表评论

captcha