Start work on an initrd driver and attempt to debug pg fault on msg send

This commit is contained in:
pjht 2019-10-20 09:44:33 -05:00
parent 86bdf24671
commit 1c5a986e6d
13 changed files with 313 additions and 23 deletions

View File

@ -30,7 +30,7 @@ debug: os.iso kernel/kernel.elf
@$(GDB) @$(GDB)
#gdbgui -g i386-elf-gdb --project $(CWD) #gdbgui -g i386-elf-gdb --project $(CWD)
os.iso: kernel/kernel.elf init vfs devfs initrd vga_drv pci os.iso: kernel/kernel.elf init vfs devfs initrd vga_drv initrd_drv pci
@cp kernel/kernel.elf sysroot/boot @cp kernel/kernel.elf sysroot/boot
@cd initrd; tar -f ../sysroot/boot/initrd.tar -c * @cd initrd; tar -f ../sysroot/boot/initrd.tar -c *
@grub-mkrescue -o $@ sysroot >/dev/null 2>/dev/null @grub-mkrescue -o $@ sysroot >/dev/null 2>/dev/null
@ -58,6 +58,10 @@ vga_drv: crts libc
@cd $@ && make @cd $@ && make
@cp $@/$@ initrd/$@ @cp $@/$@ initrd/$@
initrd_drv: crts libc
@cd $@ && make
@cp $@/$@ initrd/$@
kernel/kernel.elf: $(OBJ) $(ASM_OBJ) $(S_ASM_OBJ) sysroot/usr/lib/libc.a kernel/kernel.elf: $(OBJ) $(ASM_OBJ) $(S_ASM_OBJ) sysroot/usr/lib/libc.a
@$(CC) -z max-page-size=4096 -Xlinker -n -T kernel/cpu/$(PLAT)/linker.ld -o $@ $(CFLAGS) -nostdlib $^ -lgcc @$(CC) -z max-page-size=4096 -Xlinker -n -T kernel/cpu/$(PLAT)/linker.ld -o $@ $(CFLAGS) -nostdlib $^ -lgcc

View File

@ -77,6 +77,7 @@ char devfs_puts(vfs_message* vfs_msg) {
msg.size=vfs_msg->data; msg.size=vfs_msg->data;
msg.msg=data; msg.msg=data;
mailbox_send_msg(&msg); mailbox_send_msg(&msg);
free(data);
return 0; return 0;
} }
@ -92,18 +93,36 @@ char devfs_gets(vfs_message* vfs_msg) {
} }
char* devfs_gets_finish(vfs_message* vfs_msg) { char* devfs_gets_finish(vfs_message* vfs_msg) {
char str[256];
int_to_ascii(vfs_msg->data,str);
serial_print("gets_finish: Driver wants ");
serial_print(str);
serial_print(" bytes of gets data\n");
if (vfs_msg->flags) { if (vfs_msg->flags) {
return NULL; return NULL;
} }
char* gets_data=malloc(sizeof(vfs_msg->data)); char* gets_data=malloc(sizeof(vfs_msg->data));
Message msg; Message msg;
msg.msg=gets_data; msg.msg=gets_data;
mailbox_get_msg(devfs_drv_box,&msg,vfs_msg->data); int_to_ascii(vfs_msg->data,str);
while (msg.from==0 && msg.size==0) { serial_print("gets_finish: Driver now wants ");
yield(); serial_print(str);
mailbox_get_msg(devfs_drv_box,&msg,sizeof(vfs_message)); serial_print(" bytes of gets data\n");
} mailbox_get_msg(devfs_drv_box,&msg,(uint32_t)vfs_msg->data);
// while (msg.from==0 && msg.size==0) {
// serial_print("Yielding to wait for data msg\n");
// yield();
// mailbox_get_msg(devfs_drv_box,&msg,(uint32_t)vfs_msg->data);
// }
int_to_ascii(vfs_msg->data,str);
serial_print("gets_finish: Again, driver now wants ");
serial_print(str);
serial_print(" bytes of gets data\n");
vfs_msg->flags=0; vfs_msg->flags=0;
int_to_ascii(vfs_msg->data,str);
serial_print("gets_finish: Sending ");
serial_print(str);
serial_print(" bytes of gets data\n");
return gets_data; return gets_data;
} }
@ -127,8 +146,18 @@ char devfs_mount(vfs_message* vfs_msg) {
} }
void process_vfs_msg(vfs_message* vfs_msg, uint32_t from) { void process_vfs_msg(vfs_message* vfs_msg, uint32_t from) {
if (vfs_msg->in_progress&2) { char str[256];
int_to_ascii(vfs_msg->data,str);
serial_print("vfs_msg->data=");
serial_print(str);
serial_print("\n");
if (from!=vfs_box) {
if (vfs_msg->flags) { if (vfs_msg->flags) {
serial_print("vfs_msg->flags=");
char str[256];
int_to_ascii(vfs_msg->flags,str);
serial_print(str);
serial_print("\n");
if (vfs_msg->type==VFS_OPEN) { if (vfs_msg->type==VFS_OPEN) {
free((void*)vfs_msg->data); free((void*)vfs_msg->data);
} }
@ -148,7 +177,13 @@ void process_vfs_msg(vfs_message* vfs_msg, uint32_t from) {
vfs_msg->flags=0; vfs_msg->flags=0;
break; break;
case VFS_GETS: case VFS_GETS:
int_to_ascii(vfs_msg->data,str);
serial_print("process_vfs_msg: Driver sending ");
serial_print(str);
serial_print(" bytes of gets data\n");
serial_print("GETS_FINISH\n");
gets_data=devfs_gets_finish(vfs_msg); gets_data=devfs_gets_finish(vfs_msg);
serial_print("GETS_FINISH DONE\n");
break; break;
case VFS_MOUNT: case VFS_MOUNT:
vfs_msg->flags=0; vfs_msg->flags=0;
@ -163,27 +198,42 @@ void process_vfs_msg(vfs_message* vfs_msg, uint32_t from) {
msg.msg=vfs_msg; msg.msg=vfs_msg;
mailbox_send_msg(&msg); mailbox_send_msg(&msg);
if (gets_data) { if (gets_data) {
serial_print("Gets data\n");
char str[256];
int_to_ascii(vfs_msg->data,str);
serial_print("Sending ");
serial_print(str);
serial_print(" bytes of gets data\n");
msg.size=vfs_msg->data; msg.size=vfs_msg->data;
msg.msg=gets_data; msg.msg=gets_data;
mailbox_send_msg(&msg); mailbox_send_msg(&msg);
free(gets_data);
} else {
serial_print("No gets data\n");
} }
} }
} else { } else {
char send_msg; char send_msg;
vfs_msg->in_progress=vfs_msg->in_progress|2;
switch (vfs_msg->type) { switch (vfs_msg->type) {
case VFS_OPEN: case VFS_OPEN:
serial_print("OPEN\n");
send_msg=devfs_open(vfs_msg); send_msg=devfs_open(vfs_msg);
serial_print("OPEN DONE\n");
break; break;
case VFS_PUTS: case VFS_PUTS:
serial_print("PUTS\n");
send_msg=devfs_puts(vfs_msg); send_msg=devfs_puts(vfs_msg);
serial_print("PUTS DONE\n");
break; break;
case VFS_GETS: case VFS_GETS:
serial_print("GETS\n");
send_msg=devfs_gets(vfs_msg); send_msg=devfs_gets(vfs_msg);
serial_print("GETS DONE\n");
break; break;
case VFS_MOUNT: case VFS_MOUNT:
serial_print("Mount\n"); serial_print("MOUNT\n");
send_msg=devfs_mount(vfs_msg); send_msg=devfs_mount(vfs_msg);
serial_print("MOUNT DONE\n");
break; break;
default: default:
vfs_msg->flags=1; vfs_msg->flags=1;
@ -223,6 +273,7 @@ int main() {
} else { } else {
vfs_message* vfs_msg=(vfs_message*)msg.msg; vfs_message* vfs_msg=(vfs_message*)msg.msg;
process_vfs_msg(vfs_msg,msg.from); process_vfs_msg(vfs_msg,msg.from);
free(msg.msg);
} }
mailbox_get_msg(devfs_drv_box,&msg,sizeof(vfs_message)); mailbox_get_msg(devfs_drv_box,&msg,sizeof(vfs_message));
if (msg.from==0) { if (msg.from==0) {
@ -230,10 +281,13 @@ int main() {
} else { } else {
vfs_message* vfs_msg=(vfs_message*)msg.msg; vfs_message* vfs_msg=(vfs_message*)msg.msg;
process_vfs_msg(vfs_msg,msg.from); process_vfs_msg(vfs_msg,msg.from);
free(msg.msg);
} }
msg.msg=malloc(sizeof(devfs_message)); msg.msg=malloc(sizeof(devfs_message));
mailbox_get_msg(devfs_reg_box,&msg,sizeof(devfs_message)); mailbox_get_msg(devfs_reg_box,&msg,sizeof(devfs_message));
if (msg.from!=0) { if (msg.from==0) {
free(msg.msg);
} else {
devfs_message* devfs_msg=(devfs_message*)msg.msg; devfs_message* devfs_msg=(devfs_message*)msg.msg;
if (num_devs==max_devs) { if (num_devs==max_devs) {
max_devs+=32; max_devs+=32;
@ -246,8 +300,8 @@ int main() {
dev_mboxes[num_devs]=devfs_msg->mbox; dev_mboxes[num_devs]=devfs_msg->mbox;
dev_types[num_devs]=devfs_msg->dev_type; dev_types[num_devs]=devfs_msg->dev_type;
num_devs++; num_devs++;
free(msg.msg);
} }
free(msg.msg);
yield(); yield();
} }
} }

View File

@ -59,6 +59,11 @@ char load_task(uint32_t datapos,char* initrd) {
int pos=0; int pos=0;
elf_header header; elf_header header;
pos=datapos; pos=datapos;
char str[256];
int_to_ascii(pos,str);
serial_print("POS:");
serial_print(str);
serial_print("\n");
char* hdr_ptr=(char*)&header; char* hdr_ptr=(char*)&header;
for (size_t i=0;i<sizeof(elf_header);i++) { for (size_t i=0;i<sizeof(elf_header);i++) {
hdr_ptr[i]=initrd[pos]; hdr_ptr[i]=initrd[pos];
@ -92,6 +97,35 @@ char load_task(uint32_t datapos,char* initrd) {
return 1; return 1;
} }
char load_task_devfs(uint32_t datapos) {
serial_print("load_task_devfs\n");
FILE* initrd=fopen("/dev/initrd","r");
elf_header header;
fseek(initrd,datapos,SEEK_SET);
fread(&header,sizeof(elf_header),1,initrd);
if (header.magic!=ELF_MAGIC) {
serial_print("Bad magic number\n");
return 0;
} else {
void* cr3=new_address_space();
for (int i=0;i<header.pheader_ent_nm;i++) {
elf_pheader pheader;
fseek(initrd,(header.prog_hdr)+(header.pheader_ent_sz*i)+datapos,SEEK_SET);
fread(&pheader,sizeof(elf_pheader),1,initrd);
char* ptr=alloc_memory(((pheader.memsz)/4096)+1);
memset(ptr,0,pheader.memsz);
if (pheader.filesz>0) {
fseek(initrd,pheader.offset+datapos,SEEK_SET);
fread(ptr,sizeof(char),pheader.memsz,initrd);
}
copy_data(cr3,ptr,pheader.memsz,(void*)pheader.vaddr);
}
createTaskCr3((void*)header.entry,cr3);
}
return 1;
}
int main() { int main() {
long size=initrd_sz(); long size=initrd_sz();
char* initrd=malloc(size); char* initrd=malloc(size);
@ -103,10 +137,15 @@ int main() {
datapos=find_loc("devfs",initrd); datapos=find_loc("devfs",initrd);
load_task(datapos,initrd); load_task(datapos,initrd);
yieldToPID(3); yieldToPID(3);
datapos=find_loc("vga_drv",initrd); datapos=find_loc("initrd_drv",initrd);
load_task(datapos,initrd); load_task(datapos,initrd);
yieldToPID(4); yieldToPID(4);
mount("","devfs","/dev/"); mount("","devfs","/dev/");
datapos=find_loc("vga_drv",initrd);
serial_print("Making vga task\n");
load_task_devfs(datapos);
serial_print("Made vga task\n");
yieldToPID(5);
FILE* file; FILE* file;
do { do {
file=fopen("/dev/vga","w"); file=fopen("/dev/vga","w");

View File

@ -0,0 +1,13 @@
C_SOURCES = $(wildcard *.c)
OBJ = $(C_SOURCES:.c=.o )
CFLAGS = -Wall -g
CC = i386-myos-gcc
initrd_drv: $(OBJ) ../libc/*
@$(CC) -o $@ $(CFLAGS) $(OBJ)
%.o: %.c
@$(CC) $(CFLAGS) -c $< -o $@
clean:
@rm -rf *.o initrd_drv

BIN
initrd_drv/initrd_drv Executable file

Binary file not shown.

147
initrd_drv/main.c Normal file
View File

@ -0,0 +1,147 @@
#include <tasking.h>
#include <stdlib.h>
#include <mailboxes.h>
#include <ipc/vfs.h>
#include <memory.h>
#include <grub/text_fb_info.h>
#include <vfs.h>
#include <ipc/devfs.h>
#include <string.h>
#include <dbg.h>
#include <initrd.h>
#define VFS_PID 2
#define DEVFS_PID 3
uint32_t box;
char* initrd;
long size;
void initrd_puts(vfs_message* vfs_msg) {
char* data=malloc(sizeof(char)*vfs_msg->data);
Message msg;
msg.msg=data;
mailbox_get_msg(box,&msg,vfs_msg->data);
while (msg.from==0 && msg.size==0) {
yield();
mailbox_get_msg(box,&msg,sizeof(vfs_message));
}
if (msg.from==0) {
serial_print("Could not recieve fputs data from the VFS\n");
vfs_msg->flags=2;
return;
}
free(data);
vfs_msg->flags=2;
return;
}
char* initrd_gets(vfs_message* vfs_msg) {
char str[256];
serial_print("File pos initrd:");
int_to_ascii(vfs_msg->pos,str);
serial_print(str);
serial_print("\n");
long max_data=size-vfs_msg->pos;
serial_print("max_data=");
int_to_ascii(max_data,str);
serial_print(str);
serial_print("\n");
serial_print("Amount requested:");
int_to_ascii(vfs_msg->data,str);
serial_print(str);
serial_print("\n");
if (vfs_msg->data>max_data) {
serial_print("OVER\n");
vfs_msg->flags=2;
return NULL;
}
char* data=malloc(sizeof(char)*vfs_msg->data);
for (long i=0;i<vfs_msg->data;i++) {
data[i]=(uint8_t)initrd[i+vfs_msg->pos];
// if (i<sizeof(vfs_message)) {
// serial_print("data[");
// char str[256];
// int_to_ascii(i,str);
// serial_print(str);
// serial_print("]=");
// hex_to_ascii((uint8_t)data[i],str);
// serial_print(str);
// serial_print("\n");
// }
}
vfs_msg->flags=0;
return data;
}
void process_vfs_msg(vfs_message* vfs_msg, uint32_t from) {
char* gets_data;
switch (vfs_msg->type) {
case VFS_PUTS:
initrd_puts(vfs_msg);
break;
case VFS_GETS:
gets_data=initrd_gets(vfs_msg);
break;
break;
default:
vfs_msg->flags=1;
}
Message msg;
msg.to=from;
msg.from=box;
msg.size=sizeof(vfs_message);
msg.msg=vfs_msg;
serial_print("Sending message with flags of ");
char str[256];
int_to_ascii(vfs_msg->flags,str);
serial_print(str);
serial_print("\n");
mailbox_send_msg(&msg);
if (gets_data) {
serial_print("Amount sending:");
char str[256];
int_to_ascii(vfs_msg->data,str);
serial_print(str);
serial_print("\n");
msg.size=vfs_msg->data;
msg.msg=gets_data;
mailbox_send_msg(&msg);
free(gets_data);
}
}
int main() {
size=initrd_sz();
initrd=malloc(size);
initrd_get(initrd);
box=mailbox_new(16,"initrd");
devfs_message* msg_data=malloc(sizeof(devfs_message));
msg_data->msg_type=DEVFS_REGISTER;
msg_data->dev_type=DEV_GLOBAL;
msg_data->mbox=box;
strcpy(&msg_data->name[0],"initrd");
Message msg;
msg.from=box;
msg.to=mailbox_find_by_name("devfs_register");
msg.size=sizeof(devfs_message);
msg.msg=msg_data;
mailbox_send_msg(&msg);
free(msg_data);
yieldToPID(DEVFS_PID);
for (;;) {
Message msg;
msg.msg=malloc(sizeof(vfs_message));
mailbox_get_msg(box,&msg,sizeof(vfs_message));
if (msg.from==0) {
free(msg.msg);
} else {
vfs_message* vfs_msg=(vfs_message*)msg.msg;
process_vfs_msg(vfs_msg,msg.from);
free(vfs_msg);
yieldToPID(VFS_PID);
}
yield();
}
}

View File

@ -9,8 +9,8 @@ void cpu_init(struct multiboot_boot_header_tag* tags) {
gdt_init(); gdt_init();
isr_install(); isr_install();
asm volatile("sti"); asm volatile("sti");
serial_init();
pmem_init(tags); pmem_init(tags);
paging_init(); paging_init();
tasking_init(); tasking_init();
serial_init();
} }

View File

@ -132,8 +132,12 @@ __attribute__((unused)) static char *exception_messages[] = {
}; };
void isr_handler(registers_t r) { void isr_handler(registers_t r) {
if (r.int_no!=80 && r.int_no!=14) {
vga_write_string(exception_messages[r.int_no]);
}
switch (r.int_no) { switch (r.int_no) {
case 14: { case 14: {
serial_write_string("PAGE FAULT\n");
uint32_t addr; uint32_t addr;
asm("movl %%cr2,%0": "=r"(addr)); asm("movl %%cr2,%0": "=r"(addr));
vga_write_string("In PID "); vga_write_string("In PID ");

View File

@ -40,17 +40,15 @@ void kernel_mailbox_send_msg(Message* user_msg) {
} }
Mailbox mailbox=mailboxes[user_msg->to]; Mailbox mailbox=mailboxes[user_msg->to];
uint32_t num_pages=(user_msg->size/4096)+1; uint32_t num_pages=(user_msg->size/4096)+1;
serial_printf("Storing data in pmem\n");
void* phys_addr=pmem_alloc(num_pages); void* phys_addr=pmem_alloc(num_pages);
void* virt_addr=find_free_pages(num_pages); void* virt_addr=find_free_pages(num_pages);
// char* msg_data=kmalloc(user_msg->size);
map_pages(virt_addr,phys_addr,num_pages,0,1); map_pages(virt_addr,phys_addr,num_pages,0,1);
// if (msg_data==NULL) { serial_printf("Mapped into vmem\n");
// serial_print("Cannot allocate kernel msg data!\n"); serial_printf("memcpy(%x,%x,%d)\n",virt_addr,user_msg->msg,user_msg->size);
// vga_write_string("Cannot allocate kernel msg data!\n");
// for(;;);
// }
memcpy(virt_addr,user_msg->msg,user_msg->size); memcpy(virt_addr,user_msg->msg,user_msg->size);
unmap_pages(virt_addr,num_pages); unmap_pages(virt_addr,num_pages);
serial_printf("Stored data in pmem\n");
mailbox.msg_store[mailbox.wr].msg=phys_addr; mailbox.msg_store[mailbox.wr].msg=phys_addr;
mailbox.msg_store[mailbox.wr].from=user_msg->from; mailbox.msg_store[mailbox.wr].from=user_msg->from;
mailbox.msg_store[mailbox.wr].to=user_msg->to; mailbox.msg_store[mailbox.wr].to=user_msg->to;
@ -89,12 +87,16 @@ void kernel_mailbox_get_msg(uint32_t box, Message* recv_msg, uint32_t buffer_sz)
mailboxes[box]=mailbox; mailboxes[box]=mailbox;
return; return;
} }
if (buffer_sz>mailbox.msg_store[mailbox.rd].size) {
serial_printf("Warning: buffer sized for message %d big, but got message sized %d.\n",buffer_sz,mailbox.msg_store[mailbox.rd].size);
}
Message msg=mailbox.msg_store[mailbox.rd]; Message msg=mailbox.msg_store[mailbox.rd];
uint32_t num_pages=(msg.size/4096)+1; uint32_t num_pages=(msg.size/4096)+1;
void* virt_addr=find_free_pages(num_pages); void* virt_addr=find_free_pages(num_pages);
map_pages(virt_addr,msg.msg,num_pages,0,1); map_pages(virt_addr,msg.msg,num_pages,0,1);
memcpy(recv_msg->msg,virt_addr,mailbox.msg_store[mailbox.rd].size); memcpy(recv_msg->msg,virt_addr,mailbox.msg_store[mailbox.rd].size);
unmap_pages(virt_addr,num_pages); unmap_pages(virt_addr,num_pages);
pmem_free(((uint32_t)msg.msg)>>12,num_pages);
// kfree(mailbox.msg_store[mailbox.rd].msg); // kfree(mailbox.msg_store[mailbox.rd].msg);
mailbox.msg_store[mailbox.rd].from=0; mailbox.msg_store[mailbox.rd].from=0;
uint32_t orig_rd=mailbox.rd; uint32_t orig_rd=mailbox.rd;

View File

@ -176,6 +176,28 @@ void unmap_pages(void* start_virt,uint32_t num_pages) {
} }
} }
char make_protector(int page) {
int table=page>>10;
if (is_page_present(page)) return 0;
page=page&0x3FF;
smap_page_tables[table+1]=(smap[table]&0xFFFFFC00)|0x3;
uint32_t page_val=smap[(1024+(1024*table))+page];
page_val=page_val&(~0x6);
page_val=page_val|0x800;
smap[(1024+(1024*table))+page]=page_val;
return 1;
}
char is_in_protector(uint32_t* addr) {
int page=((uint32_t)addr)>>12;
if (is_page_present(page)) return 0;
int table=page>>10;
page=page&0x3FF;
smap_page_tables[table+1]=(smap[table]&0xFFFFFC00)|0x3;
return smap[(1024+(1024*table))+page]&0x800;
return 1;
}
void paging_init() { void paging_init() {
for (uint32_t i=0;i<NUM_KERN_DIRS*1024;i++) { for (uint32_t i=0;i<NUM_KERN_DIRS*1024;i++) {
kern_page_tables[i]=(i<<12)|0x3; kern_page_tables[i]=(i<<12)|0x3;

View File

@ -17,5 +17,7 @@ void load_address_space(uint32_t cr3);
void* virt_to_phys(void* virt_addr); void* virt_to_phys(void* virt_addr);
void* find_free_pages(int num_pages); void* find_free_pages(int num_pages);
void load_smap(uint32_t cr3); void load_smap(uint32_t cr3);
char make_protector(int page);
char is_in_protector(uint32_t* addr);
#endif #endif

View File

@ -72,7 +72,10 @@ Task* tasking_createTaskCr3KmodeParam(void* eip,void* cr3,char kmode,char param1
kstacks[top_idx-5]=0; kstacks[top_idx-5]=0;
kstacks[top_idx-4]=0; kstacks[top_idx-4]=0;
kstacks[top_idx-3]=(uint32_t)task_init; kstacks[top_idx-3]=(uint32_t)task_init;
uint32_t* user_stack=(uint32_t*)(((uint32_t)alloc_pages(1))+0x1000); uint32_t* user_stack=(uint32_t*)(((uint32_t)alloc_pages(2))+0x2000);
int buffer_pg_num=(((uint32_t)user_stack)-0x2000)>>12;
make_protector(buffer_pg_num);
// uint32_t* user_stack=(uint32_t*)(((uint32_t)alloc_pages(1))+0x1000);
user_stack-=2; user_stack-=2;
user_stack[0]=param1; user_stack[0]=param1;
user_stack[1]=param2; user_stack[1]=param2;

View File

@ -13,17 +13,17 @@ typedef enum {
} vfs_message_type; } vfs_message_type;
typedef struct { typedef struct {
char flags;
vfs_message_type type; vfs_message_type type;
uint8_t id; uint8_t id;
char mode[10]; char mode[10];
uint32_t fd; uint32_t fd;
char path[4096];
uint32_t pos; uint32_t pos;
char flags;
int data; int data;
char in_progress; char in_progress;
uint32_t orig_mbox; uint32_t orig_mbox;
void* fs_data; void* fs_data;
} vfs_message; char path[4096];
} __attribute__((packed)) vfs_message;
#endif #endif