IA32 MMU paging初始化代码
写了一段IA32 paging通用构造代码。有须要的。能够拿去
#define PDE_FLG_RW (1<<1) #define PDE_FLG_US (1<<2) #define PDE_FLG_RWT (1<<3) #define PDE_FLG_PCD (1<<4) /* * initialize to be zero for page directory and page table */ static __SECTION_ZERO_INIT("PAGE_DIR") __align(4096) U32 paging_pde[1<<10]; static __SECTION_ZERO_INIT("PAGE_TABLE") __align(4096) U32 paging_pte_4k[1<<10][1<<10]; /* * viraddr: virtual address/linear address (must be 4KB align) * phyaddr: physical address (must be 4KB align) * size: in bytes */ static void paging_4k(U32 viraddr, U32 phyaddr, U32 flags) { U32 viraddr_pd = viraddr>>22; U32 viraddr_pt = (viraddr>>12) & 0x3FF; /*page directory*/ paging_pde[viraddr_pd] = (U32)(&(paging_pte_4k[viraddr_pd][viraddr_pt])) & 0xFFFFF000; paging_pde[viraddr_pd] |= flags; paging_pde[viraddr_pd] |= 1; paging_pde[viraddr_pd] &= (~(1<<7)); /*page table*/ paging_pte_4k[viraddr_pd][viraddr_pt] = phyaddr & 0xFFFFF000; paging_pte_4k[viraddr_pd][viraddr_pt] |= flags; paging_pte_4k[viraddr_pd][viraddr_pt] |= 1; } static void paging_4k_frames(U32 viraddr, U32 phyaddr, U32 size, U32 flags) { U32 i, count = size >> 12; for(i=0; i<count; i++) { paging_4k(viraddr+((1<<12)*i), phyaddr+((1<<12)*i), flags); } } /* * viraddr: virtual address/linear address (must be 4MB align) * phyaddr: physical address (must be 4MB align) * size: in bytes */ static void paging_4m(U32 viraddr, U32 phyaddr, U32 flags) { U32 viraddr_pd = viraddr>>22; /*page directory*/ paging_pde[viraddr_pd] = phyaddr & 0xFFC00000; paging_pde[viraddr_pd] |= flags; paging_pde[viraddr_pd] |= 1; paging_pde[viraddr_pd] |= (1<<7); } static void paging_4m_frames(U32 viraddr, U32 phyaddr, U32 size, U32 flags) { U32 i, count = size >> 22; for(i=0; i<count; i++) { paging_4m(viraddr+((1<<22)*i), phyaddr+((1<<22)*i), flags); } } static void paging_frames(U32 viraddr, U32 phyaddr, U32 size, U32 flags) { /* direct mapping */ if(size & 0x3FFFFF) { paging_4k_frames(phyaddr, phyaddr, size, flags); } else { paging_4m_frames(phyaddr, phyaddr, size, flags); } } void paging_uncache(U32 phyaddr, U32 size) { /* direct mapping */ paging_frames(phyaddr, phyaddr, size, PDE_FLG_PCD|PDE_FLG_US|PDE_FLG_RW); } void paging_code(U32 phyaddr, U32 size) { /* direct mapping */ paging_frames(phyaddr, phyaddr, size, PDE_FLG_US); } void paging_data(U32 phyaddr, U32 size) { /* direct mapping */ paging_frames(phyaddr, phyaddr, size, PDE_FLG_US|PDE_FLG_RW); } void * paging_pde_addr() { return (void *)paging_pde; } void paging_enable(void) { U32 cr0; asm volatile("mov %%cr0, %0": "=r"(cr0)); cr0 |= (1<<31); asm volatile("mov %0, %%cr0":: "r"(cr0)); } void paging_setup() { /* peripherial registers */ paging_uncache(0xE0000000, 0x20000000); /* code & data areas */ paging_uncache(0x00000000, 0x40000000); paging_enable(); }