修复进程页表切换reboot问题
This commit is contained in:
parent
0fe64260c0
commit
4ed9674bde
@ -6,7 +6,7 @@
|
|||||||
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector);
|
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector);
|
||||||
#define l9660_seekdir(dir, pos) (l9660_seek(&(dir)->file, L9660_SEEK_SET, (pos)))
|
#define l9660_seekdir(dir, pos) (l9660_seek(&(dir)->file, L9660_SEEK_SET, (pos)))
|
||||||
#define l9660_telldir(dir) (l9660_tell(&(dir)->file))
|
#define l9660_telldir(dir) (l9660_tell(&(dir)->file))
|
||||||
xi#define get_root_dir(vfs) ((l9660_fs_status_t *)(vfs->cache))->root_dir
|
#define get_root_dir(vfs) ((l9660_fs_status_t *)(vfs->cache))->root_dir
|
||||||
|
|
||||||
#define SEEK_END L9660_SEEK_END
|
#define SEEK_END L9660_SEEK_END
|
||||||
#define SEEK_SET L9660_SEEK_SET
|
#define SEEK_SET L9660_SEEK_SET
|
||||||
|
@ -95,4 +95,8 @@ void free_frame(page_t *page);
|
|||||||
|
|
||||||
void page_flush(page_directory_t *dir);
|
void page_flush(page_directory_t *dir);
|
||||||
|
|
||||||
|
void page_switch(page_directory_t *dir);
|
||||||
|
|
||||||
|
uint32_t kmalloc_i_ap(uint32_t size, uint32_t *phys);
|
||||||
|
|
||||||
#endif //CRASHPOWEROS_MEMORY_H
|
#endif //CRASHPOWEROS_MEMORY_H
|
||||||
|
@ -18,18 +18,30 @@ uint32_t memory_usage(){
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t kmalloc_int(uint32_t sz, uint32_t align, uint32_t *phys) {
|
uint32_t kmalloc_i_ap(uint32_t size, uint32_t *phys){
|
||||||
|
if ((placement_address & 0x00000FFF)) {
|
||||||
|
placement_address &= 0xFFFFF000;
|
||||||
|
placement_address += 0x1000;
|
||||||
|
}
|
||||||
|
if (phys) *phys = placement_address;
|
||||||
|
uint32_t tmp = placement_address;
|
||||||
|
placement_address += size;
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t kmalloc_int(size_t sz, uint32_t align, uint32_t *phys) {
|
||||||
if (program_break) {
|
if (program_break) {
|
||||||
// 有内存堆
|
// 有内存堆
|
||||||
void *addr = alloc(sz); // 直接malloc,align丢掉了
|
void *addr = alloc(sz); // 直接malloc,align丢掉了
|
||||||
if (phys) {
|
if (phys) {
|
||||||
// 需要物理地址,先找到对应页
|
// 需要物理地址,先找到对应页
|
||||||
page_t *page = get_page((uint32_t) addr, 0, current_directory);
|
page_t *page = get_page((uint32_t) addr, 0, current_directory);
|
||||||
*phys = page->frame * 0x1000 + ((uint32_t) addr & 0xfff);
|
*phys = page->frame * 0x1000 + ((uint32_t) addr & 0x00000FFF);
|
||||||
}
|
}
|
||||||
return (uint32_t) addr;
|
return (uint32_t) addr;
|
||||||
}
|
}
|
||||||
if (align && (placement_address & 0x00000FFF)) {
|
if (align == 1 && (placement_address & 0x00000FFF)) {
|
||||||
placement_address &= 0xFFFFF000;
|
placement_address &= 0xFFFFF000;
|
||||||
placement_address += 0x1000;
|
placement_address += 0x1000;
|
||||||
}
|
}
|
||||||
@ -65,7 +77,7 @@ void *ksbrk(int incr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 寻找一个符合条件的指定大小的空闲内存块
|
// 寻找一个符合条件的指定大小的空闲内存块
|
||||||
static header_t *get_free_block(uint32_t size) {
|
static header_t *get_free_block(size_t size) {
|
||||||
header_t *curr = head;
|
header_t *curr = head;
|
||||||
while (curr) {
|
while (curr) {
|
||||||
if (curr->s.is_free && curr->s.size >= size) return curr;
|
if (curr->s.is_free && curr->s.size >= size) return curr;
|
||||||
@ -74,7 +86,7 @@ static header_t *get_free_block(uint32_t size) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *alloc(uint32_t size) {
|
void *alloc(size_t size) {
|
||||||
uint32_t total_size;
|
uint32_t total_size;
|
||||||
void *block;
|
void *block;
|
||||||
header_t *header;
|
header_t *header;
|
||||||
|
@ -92,9 +92,19 @@ void page_flush(page_directory_t *dir){
|
|||||||
//asm volatile("mov %0, %%cr3" : : "r"(&dir->physicalAddr));
|
//asm volatile("mov %0, %%cr3" : : "r"(&dir->physicalAddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void page_switch(page_directory_t *dir){
|
||||||
|
io_cli();
|
||||||
|
current_directory = dir;
|
||||||
|
logkf("TablePhy: %08x | KERPhy: %08x\n",(&dir->tablesPhysical),kernel_directory->tablesPhysical);
|
||||||
|
asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical)); // 设置cr3寄存器切换页表
|
||||||
|
logk("Switch directory win!\n");
|
||||||
|
io_sti();
|
||||||
|
}
|
||||||
|
|
||||||
void switch_page_directory(page_directory_t *dir) {
|
void switch_page_directory(page_directory_t *dir) {
|
||||||
current_directory = dir;
|
current_directory = dir;
|
||||||
asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical));
|
asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical));
|
||||||
|
|
||||||
uint32_t cr0;
|
uint32_t cr0;
|
||||||
asm volatile("mov %%cr0, %0" : "=r"(cr0));
|
asm volatile("mov %%cr0, %0" : "=r"(cr0));
|
||||||
cr0 |= 0x80000000;
|
cr0 |= 0x80000000;
|
||||||
@ -172,7 +182,7 @@ static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) {
|
|||||||
|
|
||||||
page_directory_t *clone_directory(page_directory_t *src) {
|
page_directory_t *clone_directory(page_directory_t *src) {
|
||||||
uint32_t phys;
|
uint32_t phys;
|
||||||
page_directory_t *dir = (page_directory_t *) kmalloc_ap(sizeof(page_directory_t), &phys);
|
page_directory_t *dir = (page_directory_t *) kmalloc_i_ap(sizeof(page_directory_t), &phys);
|
||||||
memset(dir, 0, sizeof(page_directory_t));
|
memset(dir, 0, sizeof(page_directory_t));
|
||||||
|
|
||||||
uint32_t offset = (uint32_t) dir->tablesPhysical - (uint32_t) dir;
|
uint32_t offset = (uint32_t) dir->tablesPhysical - (uint32_t) dir;
|
||||||
@ -200,7 +210,9 @@ void init_page(multiboot_t *mboot) {
|
|||||||
frames = (uint32_t *) kmalloc(INDEX_FROM_BIT(nframes));
|
frames = (uint32_t *) kmalloc(INDEX_FROM_BIT(nframes));
|
||||||
memset(frames, 0, INDEX_FROM_BIT(nframes));
|
memset(frames, 0, INDEX_FROM_BIT(nframes));
|
||||||
|
|
||||||
kernel_directory = (page_directory_t *) kmalloc_a(sizeof(page_directory_t)); //kmalloc: 无分页情况自动在内核后方分配 | 有分页从内核堆分配
|
uint32_t physical_addr;
|
||||||
|
kernel_directory = (page_directory_t *) kmalloc_ap(sizeof(page_directory_t),&physical_addr); //kmalloc: 无分页情况自动在内核后方分配 | 有分页从内核堆分配
|
||||||
|
kernel_directory->physicalAddr = physical_addr;
|
||||||
|
|
||||||
memset(kernel_directory, 0, sizeof(page_directory_t));
|
memset(kernel_directory, 0, sizeof(page_directory_t));
|
||||||
current_directory = kernel_directory;
|
current_directory = kernel_directory;
|
||||||
@ -225,7 +237,7 @@ void init_page(multiboot_t *mboot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
register_interrupt_handler(14, page_fault);
|
register_interrupt_handler(14, page_fault);
|
||||||
switch_page_directory(kernel_directory);
|
switch_page_directory(clone_directory(kernel_directory));
|
||||||
|
|
||||||
program_break = (void *) KHEAP_START;
|
program_break = (void *) KHEAP_START;
|
||||||
program_break_end = (void *) (KHEAP_START + KHEAP_INITIAL_SIZE);
|
program_break_end = (void *) (KHEAP_START + KHEAP_INITIAL_SIZE);
|
||||||
|
@ -158,7 +158,7 @@ void change_task_to(struct task_struct *next) {
|
|||||||
struct task_struct *prev = current;
|
struct task_struct *prev = current;
|
||||||
current = next;
|
current = next;
|
||||||
|
|
||||||
page_flush(current->pgd_dir);
|
page_switch(current->pgd_dir);
|
||||||
set_kernel_stack(current->stack);
|
set_kernel_stack(current->stack);
|
||||||
switch_to(&(prev->context), &(current->context));
|
switch_to(&(prev->context), &(current->context));
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ int32_t kernel_thread(int (*fn)(void *), void *arg,char* name) {
|
|||||||
new_task->state = TASK_RUNNABLE;
|
new_task->state = TASK_RUNNABLE;
|
||||||
new_task->stack = current;
|
new_task->stack = current;
|
||||||
new_task->pid = now_pid++;
|
new_task->pid = now_pid++;
|
||||||
new_task->pgd_dir = clone_directory(kernel_directory) ;
|
new_task->pgd_dir = clone_directory(current->pgd_dir) ;
|
||||||
|
|
||||||
new_task->name = name;
|
new_task->name = name;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user