void initialize_paging(uint32_t memsize) { nframes = memsize / 4; frames = (uint32_t *)kmalloc(INDEX_FROM_BIT(nframes)); uintptr_t pg; assert(frames != NULL); memset(frames, 0, INDEX_FROM_BIT(nframes)); uintptr_t physical; kernel_directory = (page_directory_t *)kmalloc_ap(sizeof(page_directory_t), &physical); memset(kernel_directory, 0, sizeof(page_directory_t)); current_directory = kernel_directory; #if 1 get_page(0,1,kernel_directory)->present = 0; set_frame(0); for(uintptr_t i = 0x1000; i < placement_address+0x3000; i += 0x1000) #else for(uintptr_t i = 0x0; i < placement_address+0x3000; i += 0x1000) #endif { direct_frame( get_page(i, 1, kernel_directory), 1, 0, i); } kernel_directory->physical_addr = (uintptr_t)kernel_directory->tables_physical; uintptr_t heap_start = KERNEL_HEAP_START; if(heap_start <= placement_address + 0x3000) { heap_start = placement_address + 0x100000; } for (uintptr_t i = placement_address + 0x3000; i < heap_start; i += 0x1000) { alloc_frame(get_page(i, 1, kernel_directory), 1, 0); } for(uintptr_t i = heap_start; i < heap_start + KERNEL_HEAP_INIT; i += 0x1000) { get_page(i, 1, kernel_directory); } for(uintptr_t i = heap_start; i < heap_start + KERNEL_HEAP_INIT; i += 0x1000) { alloc_frame(get_page(i, 1, kernel_directory), 0, 0); } register_isr_handler(13, general_protection_fault); register_isr_handler(14, page_fault); switch_page_directory(kernel_directory); kernel_heap = create_heap(heap_start, heap_start + KERNEL_HEAP_INIT, KERNEL_HEAP_END, 0, 0); //kernel_heap = create_heap(heap_start, KERNEL_HEAP_END, KERNEL_HEAP_END, 0, 0); }
/** * Initialises the scheduler. This sets up several required data structures and * memory segments, and sets up the scheduler to be ready to begin executing. */ void scheduler_init(void) { // Allocate frameset unsigned int nframes = (TCB_END + 1) - TCB_START; nframes /= 0x1000; KDEBUG("Scheduler supports %u threads max (sizeof(scheduler_tcb_t) = %u)\n", nframes, (unsigned int) sizeof(scheduler_tcb_t)); frames = (unsigned int *) kmalloc(INDEX_FROM_BIT(nframes)); memclr(frames, INDEX_FROM_BIT(nframes)); }
static void clear_frame(uintptr_t addr) { uintptr_t frame = addr/0x1000; uint32_t idx = INDEX_FROM_BIT(frame); uint32_t off = OFFSET_FROM_BIT(frame); frames[idx] &= ~(0x1 << off); }
static uint32_t test_frame(uintptr_t addr) { uintptr_t frame = addr/0x1000; uint32_t idx = INDEX_FROM_BIT(frame); uint32_t off = OFFSET_FROM_BIT(frame); return (frames[idx] & (0x1 << off)); }
static uint32_t test_frame(uint32_t frame_addr) { uint32_t frame=frame_addr/0x1000; uint32_t idx=INDEX_FROM_BIT(frame); uint32_t offset=OFFSET_FROM_BIT(frame); return frames[idx] & (1<<offset); }
u32int test_frame(u32int frame_addr) { u32int frame = frame_addr / 0x1000; u32int idx = INDEX_FROM_BIT(frame); u32int off = OFFSET_FROM_BIT(frame); return frames[idx] & (0x1 << off); }
void clear_frame(u32int frame_addr) { u32int frame = frame_addr / 0x1000; u32int idx = INDEX_FROM_BIT(frame); u32int off = OFFSET_FROM_BIT(frame); frames[idx] &= ~(0x1 << off); }
static void clear_frame(uint32_t frame_addr) { uint32_t frame=frame_addr/0x1000; uint32_t idx=INDEX_FROM_BIT(frame); uint32_t offset=OFFSET_FROM_BIT(frame); frames[idx] &= ( ~(1<<offset) ); }
static void clear_frame(uint32_t frame_addr) { uint32_t frame = frame_addr/PAGE_SIZ; uint32_t idx = INDEX_FROM_BIT(frame); uint32_t off = OFFSET_FROM_BIT(frame); frames[idx] &= ~(0x1 << off); }
/* Static function to set a bit in the frames bitset */ static void set_frame(addr frame_addr) { addr frame = frame_addr/0x1000; addr idx = INDEX_FROM_BIT(frame); addr off = OFFSET_FROM_BIT(frame); frames[idx] |= (0x1 << off); }
/* Static function to test if a bit is set */ static unsigned int test_frame(addr frame_addr) { addr frame = frame_addr/0x1000; addr idx = INDEX_FROM_BIT(frame); addr off = OFFSET_FROM_BIT(frame); return (frames[idx] & (0x1 << off)); }
static void set_frame(uint32_t frame_addr) { uint32_t frame = frame_addr / 0x1000; uint32_t idx = INDEX_FROM_BIT(frame); uint32_t off = OFFSET_FROM_BIT(frame); _pages[idx] |= (0x1 << off); }
static void set_frame(uint32_t frame_addr) { off_t off; uint32_t idx, frame; frame = frame_addr/PAGE_SIZ; idx = INDEX_FROM_BIT(frame); off = OFFSET_FROM_BIT(frame); frames[idx] |= (0x1 << off); }
// Static function to test if a bit is set. inline bool operator[]( const size_t &pos ) const { //static u32int test_frame(u32int frame_addr) //{ // uint32_t frame = frame_addr/0x1000; const uint32_t idx = INDEX_FROM_BIT(pos); const uint32_t off = OFFSET_FROM_BIT(pos); return (base[idx] & (0x1 << off)); //} }
static void set_frame(uintptr_t addr) { if(addr < nframes * 0x1000) { uint32_t frame = addr/0x1000; uint32_t idx = INDEX_FROM_BIT(frame); uint32_t off = OFFSET_FROM_BIT(frame); frames[idx] |= (0x1 << off); } }
static uint32_t first_frame() { uint32_t i, j, to_test; for (i = 0; i < INDEX_FROM_BIT(nframes); i++) if (frames[i] != 0xFFFFFFFF) for (j = 0; j < 32; j++) { to_test = 0x1 << j; if (!(frames[i] & to_test)) return i * 4 * 8 + j; } return 0; }
static uint32_t first_frame(void) { printf("first_frame called.\n"); printf("nFrames is: %d\n", nFrames); printf("will loop %d times\n", INDEX_FROM_BIT(nFrames)); for(uint32_t i=0;i<INDEX_FROM_BIT(nFrames);++i) { if(frames[i]!=0xFFFFFFFF) // there is a free bit here { printf("Found a limb with a free bit!\n"); for(int j=0;j<32;++j) { uint32_t temp=(1<<j); if(!(frames[i] & temp) ) // current bit is zero { return i*4*8+j; } } } } // we're out of free frames! return (uint32_t) -1; }
void init_paging() { size_t sz; uint32_t i; uint32_t mem_end_page; DPRINTK("paging...\t\t"); mem_end_page = 0x1000000; nframes = mem_end_page / PAGE_SIZ; sz = INDEX_FROM_BIT(nframes); frames = (uint32_t *)kmalloc(sz); memset(frames, 0, sz); kernel_directory = (struct page_directory *) kmalloc_a(sizeof(struct page_directory)); memset(kernel_directory, 0, sizeof(struct page_directory)); // don't do this... current_directory = kernel_directory; // do this instead... kernel_directory->physical_addr = (uint32_t)kernel_directory->tables_physical; for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += PAGE_SIZ) get_page(i, 1, kernel_directory); i = 0; while (i < placement_addr + PAGE_SIZ) { alloc_frame(get_page(i, 1, kernel_directory), 0, 0); i += PAGE_SIZ; } for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += PAGE_SIZ) alloc_frame(get_page(i, 1, kernel_directory), 0, 0); // register_interrupt_handler(14, page_fault); switch_page_directory(kernel_directory); enable_paging(); kheap = create_heap(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, 0, 0); current_directory = clone_directory(kernel_directory); switch_page_directory(current_directory); DPRINTK("done!\n"); }
u32int first_frame() { u32int i, j; for(i = 0; i < INDEX_FROM_BIT(nframes); i++){ if(frames[i] != 0xffffffff){ for(j = 0; j < 32; j++){ u32int mask = 0x1 << j; if(!(frames[i] & mask)){ return i * 32 + j; } } } } return 0xffffffff;//应该加个参数 否则无法分辨是成功分配了还是满了 }
static uint32_t first_frame() { for (uint32_t i = 0; i < INDEX_FROM_BIT(nframes); i++) { if (frames[i] != 0xFFFFFFFF) { // at least one bit is free here. for (uint32_t j = 0; j < 0x20; j++) { if ( !(frames[i] & (0x1 << j)) ) { return i*0x20+j; } } } } return 0xFFFFFFFF; }
/** * Find the first free frame that can be allocated for a structure. * * @return Offset into the bitset */ static unsigned int find_free_frame() { unsigned int i, j; for(i = 0; i < INDEX_FROM_BIT(nframes); i++) { if(frames[i] != 0xFFFFFFFF) { // nothing free, check next // At least one bit is free here for (j = 0; j < 32; j++) { unsigned int toTest = 0x1 << j; // If this frame is free, return if (!(frames[i] & toTest)) { return i*4*8+j; } } } } return -1; }
/* Static function to find the first free frame */ static addr first_frame() { unsigned int i, j; for (i = 0; i < INDEX_FROM_BIT(nframes); i++) { if (frames[i] != 0xFFFFFFFF) { for (j = 0; j < 32; j++) { unsigned int test = 0x1 << j; if ( !(frames[i]&test) ) { return i*4*8+j; } } } } return (addr) - 1; }
static uint32_t first_frame() { uint32_t i, j, frame; frame = 0; for (i = 0; i < INDEX_FROM_BIT(_nr_total_pages); i++) { if (_pages[i] != 0xFFFFFFFF) { for (j = 0; j < 32; j++) { uint32_t to_test = 0x1 << j; if (!(_pages[i] & to_test)) { frame = i * 4 * 8 + j; goto out; } } } } out: return frame; }
/* * Initialises paging and sets up page tables. */ void paging_init() { kheap = NULL; unsigned int i = 0; // Hopefully the bootloader got the correct himem size uint32_t mem_end_page = sys_multiboot_info->mem_upper * 1024; nframes = mem_end_page / 0x1000; pages_total = nframes; frames = (uint32_t *) kmalloc(INDEX_FROM_BIT(nframes)); memclr(frames, INDEX_FROM_BIT(nframes)); // Allocate mem for a page directory. kernel_directory = (page_directory_t *) kmalloc_a(sizeof(page_directory_t)); ASSERT(kernel_directory != NULL); memclr(kernel_directory, sizeof(page_directory_t)); current_directory = kernel_directory; // Map some pages in the kernel heap area. // Here we call get_page but not alloc_frame. This causes page_table_t's // to be created where necessary. We can't allocate frames yet because they // they need to be identity mapped first below, and yet we can't increase // placement_address between identity mapping and enabling the heap for(i = KHEAP_START; i < KHEAP_START+KHEAP_INITIAL_SIZE; i += 0x1000) { page_t* page = paging_get_page(i, true, kernel_directory); memclr(page, sizeof(page_t)); page->rw = 1; page->user = 0; } // This step serves to map the kernel itself // We don't allocate frames here, as that's done below. for(i = 0xC0000000; i < 0xC7FFF000; i += 0x1000) { page_t* page = paging_get_page(i, true, kernel_directory); memclr(page, sizeof(page_t)); page->present = 1; page->rw = 1; page->user = 0; page->frame = ((i & 0x0FFFF000) >> 12); } // Allocate enough memory past the kernel heap so we can use the 'smart' allocator. // Note that this actually performs identity mapping. i = 0x00000000; while(i < (kheap_placement_address & 0x0FFFFFFF) + 0x1000) { alloc_frame(paging_get_page(i, true, kernel_directory), true, true); if(i < (uint32_t) &__kern_size) { pages_wired++; } i += 0x1000; } // Allocate kernel heap pages. for(i = KHEAP_START; i < KHEAP_START+KHEAP_INITIAL_SIZE; i += 0x1000) { alloc_frame(paging_get_page(i, false, kernel_directory), true, true); } // Set page fault handler // sys_set_idt_gate(14, (uint32_t) isr14, 0x08, 0x8E); // Convert kernel directory address to physical and save it kern_dir_phys = (uint32_t) &kernel_directory->tablesPhysical; kern_dir_phys -= 0xC0000000; kernel_directory->physicalAddr = kern_dir_phys; // Enable paging paging_switch_directory(kernel_directory); // Initialise a kernel heap kheap = create_heap(KHEAP_START, KHEAP_START+KHEAP_INITIAL_SIZE, 0xCFFFF000, true, true); }
inline void set( const size_t &pos ){ // u32int frame = frame_addr/0x1000; const uint32_t idx = INDEX_FROM_BIT(pos); const uint32_t off = OFFSET_FROM_BIT(pos); base[idx] |= (0x1 << off); }
/** * Set a bit in the frames bitset as used. * * @param frame Offset into the array */ static inline void set_frame(unsigned int frame) { unsigned int idx = INDEX_FROM_BIT(frame); unsigned int off = OFFSET_FROM_BIT(frame); frames[idx] |= (0x1 << off); }
inline void clear( const size_t &pos ){ // uint32_t frame = frame_addr/0x1000; const uint32_t idx = INDEX_FROM_BIT(pos); const uint32_t off = OFFSET_FROM_BIT(pos); base[idx] &= ~(0x1 << off); }