long mode paging work

This commit is contained in:
pjht 2019-04-30 17:11:26 -05:00
parent 5020cfa3dd
commit 5cb95d816f
10 changed files with 349 additions and 97 deletions

View File

@ -1,4 +1,4 @@
PLAT=x86_64 PLAT=i386
C_SOURCES = $(wildcard kernel/*.c drivers/$(PLAT)/*.c drivers/$(PLAT)/*/*.c cpu/$(PLAT)/*.c fs/*.c) C_SOURCES = $(wildcard kernel/*.c drivers/$(PLAT)/*.c drivers/$(PLAT)/*/*.c cpu/$(PLAT)/*.c fs/*.c)
ASM = $(wildcard cpu/$(PLAT)/*.asm) ASM = $(wildcard cpu/$(PLAT)/*.asm)
S_ASM = $(wildcard cpu/$(PLAT)/*.s) S_ASM = $(wildcard cpu/$(PLAT)/*.s)

View File

@ -10,7 +10,7 @@ floppy_bootsig_check: disabled=0
# no floppya # no floppya
# no floppyb # no floppyb
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path=ext2.img, mode=flat, cylinders=65, heads=16, spt=63, model="Generic 1234", biosdetect=auto, translation=auto ata0-master: type=none, path=ext2.img, mode=flat, cylinders=65, heads=16, spt=63, model="Generic 1234", biosdetect=auto, translation=auto
ata0-slave: type=cdrom, path=os.iso, status=inserted, model="Generic 1234", biosdetect=auto ata0-slave: type=cdrom, path=os.iso, status=inserted, model="Generic 1234", biosdetect=auto
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata1-master: type=none ata1-master: type=none

View File

@ -6,8 +6,14 @@ header_start:
; checksum ; checksum
dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))
; insert optional multiboot tags here ; info request tag
info_tag_start:
dw 1 ; type
dw 0 ; flags
dd info_tag_end-info_tag_start ;size
dd 6 ; full memory map (available and reserved ranges)
info_tag_end:
dd 0 ; tag alignment
; required end tag ; required end tag
dw 0 ; type dw 0 ; type
dw 0 ; flags dw 0 ; flags
@ -21,6 +27,7 @@ section .boot.text
bits 32 bits 32
start: start:
mov esp, stack_top mov esp, stack_top
mov edi, ebx
call check_multiboot call check_multiboot
call check_cpuid call check_cpuid

View File

@ -1,15 +1,13 @@
// #include "gdt.h" #include "paging.h"
// #include "paging.h"
#include "isr.h" #include "isr.h"
#include <grub/multiboot.h> #include <grub/multiboot2.h>
// #include "pmem.h" #include "pmem.h"
// #include "../tasking.h" // #include "../tasking.h"
void cpu_init(multiboot_info_t* mbd) { void cpu_init(struct multiboot_boot_header_tag* mbd) {
// gdt_init();
isr_install(); isr_install();
asm volatile("sti"); asm volatile("sti");
// pmem_init(mbd); pmem_init(mbd);
// paging_init(); paging_init();
// tasking_init(); // tasking_init();
} }

View File

@ -4,6 +4,7 @@ extern kmain
section .boot.text section .boot.text
bits 64 bits 64
long_mode_start: long_mode_start:
xchg bx,bx
mov ax, 0 mov ax, 0
mov ss, ax mov ss, ax
mov ds, ax mov ds, ax

103
cpu/x86_64/paging.c Normal file
View File

@ -0,0 +1,103 @@
#include <stdint.h>
#include "paging.h"
#include "pmem.h"
static uint64_t pml4[512] __attribute__((aligned(4096)));
static uint64_t pdpt[512] __attribute__((aligned(4096)));
static uint64_t page_directory[512] __attribute__((aligned(4096)));
uint64_t* curr_structs=(uint64_t*)0xFFFFFF8000000000;
uint64_t get_pml4_entry(int entry) {
return ((uint64_t*)(((char*)curr_structs)+0x7FFFFFF000))[entry];
}
uint64_t get_pdpt_entry(int pml4_entry,int entry) {
return ((uint64_t*)(((char*)curr_structs)+0x7FFFE00000))[(pml4_entry<<9)+entry];
}
uint64_t get_page_dir_entry(int pml4_entry,int pdpt_entry, int entry) {
return ((uint64_t*)(((char*)curr_structs)+0x7FC0000000))[(pml4_entry<<18)+(pdpt_entry<<9)+entry];
}
uint64_t get_page_table_entry(int pml4_entry,int pdpt_entry, int pdir_entry, int entry) {
return ((uint64_t*)(((char*)curr_structs)+0x7000000000))[(pml4_entry<<27)+(pdpt_entry<<18)+(pdir_entry<<9)+entry];
}
void set_pml4_entry(int entry,uint64_t mapping) {
((uint64_t*)(((char*)curr_structs)+0x7FFFFFF000))[entry]=mapping;
}
void set_pdpt_entry(int pml4_entry,int entry,uint64_t mapping) {
((uint64_t*)(((char*)curr_structs)+0x7FFFE00000))[(pml4_entry<<9)+entry]=mapping;
}
void set_page_dir_entry(int pml4_entry,int pdpt_entry, int entry,uint64_t mapping) {
((uint64_t*)(((char*)curr_structs)+0x7FC0000000))[(pml4_entry<<18)+(pdpt_entry<<9)+entry]=mapping;
}
void set_page_table_entry(int pml4_entry,int pdpt_entry, int pdir_entry, int entry,uint64_t mapping) {
((uint64_t*)(((char*)curr_structs)+0x7000000000))[(pml4_entry<<27)+(pdpt_entry<<18)+(pdir_entry<<9)+entry]=mapping;
}
uint32_t find_free_page() {
for (int a=0;a<512;a++) {
if (get_pml4_entry(a)&0x1) {
for (int b=0;b<512;b++) {
if (get_pdpt_entry(a,b)&0x1) {
for (int c=0;c<512;c++) {
if (get_page_dir_entry(a,b,c)&0x1) {
for (int d=0;d<512;d++) {
if (!(get_page_table_entry(a,b,c,d)&0x1)) {
return (a<<27)+(b<<18)+(c<<9)+d;
}
} // end for d
} else {
uint64_t addr=pmem_alloc(1);
set_page_dir_entry(a,b,c,addr|0x7);
return (a<<27)+(b<<18)+(c<<9);
} // end if abc
} // end for c
} else {
uint64_t addr=pmem_alloc(1);
set_pdpt_entry(a,b,addr|0x7);
addr=pmem_alloc(1);
set_page_dir_entry(a,b,0,addr|0x7);
return (a<<27)+(b<<18);
} // end if ab
} // end for b
} else {
uint64_t addr=pmem_alloc(1);
set_pml4_entry(a,addr|0x7);
addr=pmem_alloc(1);
set_pdpt_entry(a,0,addr|0x7);
addr=pmem_alloc(1);
set_page_dir_entry(a,0,0,addr|0x7);
return a<<27;
} //end if a
} // end for a
return 0;
}
void paging_init() {
pml4[0]=(((uint64_t)&pdpt)-0xffff800000000000)|0x7;
pml4[256]=(((uint64_t)&pdpt)-0xffff800000000000)|0x7;
pml4[511]=(((uint64_t)&pml4)-0xffff800000000000)|0x7;
pdpt[0]=(((uint64_t)&page_directory)-0xffff800000000000)|0x7;
for (int i=0;i<NUM_KERN_DIRS;i++) {
page_directory[i]=(i*0x200000)|0x87;
}
asm volatile("mov %0,%%cr3"::"r"((uint64_t)pml4-0xffff800000000000));
}
void check_gets() {
char str[256];
hex_to_ascii(find_free_page(),str);
vga_write_string(str);
vga_write_string("\n");
str[0]='\0';
hex_to_ascii(find_free_page(),str);
vga_write_string(str);
vga_write_string("\n");
}

10
cpu/x86_64/paging.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef PAGING_H
#define PAGING_H
#include <stdint.h>
#define NUM_KERN_DIRS 4
void paging_init();
#endif

123
cpu/x86_64/pmem.c Normal file
View File

@ -0,0 +1,123 @@
#include <grub/multiboot2.h>
#include "../halt.h"
#include <stdint.h>
#include <stdlib.h>
#include <klog.h>
static char bmap[131072];
static char get_bmap_bit(int index) {
int byte=index/8;
int bit=index%8;
char entry=bmap[byte];
return (entry&(1<<bit))>0;
}
static void set_bmap_bit(int index) {
int byte=index/8;
int bit=index%8;
bmap[byte]=bmap[byte]|(1<<bit);
}
static void clear_bmap_bit(int index) {
int byte=index/8;
int bit=index%8;
bmap[byte]=bmap[byte]&(~(1<<bit));
}
void pmem_init(struct multiboot_boot_header_tag* tags) {
for (int i=0;i<131072;i++) {
bmap[i]=0xFF;
}
char found_mmap=0;
struct multiboot_tag* tag=(struct multiboot_tag*)(tags+1);
while (tag->type!=0) {
switch (tag->type) {
case MULTIBOOT_TAG_TYPE_MMAP: {
found_mmap=1;
struct multiboot_mmap_entry* orig_ptr=(struct multiboot_mmap_entry*)(((char*)tag)+16);
for (struct multiboot_mmap_entry* ptr=orig_ptr;(char*)ptr<((char*)orig_ptr)+tag->size;ptr++) {
if (ptr->type!=MULTIBOOT_MEMORY_AVAILABLE) continue;
uint32_t size=ptr->len;
uint32_t start=ptr->addr;
if (start<0x100000) continue;
uint32_t end=start+ptr->len-1;
if (start&0xFFF) {
start+=0x1000;
}
start=start>>12;
end=end>>12;
for (uint32_t i=start;i<end;i++) {
clear_bmap_bit(i);
}
}
char str[256];
break;
}
}
tag=(struct multiboot_tag*)((char*)tag+((tag->size+7)&0xFFFFFFF8));
}
if (!found_mmap) {
vga_write_string("[PANIC] No memory map supplied by bootloader!");
halt();
}
for (uint32_t i=0;i<2048;i++) {
set_bmap_bit(i);
}
}
void* pmem_alloc(int num_pages) {
uint32_t bmap_index;
uint32_t remaining_blks;
for(uint32_t i=0;i<131072;i++) {
if (bmap[i]!=0xFF) {
char got_0=0;
remaining_blks=num_pages;
uint32_t old_j;
for (uint32_t j=i*8;;j++) {
char bit=get_bmap_bit(j);
if (got_0) {
if (bit) {
if (remaining_blks==0) {
bmap_index=old_j;
break;
} else {
i+=j/8;
i--;
break;
}
} else {
remaining_blks--;
}
} else {
if (!bit) {
got_0=1;
old_j=j;
remaining_blks--;
}
}
if (remaining_blks==0) {
bmap_index=old_j;
break;
}
}
}
if (remaining_blks==0) {
break;
}
}
if (remaining_blks!=0) {
return NULL;
}
for (int i=0;i<num_pages;i++) {
set_bmap_bit(bmap_index+i);
}
void* addr=(void*)(bmap_index<<12);
return addr;
}
void pmem_free(int start_page,int num_pages) {
for (int i=start_page;i<num_pages;i++) {
set_bmap_bit(i);
}
}

10
cpu/x86_64/pmem.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef PMEM_H
#define PMEM_H
#include <grub/multiboot2.h>
void pmem_init(struct multiboot_boot_header_tag* tags);
void* pmem_alloc(int num_pages);
void pmem_free(int start_page,int num_pages);
#endif

View File

@ -24,33 +24,33 @@ static long initrd_sz;
static char* initrd; static char* initrd;
typedef int (*func_ptr)(); typedef int (*func_ptr)();
// static int console_dev_drv(char* filename,int c,long pos,char wr) { static int console_dev_drv(char* filename,int c,long pos,char wr) {
// if (wr) { if (wr) {
// if (c=='\f') { if (c=='\f') {
// vga_clear(); vga_clear();
// } else if (c=='\b') { } else if (c=='\b') {
// vga_backspace(); vga_backspace();
// } }
// char str[2]; char str[2];
// str[0]=(char)c; str[0]=(char)c;
// str[1]='\0'; str[1]='\0';
// vga_write_string(str); vga_write_string(str);
// return 0; return 0;
// } else { } else {
// return 0; return 0;
// // return devbuf_get(kbd_buf); // return devbuf_get(kbd_buf);
// } }
// } }
// static int initrd_dev_drv(char* filename,int c,long pos,char wr) { static int initrd_dev_drv(char* filename,int c,long pos,char wr) {
// if (wr) { if (wr) {
// return 0; return 0;
// } }
// if (pos>=initrd_sz) { if (pos>=initrd_sz) {
// return EOF; return EOF;
// } }
// return initrd[pos]; return initrd[pos];
// } }
// static void read_initrd(multiboot_info_t* mbd) { // static void read_initrd(multiboot_info_t* mbd) {
// if ((mbd->flags&MULTIBOOT_INFO_MODS)!=0) { // if ((mbd->flags&MULTIBOOT_INFO_MODS)!=0) {
@ -76,58 +76,58 @@ typedef int (*func_ptr)();
// } // }
// } // }
// static void init() { static void init() {
// init_vfs(); init_vfs();
// init_devfs(); init_devfs();
// devfs_add(console_dev_drv,"console"); devfs_add(console_dev_drv,"console");
// stdout=fopen("/dev/console","w"); stdout=fopen("/dev/console","w");
// stdin=fopen("/dev/console","r"); stdin=fopen("/dev/console","r");
// stderr=fopen("/dev/console","w"); stderr=fopen("/dev/console","w");
// // read_initrd(mbd); // read_initrd(mbd);
// // devfs_add(initrd_dev_drv,"initrd"); // devfs_add(initrd_dev_drv,"initrd");
// // initrd_init(); // initrd_init();
// // mount("/initrd/","","initrd"); // mount("/initrd/","","initrd");
// // Detect PCI // Detect PCI
// port_long_out(0xCF8,(1<<31)); port_long_out(0xCF8,(1<<31));
// uint32_t word=port_long_in(0xCFC); uint32_t word=port_long_in(0xCFC);
// port_long_out(0xCF8,(1<<31)|0x4); port_long_out(0xCF8,(1<<31)|0x4);
// if (word!=port_long_in(0xCFC)) { if (word!=port_long_in(0xCFC)) {
// // pci_init(); // pci_init();
// } }
// // Detect and initailize serial ports // Detect and initailize serial ports
// serial_init(); serial_init();
// // FILE* file=fopen("/initrd/prog.elf","r"); // FILE* file=fopen("/initrd/prog.elf","r");
// // elf_header header; // elf_header header;
// // fread(&header,sizeof(elf_header),1,file); // fread(&header,sizeof(elf_header),1,file);
// // if (header.magic!=ELF_MAGIC) { // if (header.magic!=ELF_MAGIC) {
// // klog("INFO","Invalid magic number for prog.elf"); // klog("INFO","Invalid magic number for prog.elf");
// // fclose(file); // fclose(file);
// // } else { // } else {
// // fseek(file,header.prog_hdr,SEEK_SET); // fseek(file,header.prog_hdr,SEEK_SET);
// // elf_pheader pheader; // elf_pheader pheader;
// // fread(&pheader,sizeof(elf_pheader),1,file); // fread(&pheader,sizeof(elf_pheader),1,file);
// // alloc_memory_virt(1,(void*)pheader.vaddr); // alloc_memory_virt(1,(void*)pheader.vaddr);
// // fseek(file,pheader.offset,SEEK_SET); // fseek(file,pheader.offset,SEEK_SET);
// // fread((void*)pheader.vaddr,pheader.filesz,1,file); // fread((void*)pheader.vaddr,pheader.filesz,1,file);
// // klog("INFO","VADDR:%x",pheader.vaddr); // klog("INFO","VADDR:%x",pheader.vaddr);
// // func_ptr prog=(func_ptr)header.entry; // func_ptr prog=(func_ptr)header.entry;
// // int val=prog(); // int val=prog();
// // klog("INFO","RAN PROG:%d",val); // klog("INFO","RAN PROG:%d",val);
// // } // }
// ide_init(); ide_init();
// load_parts("/dev/hda"); load_parts("/dev/hda");
// init_ext2(); init_ext2();
// mount("/","/dev/hda1","ext2"); mount("/","/dev/hda1","ext2");
// klog("INFO","MOUNT"); klog("INFO","MOUNT");
// FILE* f=fopen("/file","r"); FILE* f=fopen("/file","r");
// char str[256]; char str[256];
// fgets(str,256,f); fgets(str,256,f);
// str[strlen(str)-1]='\0'; str[strlen(str)-1]='\0';
// klog("INFO","Got string %s",str); klog("INFO","Got string %s",str);
// for(;;) { for(;;) {
// yield(); yield();
// } }
// } }
void kmain(struct multiboot_boot_header_tag* tags) { void kmain(struct multiboot_boot_header_tag* tags) {
cpu_init(tags); cpu_init(tags);
@ -137,16 +137,16 @@ void kmain(struct multiboot_boot_header_tag* tags) {
// info.width=header->framebuffer_width; // info.width=header->framebuffer_width;
// info.height=header->framebuffer_height; // info.height=header->framebuffer_height;
// } else { // } else {
info.address=(char*)0xffff8000000B8000; // info.address=(char*)0xffff8000000B8000;
// info.address=(char*)0xC00B8000; info.address=(char*)0xC00B8000;
info.width=80; info.width=80;
info.height=25; info.height=25;
// } // }
vga_init(info); vga_init(info);
vga_write_string("Hello long mode world!\n"); vga_write_string("Hello long mode world!\n");
// createTask(init); // check_gets();
// for (;;) { createTask(init);
// yield(); for (;;) {
// } yield();
for(;;); }
} }