Long mode works!!!

This commit is contained in:
pjht 2019-04-26 09:47:57 -05:00
parent 1690e1ed5b
commit fbef5710ed
8 changed files with 652 additions and 160 deletions

183
cpu/x86_64/boot.asm Normal file
View File

@ -0,0 +1,183 @@
section .multiboot
header_start:
dd 0xe85250d6 ; magic number (multiboot 2)
dd 0 ; architecture 0 (protected mode i386)
dd header_end - header_start ; header length
; checksum
dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))
; insert optional multiboot tags here
; required end tag
dw 0 ; type
dw 0 ; flags
dd 8 ; size
header_end:
global start
extern long_mode_start
section .boot.text
bits 32
start:
mov esp, stack_top
call check_multiboot
call check_cpuid
call check_long_mode
call set_up_page_tables
call enable_paging
lgdt [gdt64.pointer]
jmp 0x08:long_mode_start
; print `NO` to screen
mov dword [0xb8000], 0x4f4f4f4e
hlt
check_multiboot:
cmp eax, 0x36d76289
jne .no_multiboot
ret
.no_multiboot:
mov al, "0"
jmp error
check_cpuid:
; Check if CPUID is supported by attempting to flip the ID bit (bit 21)
; in the FLAGS register. If we can flip it, CPUID is available.
; Copy FLAGS in to EAX via stack
pushfd
pop eax
; Copy to ECX as well for comparing later on
mov ecx, eax
; Flip the ID bit
xor eax, 1 << 21
; Copy EAX to FLAGS via the stack
push eax
popfd
; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported)
pushfd
pop eax
; Restore FLAGS from the old version stored in ECX (i.e. flipping the
; ID bit back if it was ever flipped).
push ecx
popfd
; Compare EAX and ECX. If they are equal then that means the bit
; wasn't flipped, and CPUID isn't supported.
cmp eax, ecx
je .no_cpuid
ret
.no_cpuid:
mov al, "1"
jmp error
check_long_mode:
; test if extended processor info in available
mov eax, 0x80000000 ; implicit argument for cpuid
cpuid ; get highest supported argument
cmp eax, 0x80000001 ; it needs to be at least 0x80000001
jb .no_long_mode ; if it's less, the CPU is too old for long mode
; use extended info to test if long mode is available
mov eax, 0x80000001 ; argument for extended processor info
cpuid ; returns various feature bits in ecx and edx
test edx, 1 << 29 ; test if the LM-bit is set in the D-register
jz .no_long_mode ; If it's not set, there is no long mode
ret
.no_long_mode:
mov al, "2"
jmp error
set_up_page_tables:
; map first P4 entry to P3 table
mov eax, p3_table
or eax, 0b11 ; present + writable
mov [p4_table], eax
; map 256th P4 entry to P3 table
mov eax, p3_table
or eax, 0b11 ; present + writable
mov [p4_table+256*8], eax
; map first P3 entry to P2 table
mov eax, p2_table
or eax, 0b11 ; present + writable
mov [p3_table], eax
; map each P2 entry to a huge 2MiB page
mov ecx, 0 ; counter variable
.map_p2_table:
; map ecx-th P2 entry to a huge page that starts at address 2MiB*ecx
mov eax, 0x200000 ; 2MiB
mul ecx ; start address of ecx-th page
or eax, 0b10000011 ; present + writable + huge
mov [p2_table + ecx * 8], eax ; map ecx-th entry
inc ecx ; increase counter
cmp ecx, 4 ; if counter == 4, we have mapped enough pages
jne .map_p2_table ; else map the next entry
ret
enable_paging:
; load P4 to cr3 register (cpu uses this to access the P4 table)
mov eax, p4_table
mov cr3, eax
; enable PAE-flag in cr4 (Physical Address Extension)
mov eax, cr4
or eax, 1 << 5
mov cr4, eax
; set the long mode bit in the EFER MSR (model specific register)
mov ecx, 0xC0000080
rdmsr
or eax, 1 << 8
wrmsr
; enable paging in the cr0 register
mov eax, cr0
or eax, 1 << 31
mov cr0, eax
ret
; Prints `ERR: ` and the given error code to screen and hangs.
; parameter: error code (in ascii) in al
error:
mov dword [0xb8000], 0x4f524f45
mov dword [0xb8004], 0x4f3a4f52
mov dword [0xb8008], 0x4f204f20
mov byte [0xb800a], al
hlt
section .boot.bss
align 4096
p4_table:
resb 4096
p3_table:
resb 4096
p2_table:
resb 4096
stack_bottom:
resb 4096*4
stack_top:
section .boot.rodata
gdt64:
dq 0 ; zero entry
dq (1<<43) | (1<<44) | (1<<47) | (1<<53) ; code segment
dq (1<<43) | (1<<44) | (1<<45) | (1<<46) | (1<<47) | (1<<53) ; user code segment
.pointer:
dw $ - gdt64 - 1
dq gdt64

48
cpu/x86_64/linker.ld Normal file
View File

@ -0,0 +1,48 @@
ENTRY(start)
SECTIONS {
. = 1M;
.multiboot :
{
*(.multiboot)
}
.boottext ALIGN (4K) :
{
*(.boot.text)
}
.bootrodata ALIGN (4K) :
{
*(.boot.rodata)
}
.bootdata ALIGN (4K) :
{
*(.boot.data)
}
.bootbss ALIGN (4K) :
{
*(.boot.bss)
}
. += 0xffff800000000000;
.text ALIGN (4K) : AT (ADDR (.text) - 0xffff800000000000)
{
*(.text)
}
.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xffff800000000000)
{
*(.rodata)
}
.data ALIGN (4K) : AT (ADDR (.data) - 0xffff800000000000)
{
*(.data)
}
.bss ALIGN (4K) : AT (ADDR (.bss) - 0xffff800000000000)
{
*(.bss)
}
}

View File

@ -0,0 +1,9 @@
global long_mode_start
extern kmain
section .boot.text
bits 64
long_mode_start:
mov rax,kmain
call rax
loop: jmp loop

31
cpu/x86_64/ports.c Normal file
View File

@ -0,0 +1,31 @@
#include <stdint.h>
uint8_t port_byte_in(uint16_t port) {
uint8_t result;
asm("in %%dx, %%al":"=a"(result):"d"(port));
return result;
}
void port_byte_out(uint16_t port,uint8_t data) {
asm("out %%al, %%dx":: "a"(data),"d"(port));
}
uint16_t port_word_in(uint16_t port) {
uint16_t result;
asm("in %%dx, %%ax":"=a"(result):"d"(port));
return result;
}
void port_word_out(uint16_t port,uint16_t data) {
asm("out %%ax, %%dx":: "a" (data), "d" (port));
}
uint32_t port_long_in(uint16_t port) {
uint32_t result;
asm("inl %%dx, %%eax":"=a"(result):"d"(port));
return result;
}
void port_long_out(uint16_t port,uint32_t data) {
asm("outl %%eax, %%dx":: "a" (data), "d" (port));
}

12
cpu/x86_64/ports.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef PORTS_H
#define PORTS_H
#include <stdint.h>
uint8_t port_byte_in(uint16_t port);
void port_byte_out(uint16_t port,uint8_t data);
uint16_t port_word_in(uint16_t port);
void port_word_out(uint16_t port,uint16_t data);
uint32_t port_long_in(uint16_t port);
void port_long_out(uint16_t port,uint32_t data);
#endif

View File

@ -1,6 +1,6 @@
timeout=0
menuentry "My OS" {
multiboot /boot/kernel.elf
multiboot2 /boot/kernel.elf
boot
}

View File

@ -1,164 +1,157 @@
#include "../cpu/cpu_init.h"
#include "../drivers/vga.h"
#include "../drivers/pci.h"
#include "../drivers/serial.h"
#include "../cpu/i386/ports.h"
#include "vfs.h"
#include "../fs/devfs.h"
#include "../fs/initrd.h"`
#include <grub/text_fb_info.h>
#include <stdlib.h>
#include <tasking.h>
#include <string.h>
#include <memory.h>
// #include "../cpu/cpu_init.h"
// #include "../drivers/vga.h"
// #include "../drivers/pci.h"
// #include "../drivers/serial.h"
// #include "../cpu/i386/ports.h"
// #include "vfs.h"
// #include "../fs/devfs.h"
// #include "../fs/initrd.h"
// #include <grub/text_fb_info.h>
// #include <stdlib.h>
// #include <tasking.h>
// #include <string.h>
// #include <memory.h>
#include <grub/multiboot.h>
#include "klog.h"
#include "elf.h"
#include <errno.h>
#include "../drivers/ide.h"
#include "parts.h"
#include "../fs/ext2.h"
#include <stdint.h>
static long initrd_sz;
static char* initrd;
static multiboot_info_t* mbd;
typedef int (*func_ptr)();
static int console_dev_drv(char* filename,int c,long pos,char wr) {
if (wr) {
if (c=='\f') {
vga_clear();
} else if (c=='\b') {
vga_backspace();
}
char str[2];
str[0]=(char)c;
str[1]='\0';
vga_write_string(str);
return 0;
} else {
return 0;
// return devbuf_get(kbd_buf);
}
}
static int initrd_dev_drv(char* filename,int c,long pos,char wr) {
if (wr) {
return 0;
}
if (pos>=initrd_sz) {
return EOF;
}
return initrd[pos];
}
static void read_initrd(multiboot_info_t* mbd) {
if ((mbd->flags&MULTIBOOT_INFO_MODS)!=0) {
uint32_t mods_count=mbd->mods_count;
if (mods_count>0) {
while (mods_count>0) {
multiboot_module_t* mods_addr=(multiboot_module_t*)(mbd->mods_addr+0xC0000000);
if (strcmp((char*)(mods_addr->cmdline+0xC0000000),"initrd")==0) {
initrd=malloc(sizeof(char)*(mods_addr->mod_end-mods_addr->mod_start));
initrd_sz=(mods_addr->mod_end-mods_addr->mod_start);
memcpy(initrd,(void*)mods_addr->mod_start+0xC0000000,initrd_sz);
};
mods_count--;
}
}
} else {
klog("PANIC","Cannnot load initrd. No modules found!");
for(;;) {}
}
if (!initrd) {
klog("PANIC","Cannnot load initrd. Initrd module not found!");
for(;;) {}
}
}
static void init() {
init_vfs();
init_devfs();
devfs_add(console_dev_drv,"console");
stdout=fopen("/dev/console","w");
stdin=fopen("/dev/console","r");
stderr=fopen("/dev/console","w");
read_initrd(mbd);
devfs_add(initrd_dev_drv,"initrd");
initrd_init();
mount("/initrd/","","initrd");
// Detect PCI
port_long_out(0xCF8,(1<<31));
uint32_t word=port_long_in(0xCFC);
port_long_out(0xCF8,(1<<31)|0x4);
if (word!=port_long_in(0xCFC)) {
// pci_init();
}
// Detect and initailize serial ports
serial_init();
FILE* file=fopen("/initrd/prog.elf","r");
elf_header header;
fread(&header,sizeof(elf_header),1,file);
if (header.magic!=ELF_MAGIC) {
klog("INFO","Invalid magic number for prog.elf");
fclose(file);
} else {
fseek(file,header.prog_hdr,SEEK_SET);
elf_pheader pheader;
fread(&pheader,sizeof(elf_pheader),1,file);
alloc_memory_virt(1,(void*)pheader.vaddr);
fseek(file,pheader.offset,SEEK_SET);
fread((void*)pheader.vaddr,pheader.filesz,1,file);
klog("INFO","VADDR:%x",pheader.vaddr);
func_ptr prog=(func_ptr)header.entry;
int val=prog();
klog("INFO","RAN PROG:%d",val);
}
ide_init();
load_parts("/dev/hda");
init_ext2();
mount("/","/dev/hda1","ext2");
klog("INFO","MOUNT");
FILE* f=fopen("/file","r");
char str[256];
fgets(str,256,f);
str[strlen(str)-1]='\0';
klog("INFO","Got string %s",str);
for(;;) {
yield();
}
}
void func() {
for (;;);
}
// #include "klog.h"
// #include "elf.h"
// #include <errno.h>
// #include "../drivers/ide.h"
// #include "parts.h"
// #include "../fs/ext2.h"
// #include <stdint.h>
//
// static long initrd_sz;
// static char* initrd;
// static multiboot_info_t* mbd;
// typedef int (*func_ptr)();
//
// static int console_dev_drv(char* filename,int c,long pos,char wr) {
// if (wr) {
// if (c=='\f') {
// vga_clear();
// } else if (c=='\b') {
// vga_backspace();
// }
// char str[2];
// str[0]=(char)c;
// str[1]='\0';
// vga_write_string(str);
// return 0;
// } else {
// return 0;
// // return devbuf_get(kbd_buf);
// }
// }
//
// static int initrd_dev_drv(char* filename,int c,long pos,char wr) {
// if (wr) {
// return 0;
// }
// if (pos>=initrd_sz) {
// return EOF;
// }
// return initrd[pos];
// }
//
// static void read_initrd(multiboot_info_t* mbd) {
// if ((mbd->flags&MULTIBOOT_INFO_MODS)!=0) {
// uint32_t mods_count=mbd->mods_count;
// if (mods_count>0) {
// while (mods_count>0) {
// multiboot_module_t* mods_addr=(multiboot_module_t*)(mbd->mods_addr+0xC0000000);
// if (strcmp((char*)(mods_addr->cmdline+0xC0000000),"initrd")==0) {
// initrd=malloc(sizeof(char)*(mods_addr->mod_end-mods_addr->mod_start));
// initrd_sz=(mods_addr->mod_end-mods_addr->mod_start);
// memcpy(initrd,(void*)mods_addr->mod_start+0xC0000000,initrd_sz);
// };
// mods_count--;
// }
// }
// } else {
// klog("PANIC","Cannnot load initrd. No modules found!");
// for(;;) {}
// }
// if (!initrd) {
// klog("PANIC","Cannnot load initrd. Initrd module not found!");
// for(;;) {}
// }
// }
//
// static void init() {
// init_vfs();
// init_devfs();
// devfs_add(console_dev_drv,"console");
// stdout=fopen("/dev/console","w");
// stdin=fopen("/dev/console","r");
// stderr=fopen("/dev/console","w");
// // read_initrd(mbd);
// // devfs_add(initrd_dev_drv,"initrd");
// // initrd_init();
// mount("/initrd/","","initrd");
// // Detect PCI
// port_long_out(0xCF8,(1<<31));
// uint32_t word=port_long_in(0xCFC);
// port_long_out(0xCF8,(1<<31)|0x4);
// if (word!=port_long_in(0xCFC)) {
// // pci_init();
// }
// // Detect and initailize serial ports
// serial_init();
// FILE* file=fopen("/initrd/prog.elf","r");
// elf_header header;
// fread(&header,sizeof(elf_header),1,file);
// if (header.magic!=ELF_MAGIC) {
// klog("INFO","Invalid magic number for prog.elf");
// fclose(file);
// } else {
// fseek(file,header.prog_hdr,SEEK_SET);
// elf_pheader pheader;
// fread(&pheader,sizeof(elf_pheader),1,file);
// alloc_memory_virt(1,(void*)pheader.vaddr);
// fseek(file,pheader.offset,SEEK_SET);
// fread((void*)pheader.vaddr,pheader.filesz,1,file);
// klog("INFO","VADDR:%x",pheader.vaddr);
// func_ptr prog=(func_ptr)header.entry;
// int val=prog();
// klog("INFO","RAN PROG:%d",val);
// }
// ide_init();
// load_parts("/dev/hda");
// init_ext2();
// mount("/","/dev/hda1","ext2");
// klog("INFO","MOUNT");
// FILE* f=fopen("/file","r");
// char str[256];
// fgets(str,256,f);
// str[strlen(str)-1]='\0';
// klog("INFO","Got string %s",str);
// for(;;) {
// yield();
// }
// }
//
//
// void func() {
// for (;;);
// }
void kmain(multiboot_info_t* header) {
void (*ptr)()=((uint64_t)func)+0x800000000000;
ptr();
mbd=header;
cpu_init(mbd);
text_fb_info info;
if (header->flags&MULTIBOOT_INFO_FRAMEBUFFER_INFO&&header->framebuffer_type==2) {
info.address=(char*)(((uint32_t)header->framebuffer_addr&0xFFFFFFFF)+0xC0000000);
info.width=header->framebuffer_width;
info.height=header->framebuffer_height;
} else {
info.address=(char*)0xB8000;
info.address=(char*)0xffff8000000B8000;
info.width=80;
info.height=25;
}
vga_init(info);
vga_write_string("OKAY\n");
createTask(init);
for (;;) {
yield();
}
static char* screen=(char*)0xB8000;
screen[0]='O';
screen[1]=0x2f;
// mbd=header;
// cpu_init(mbd);
// text_fb_info info;
// if (header->flags&MULTIBOOT_INFO_FRAMEBUFFER_INFO&&header->framebuffer_type==2) {
// info.address=(char*)(((uint32_t)header->framebuffer_addr&0xFFFFFFFF)+0xC0000000);
// info.width=header->framebuffer_width;
// info.height=header->framebuffer_height;
// } else {
// info.address=(char*)0xB8000;
// info.width=80;
// info.height=25;
// }
// vga_init(info);
// createTask(init);
// for (;;) {
// yield();
// }
for(;;);
}

216
out Normal file
View File

@ -0,0 +1,216 @@
iso/boot/kernel.elf: file format elf64-x86-64
iso/boot/kernel.elf
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000101000
Program Header:
LOAD off 0x0000000000001000 vaddr 0x0000000000100000 paddr 0x0000000000100000 align 2**12
filesz 0x000000000000a000 memsz 0x000000000000a000 flags r--
LOAD off 0x000000000000b000 vaddr 0xffff80000010a000 paddr 0x000000000010a000 align 2**5
filesz 0x0000000000006bc0 memsz 0x000000000000b0f0 flags rwx
Sections:
Idx Name Size VMA LMA File off Algn
0 .multiboot 00000018 0000000000100000 0000000000100000 00001000 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .boottext 00000126 0000000000101000 0000000000101000 00002000 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .bootrodata 00000022 0000000000102000 0000000000102000 00003000 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .bootbss 00007000 0000000000103000 0000000000103000 00004000 2**12
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .text 00005754 ffff80000010a000 000000000010a000 0000b000 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
5 .rodata 0000013c ffff800000110000 0000000000110000 00011000 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .eh_frame 00000a80 ffff800000110140 0000000000110140 00011140 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .bss 000040f0 ffff800000111000 0000000000111000 00011bc0 2**5
ALLOC
8 .debug_info 000050a7 0000000000000000 0000000000000000 00011bc0 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_abbrev 0000100f 0000000000000000 0000000000000000 00016c67 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_aranges 00000270 0000000000000000 0000000000000000 00017c76 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_line 00002229 0000000000000000 0000000000000000 00017ee6 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_str 000010f9 0000000000000000 0000000000000000 0001a10f 2**0
CONTENTS, READONLY, DEBUGGING
13 .comment 00000011 0000000000000000 0000000000000000 0001b208 2**0
CONTENTS, READONLY
14 .debug_ranges 000001e0 0000000000000000 0000000000000000 0001b219 2**0
CONTENTS, READONLY, DEBUGGING
SYMBOL TABLE:
0000000000100000 l d .multiboot 0000000000000000 .multiboot
0000000000101000 l d .boottext 0000000000000000 .boottext
0000000000102000 l d .bootrodata 0000000000000000 .bootrodata
0000000000103000 l d .bootbss 0000000000000000 .bootbss
ffff80000010a000 l d .text 0000000000000000 .text
ffff800000110000 l d .rodata 0000000000000000 .rodata
ffff800000110140 l d .eh_frame 0000000000000000 .eh_frame
ffff800000111000 l d .bss 0000000000000000 .bss
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l d .debug_ranges 0000000000000000 .debug_ranges
0000000000000000 l df *ABS* 0000000000000000 cpu/x86_64/boot.asm
0000000000100000 l .multiboot 0000000000000000 header_start
0000000000100018 l .multiboot 0000000000000000 header_end
0000000000101037 l .boottext 0000000000000000 check_multiboot
000000000010103f l .boottext 0000000000000000 check_multiboot.no_multiboot
0000000000101046 l .boottext 0000000000000000 check_cpuid
000000000010105a l .boottext 0000000000000000 check_cpuid.no_cpuid
0000000000101061 l .boottext 0000000000000000 check_long_mode
000000000010107f l .boottext 0000000000000000 check_long_mode.no_long_mode
0000000000101083 l .boottext 0000000000000000 set_up_page_tables
00000000001010af l .boottext 0000000000000000 set_up_page_tables.map_p2_table
00000000001010c9 l .boottext 0000000000000000 enable_paging
00000000001010f4 l .boottext 0000000000000000 error
0000000000103000 l .bootbss 0000000000000000 p4_table
0000000000104000 l .bootbss 0000000000000000 p3_table
0000000000105000 l .bootbss 0000000000000000 p2_table
0000000000106000 l .bootbss 0000000000000000 stack_bottom
000000000010a000 l .bootbss 0000000000000000 stack_top
0000000000102000 l .bootrodata 0000000000000000 gdt64
0000000000102018 l .bootrodata 0000000000000000 gdt64.pointer
0000000000000000 l df *ABS* 0000000000000000 cpu/x86_64/long_start.asm
0000000000101124 l .boottext 0000000000000000 loop
0000000000000000 l df *ABS* 0000000000000000 kernel.c
0000000000000000 l df *ABS* 0000000000000000 parts.c
ffff800000111000 l O .bss 0000000000000008 part_devs
ffff800000111008 l O .bss 0000000000000008 parts
ffff800000111010 l O .bss 0000000000000004 num_part_devs
ffff800000111014 l O .bss 0000000000000004 max_part_devs
0000000000000000 l df *ABS* 0000000000000000 vfs.c
ffff800000111030 l O .bss 0000000000000008 drv_names
ffff800000111038 l O .bss 0000000000000008 drvs
ffff800000111040 l O .bss 0000000000000004 max_drvs
ffff800000111044 l O .bss 0000000000000004 next_drv_indx
ffff800000111048 l O .bss 0000000000000008 head_mapping
ffff800000111050 l O .bss 0000000000000008 tail_mapping
ffff80000010a786 l F .text 000000000000009f vfsstrcmp
0000000000000000 l df *ABS* 0000000000000000 ports.c
0000000000000000 l df *ABS* 0000000000000000 devfs.c
ffff800000111058 l O .bss 0000000000000008 devices
ffff800000111060 l O .bss 0000000000000008 dev_drivers
ffff800000111068 l O .bss 0000000000000004 num_devices
ffff80000011106c l O .bss 0000000000000004 max_devices
0000000000000000 l df *ABS* 0000000000000000 ext2.c
ffff80000010bd3e l F .text 0000000000000048 get_bmap_bit
ffff80000010bd86 l F .text 000000000000004f set_bmap_bit
ffff80000010d460 l F .text 0000000000000da2 drv
0000000000000000 l df *ABS* 0000000000000000 initrd.c
ffff800000111070 l O .bss 0000000000000008 names
ffff800000111078 l O .bss 0000000000000008 offsets
ffff800000111080 l O .bss 0000000000000008 sizes
ffff800000111088 l O .bss 0000000000000004 num_files
ffff800000111090 l O .bss 0000000000000008 initrd_fd
ffff80000010e30f l F .text 00000000000001dd drv
0000000000000000 l df *ABS* 0000000000000000 errno.c
0000000000000000 l df *ABS* 0000000000000000 klog.c
0000000000000000 l df *ABS* 0000000000000000 math.c
0000000000000000 l df *ABS* 0000000000000000 stdlib.c
ffff8000001110a0 l O .bss 0000000000004000 entries
ffff8000001150a0 l O .bss 0000000000000004 num_used_entries
ffff80000010ea06 l F .text 0000000000000048 get_bmap_bit
ffff80000010ea4e l F .text 000000000000004d set_bmap_bit
ffff80000010ea9b l F .text 000000000000004d clear_bmap_bit
ffff80000010eae8 l F .text 00000000000001e9 reserve_block
0000000000000000 l df *ABS* 0000000000000000 string.c
ffff8000001150a8 l O .bss 0000000000000008 strtok_str
ffff8000001150b0 l O .bss 0000000000000008 strtok_index
ffff80000010f4ef l F .text 0000000000000098 strtok_delim_check
0000000000000000 l df *ABS* 0000000000000000 memory.c
ffff80000010f1a1 g F .text 0000000000000067 strcpy
ffff80000010b65b g F .text 00000000000000e1 printf
ffff800000111020 g O .bss 0000000000000008 stdout
ffff80000010bf35 g F .text 000000000000027c read_inode
ffff80000010c848 g F .text 0000000000000065 set_sz
ffff80000010b899 g F .text 0000000000000018 port_long_out
ffff80000010e9cb g F .text 000000000000003b ceil
ffff80000010e202 g F .text 000000000000010d init_ext2
ffff8000001150b8 g O .bss 0000000000000008 supblks
ffff80000010d2f3 g F .text 00000000000000bd inode_for_fname
ffff8000001150c0 g O .bss 0000000000000008 blk_grps
ffff80000010aeaf g F .text 00000000000000cd fgets
ffff80000010ae8d g F .text 0000000000000022 getc
ffff80000010f04e g F .text 000000000000005a memcpy
ffff80000010c1b1 g F .text 000000000000033a write_inode
ffff80000010d219 g F .text 000000000000000b free_dir_listing
ffff80000010b1a2 g F .text 0000000000000031 puts
ffff80000010c921 g F .text 0000000000000184 read_char
ffff80000010b7ee g F .text 0000000000000011 feof
ffff80000010caa5 g F .text 000000000000014c append_char
ffff80000010ecd1 g F .text 000000000000024d malloc
ffff80000010a8b0 g F .text 0000000000000159 register_fs
ffff80000010f208 g F .text 0000000000000089 strrev
ffff80000010bdd5 g F .text 00000000000000c8 read_blk
ffff80000010b8b1 g F .text 000000000000022b devfs_drv
ffff8000001150c8 g O .bss 0000000000000008 blk_grp_num
ffff80000010a825 g F .text 000000000000008b init_vfs
ffff80000010c7f3 g F .text 0000000000000055 get_sz
ffff80000010a339 g F .text 000000000000044d load_parts
ffff80000010bb8f g F .text 00000000000001af devfs_add
ffff8000001150d0 g O .bss 0000000000000004 max_mnts
ffff80000010b580 g F .text 00000000000000db fprintf
ffff80000010c8ad g F .text 0000000000000074 inc_sz
ffff80000010b73c g F .text 0000000000000045 fseek
ffff80000010f70f g F .text 0000000000000022 alloc_memory
ffff800000111018 g O .bss 0000000000000008 stdin
ffff8000001150d4 g O .bss 0000000000000004 num_mnts
ffff80000010b7ff g F .text 0000000000000011 ferror
ffff80000010be9d g F .text 0000000000000098 write_blk
ffff80000010b880 g F .text 0000000000000019 port_long_in
ffff80000010f731 g F .text 0000000000000023 alloc_memory_virt
ffff8000001150d8 g O .bss 0000000000000008 devs
ffff80000010ef1e g F .text 0000000000000081 realloc
ffff80000010f587 g F .text 0000000000000188 strtok
ffff80000010badc g F .text 00000000000000b3 init_devfs
ffff80000010f291 g F .text 00000000000000c7 int_to_ascii
ffff80000010af7c g F .text 00000000000000bb fread
ffff80000010ac05 g F .text 000000000000020f fopen
ffff80000010f0a8 g F .text 0000000000000046 memset
ffff80000010b781 g F .text 0000000000000012 ftell
ffff80000010b793 g F .text 000000000000005b fclose
ffff80000010b810 g F .text 000000000000001a port_byte_in
ffff80000010b863 g F .text 000000000000001d port_word_out
ffff80000010d037 g F .text 00000000000001e2 get_dir_listing
ffff80000010b0c3 g F .text 000000000000002e putc
ffff80000010aa09 g F .text 00000000000001fc mount
ffff80000010f0ee g F .text 0000000000000084 strcmp
ffff80000010e4ec g F .text 0000000000000380 initrd_init
ffff80000010d3b0 g F .text 00000000000000b0 fname_for_inode
ffff80000010ae14 g F .text 0000000000000079 fgetc
ffff800000111028 g O .bss 0000000000000008 stderr
ffff80000010b82a g F .text 000000000000001d port_byte_out
ffff80000010b037 g F .text 000000000000008c fputc
ffff80000010e992 g F .text 0000000000000039 ceilf
ffff80000010b1d3 g F .text 00000000000000be fwrite
ffff80000010b847 g F .text 000000000000001c port_word_in
ffff80000010cd76 g F .text 00000000000002c1 read_inode_contents
ffff80000010f467 g F .text 0000000000000050 append
0000000000101118 g .boottext 0000000000000000 long_mode_start
0000000000101000 g .boottext 0000000000000000 start
ffff80000010a00a g F .text 000000000000032f drv
ffff8000001150e0 g O .bss 0000000000000008 blk_size
ffff80000010a000 g F .text 000000000000000a kmain
ffff80000010f358 g F .text 000000000000010f hex_to_ascii
ffff80000010f172 g F .text 000000000000002f strlen
ffff80000010f4b7 g F .text 0000000000000038 backspace
ffff8000001150e8 g O .bss 0000000000000008 mnts
ffff80000010cbf1 g F .text 0000000000000185 write_char
ffff80000010b0f1 g F .text 00000000000000b1 fputs
ffff80000010c4eb g F .text 0000000000000308 reserve_inode
ffff80000010e86c g F .text 000000000000001a __get_errno_address
ffff80000010e886 g F .text 000000000000010c klog
ffff80000010b291 g F .text 00000000000002ef vfprintf
ffff80000010ef9f g F .text 00000000000000af free
ffff80000010d224 g F .text 00000000000000cf read_dir_entry