Change IPC to a mailbox-based system

Instead of using PIDs to identify a destination, a process can have one 
or more mailboxes to send messages to.
This commit is contained in:
pjht 2019-06-27 17:00:23 -05:00
parent 9db6bf61ca
commit 51bb986d76
13 changed files with 187 additions and 132 deletions

View File

@ -3,8 +3,8 @@ OBJ = $(C_SOURCES:.c=.o )
CFLAGS = -I../sysroot/usr/include -Wall -g -ffreestanding
CC = i386-elf-gcc
init: $(OBJ)
@i386-elf-ld -o $@ $^ ../kernel/start.o ../libc/libc.a
init: $(OBJ) ../libc/*
@i386-elf-ld -o $@ $(OBJ) ../kernel/start.o ../libc/libc.a
%.o: %.c
@$(CC) $(CFLAGS) -c $< -o $@

View File

@ -3,6 +3,10 @@
#include <grub/text_fb_info.h>
#include <ipc/vfs.h>
#include <elf.h>
#include <mailboxes.h>
#include <memory.h>
#include <tasking.h>
#include <stdlib.h>
typedef struct {
char filename[100];
@ -27,7 +31,7 @@ uint32_t getsize(const char *in) {
int main(char* initrd, uint32_t initrd_sz) {
text_fb_info info;
info.address=map_phys(0xB8000,10);
info.address=map_phys((void*)0xB8000,10);
info.width=80;
info.height=25;
vga_init(info);
@ -88,42 +92,49 @@ int main(char* initrd, uint32_t initrd_sz) {
}
vga_write_string("Loaded VFS into memory, creating task\n");
createTaskCr3((void*)header.entry,cr3);
vga_write_string("Created VFS task, sending test message\n");
vfs_message* msg=malloc(sizeof(vfs_message)+strlen("/dev/sda")+1);
msg->type=VFS_OPEN;
msg->id=1;
msg->mode[0]='r';
msg->mode[1]='\0';
strcpy(&msg->path,"/dev/sda");
send_msg(2,msg,sizeof(vfs_message)+strlen("/dev/sda")+1);
free(msg);
vga_write_string("Created VFS task, creating mailbox\n");
uint32_t box=mailbox_new(16);
vga_write_string("Created mailbox, yielding to VFS so it can create it's mailbox.\n");
yield();
vga_write_string("VFS yielded back, sending test message\n");
vfs_message* msg_data=malloc(sizeof(vfs_message));
msg_data->type=VFS_OPEN;
msg_data->id=1;
strcpy(&msg_data->mode,"r");
strcpy(&msg_data->path,"/dev/sda");
Message msg;
msg.from=box;
msg.to=1;
msg.msg=msg_data;
msg.size=sizeof(vfs_message);
mailbox_send_msg(&msg);
vga_write_string("Sent test message, yielding to task\n");
yield();
vga_write_string("Yielded and got control, getting message\n");
int sender;
int size;
msg=get_msg(&sender,&size);
msg.msg=malloc(sizeof(vfs_message));
mailbox_get_msg(box,&msg,sizeof(vfs_message));
vfs_message* vfs_msg=(vfs_message*)msg.msg;
vga_write_string("Message of type ");
char str[256];
str[0]='\0';
int_to_ascii(msg->type,str);
int_to_ascii(vfs_msg->type,str);
vga_write_string(str);
vga_write_string("\n");
vga_write_string("ID ");
str[0]='\0';
int_to_ascii(msg->id,str);
int_to_ascii(vfs_msg->id,str);
vga_write_string(str);
vga_write_string("\n");
vga_write_string("Mode ");
vga_write_string(&msg->mode);
vga_write_string(&vfs_msg->mode);
vga_write_string("\n");
vga_write_string("FD ");
str[0]='\0';
int_to_ascii(msg->fd,str);
int_to_ascii(vfs_msg->fd,str);
vga_write_string(str);
vga_write_string("\n");
vga_write_string("Path ");
vga_write_string(&msg->path);
vga_write_string(&vfs_msg->path);
vga_write_string("\n");
}
for(;;);

View File

@ -118,6 +118,11 @@ _start:
orl $0x80010000, %ecx
movl %ecx, %cr0
#Enable PSE (Page Size Extension, allows for 4MiB pages)
movl %cr4, %ecx
orl $0x00000010, %ecx
movl %ecx, %cr4
# Jump to higher half with an absolute jump.
lea 4f, %ecx
jmp *%ecx

View File

@ -8,6 +8,7 @@
#include "../tasking.h"
#include "interrupt.h"
#include "address_spaces.h"
#include "mailboxes.h"
#include <string.h>
#include <stdint.h>
void irq_handler(registers_t r);
@ -186,9 +187,9 @@ void isr_handler(registers_t r) {
} else if (r.eax==5) {
r.ebx=(uint32_t)tasking_get_errno_address();
} else if (r.eax==6) {
r.ebx=(uint32_t)tasking_get_msg((uint32_t*)r.ebx,(uint32_t*)r.ecx);
kernel_mailbox_get_msg(r.ebx,r.ecx,r.edx);
} else if (r.eax==7) {
tasking_send_msg(r.ebx,(void*)r.ecx,r.edx);
kernel_mailbox_send_msg((Message*)r.ebx);
} else if (r.eax==8) {
r.ebx=(uint32_t)paging_new_address_space();
} else if (r.eax==9) {
@ -208,8 +209,10 @@ void isr_handler(registers_t r) {
tasking_createTaskCr3KmodeParam((void*)r.ebx,(void*)r.ecx,0,1,r.edx,1,r.esi);
} else if (r.eax==13) {
r.ebx=(uint32_t)address_spaces_put_data((void*)r.ebx,(void*)r.ecx,r.edx);
} else if (r.eax==14) {
r.ebx=kernel_mailbox_new((uint16_t)r.ebx);
}
break;
break;
}
}
}

View File

@ -1,64 +1,84 @@
#include "mailboxes.h"
#include "kmalloc.h"
#include <string.h>
#include <stdint.h>
#include <mailboxes.h>
Mailbox* mailbox_new(uint16_t size) {
Mailbox* box=kmalloc(sizeof(Mailbox));
box->rd=0;
box->wr=0;
box->size=size;
box->msg_store=kmalloc(sizeof(Message)*size);
Mailbox* mailboxes=0xF6400000;
uint32_t next_box=0;
uint32_t kernel_mailbox_new(uint16_t size) {
if (next_box==262144) {
return 0xFFFFFFFF;
}
mailboxes[next_box].rd=0;
mailboxes[next_box].wr=0;
mailboxes[next_box].size=size;
mailboxes[next_box].msg_store=kmalloc(sizeof(Message)*size);
next_box++;
return next_box-1;
}
void mailbox_put_msg(Mailbox* mailbox, uint32_t pid,char* msg,uint32_t size) {
// char* data=kmalloc(size);
// for (int i=0;i<size;i++) {
// data[i]=msg[i];
// }
mailbox->msg_store[mailbox->wr]->msg=data;
mailbox->msg_store[mailbox->wr]->sender=sender;
mailbox->msg_store[mailbox->wr]->size=size;
mailbox->wr++;
if (mailbox->wr==mailbox->size) {
mailbox->wr=0;
}
if (mailbox->wr==mailbox->rd) {
mailbox->wr--;
if (mailbox->wr==(2^32)-1) {
mailbox->wr=mailbox->size-1;
}
}
break;
void kernel_mailbox_free(uint32_t box) {
kfree(mailboxes[box].msg_store);
}
Message* mailbox_get_msg(Mailbox* mailbox, uint32_t* sender,uint32_t* size) {
if (mailbox->msg_store[mailbox->rd]==NULL) {
mailbox->rd++;
if (mailbox->rd==mailbox->size) {
mailbox->rd=0;
void kernel_mailbox_send_msg(Message* user_msg) {
Mailbox mailbox=mailboxes[user_msg->to];
char* msg_data=kmalloc(user_msg->size);
memcpy(msg_data,user_msg->msg,user_msg->size);
mailbox.msg_store[mailbox.wr].msg=msg_data;
mailbox.msg_store[mailbox.wr].from=user_msg->from;
mailbox.msg_store[mailbox.wr].to=user_msg->to;
mailbox.msg_store[mailbox.wr].size=user_msg->size;
mailbox.wr++;
if (mailbox.wr==mailbox.size) {
mailbox.wr=0;
}
if (mailbox.wr==mailbox.rd) {
mailbox.wr--;
if (mailbox.wr==(2^32)-1) {
mailbox.wr=mailbox.size-1;
}
if (mailbox->msg_store[mailbox->rd]==NULL) {
mailbox->rd--;
if (mailbox->rd==(2^32)-1) {
mailbox->rd=mailbox->size-1;
}
}
void kernel_mailbox_get_msg(uint32_t box, Message* recv_msg, uint32_t buffer_sz) {
Mailbox mailbox=mailboxes[box];
if (mailbox.msg_store[mailbox.rd].size==0) {
mailbox.rd++;
if (mailbox.rd==mailbox.size) {
mailbox.rd=0;
}
if (mailbox.msg_store[mailbox.rd].size==0) {
mailbox.rd--;
if (mailbox.rd==(2^32)-1) {
mailbox.rd=mailbox.size-1;
}
return NULL;
recv_msg->size=0;
recv_msg->from=0;
return;
}
}
Mesage* msg_kmem=&mailbox->msg_store[mailbox->rd];
// *size=mailbox->size_store[mailbox->rd];
// char* data=mailbox->msg_store[mailbox->rd];
// char* msg=alloc_pages((*size/4096)+1);
// for (int i=0;i<*size;i++) {
// msg[i]=data[i];
// }
// kfree(data);
mailbox->rd++;
if (mailbox->rd==mailbox->size) {
mailbox->rd=0;
recv_msg->from=mailbox.msg_store[mailbox.rd].from;
recv_msg->to=mailbox.msg_store[mailbox.rd].to;
recv_msg->size=mailbox.msg_store[mailbox.rd].size;
if (buffer_sz>mailbox.msg_store[mailbox.rd].size) {
recv_msg->size=mailbox.msg_store[mailbox.rd].size;
recv_msg->from=0;
return;
}
if (mailbox->rd>mailbox->wr) {
mailbox->rd=mailbox->wr-1;
if (mailbox->rd==(2^32)-1) {
mailbox->rd=mailbox->size-1;
memcpy(recv_msg->msg,mailbox.msg_store[mailbox.rd].msg,mailbox.msg_store[mailbox.rd].size);
kfree(mailbox.msg_store[mailbox.rd].msg);
mailbox.msg_store[mailbox.rd].size=0;
mailbox.rd++;
if (mailbox.rd==mailbox.size) {
mailbox.rd=0;
}
if (mailbox.rd>mailbox.wr) {
mailbox.rd=mailbox.wr-1;
if (mailbox.rd==(2^32)-1) {
mailbox.rd=mailbox.size-1;
}
}
return msg;
}

View File

@ -1,23 +1,12 @@
#ifndef MALBOXES_H
#define MAILBOXES_H
#ifndef KERNEL_MAILBOXES_H
#define KERNEL_MAILBOXES_H
typedef struct {
void* msg;
uint32_t sender;
uint32_t size;
} Message;
#include <stdint.h>
#include <mailboxes.h>
typedef struct {
uint32_t rd;
uint32_t wr;
uint16_t size;
Message* msg_store;
} Mailbox;
#include "mailboxes.h"
Mailbox* mailbox_new(uint16_t size);
void mailbox_put_msg(Mailbox* mailbox, uint32_t pid,char* msg,uint32_t size);
void* mailbox_get_msg(Mailbox* mailbox, Mailbox** sender,uint32_t* size);
uint32_t kernel_mailbox_new(uint16_t size);
void kernel_mailbox_free(uint32_t box);
void kernel_mailbox_send_msg(Message* user_msg);
void kernel_mailbox_get_msg(uint32_t box, Message* recv_msg, uint32_t buffer_sz);
#endif

View File

@ -132,21 +132,8 @@ void* paging_new_address_space() {
void* dir=pmem_alloc(1);
smap_page_tables[0]=((uint32_t)dir)|0x3;
invl_page(smap);
for (uint32_t i=0;i<NUM_KERN_DIRS;i++) {
uint32_t entry_virt=(uint32_t)&(kern_page_tables[i*1024]);
smap[i+768]=(entry_virt-0xC0000000)|0x3;
}
for (uint32_t i=0;i<32;i++) {
uint32_t entry_virt=(uint32_t)&(kstack_page_tables[i*1024]);
smap[i+986]=(entry_virt-0xC0000000)|0x3;
}
for (uint32_t i=0;i<4;i++) {
uint32_t entry_virt=(uint32_t)&(kmalloc_page_tables[i*1024]);
smap[i+1018]=(entry_virt-0xC0000000)|0x3;
}
for (uint32_t i=0;i<2;i++) {
uint32_t entry_virt=(uint32_t)&(smap_page_tables[i*1024]);
smap[i+1022]=(entry_virt-0xC0000000)|0x3;
for (uint32_t i=0;i<1024;i++) {
smap[i]=page_directory[i];
}
smap_page_tables[0]=cr3|0x3;
invl_page(smap);
@ -203,6 +190,7 @@ void paging_init() {
uint32_t entry_virt=(uint32_t)&(kern_page_tables[i*1024]);
page_directory[i+768]=(entry_virt-0xC0000000)|0x3;
}
page_directory[985]=(uint32_t)(pmem_alloc(1024))|0x83;
for (uint32_t i=0;i<32;i++) {
uint32_t entry_virt=(uint32_t)&(kstack_page_tables[i*1024]);
page_directory[i+986]=(entry_virt-0xC0000000)|0x3;
@ -217,4 +205,5 @@ void paging_init() {
page_directory[i+1022]=(entry_virt-0xC0000000)|0x3;
}
load_page_directory((uint32_t*)((uint32_t)page_directory-0xC0000000));
asm volatile("xchgw %bx, %bx");
}

25
libc/mailboxes.c Normal file
View File

@ -0,0 +1,25 @@
#include <stdint.h>
#include <mailboxes.h>
uint32_t mailbox_new(uint16_t size) {
uint32_t box;
asm volatile(" \
mov $14, %%eax; \
int $80; \
":"=b"(box):"b"(size));
return box;
}
void mailbox_send_msg(Message* msg) {
asm volatile(" \
mov $7, %%eax; \
int $80; \
"::"b"(msg));
}
void mailbox_get_msg(uint32_t box, Message* recv_msg, uint32_t buffer_sz) {
asm volatile(" \
mov $6, %%eax; \
int $80; \
"::"b"(box),"c"(recv_msg),"d"(buffer_sz));
}

View File

@ -14,22 +14,6 @@ void createTask(void* task) {
"::"b"(task));
}
void* get_msg(uint32_t* sender,uint32_t* size) {
void* msg;
asm volatile(" \
mov $6, %%eax; \
int $80; \
":"=b"(msg):"b"(sender),"c"(size));
return msg;
}
void send_msg(uint32_t pid,void* msg,uint32_t size) {
asm volatile(" \
mov $7, %%eax; \
int $80; \
"::"b"(pid),"c"(msg),"d"(size));
}
void createTaskCr3(void* task,void* cr3) {
asm volatile(" \
mov $9, %%eax; \

View File

@ -10,7 +10,7 @@ typedef struct {
uint32_t id;
char mode[10];
uint32_t fd;
char path[0];
char path[4096];
} vfs_message;
#endif

View File

@ -0,0 +1,22 @@
#ifndef MAILBOXES_H
#define MAILBOXES_H
#include <stdint.h>
typedef struct {
void* msg;
uint32_t from;
uint32_t to;
uint32_t size;
} Message;
typedef struct {
uint32_t rd;
uint32_t wr;
uint16_t size;
Message* msg_store;
} Mailbox;
uint32_t mailbox_new(uint16_t size);
void mailbox_send_msg(Message* msg);
#endif

View File

@ -3,8 +3,8 @@ OBJ = $(C_SOURCES:.c=.o)
CFLAGS = -I../sysroot/usr/include -Wall -g -ffreestanding
CC = i386-elf-gcc
vfs: $(OBJ)
@i386-elf-ld -o $@ $^ ../kernel/start.o ../libc/libc.a
vfs: $(OBJ) ../libc/*
@i386-elf-ld -o $@ $(OBJ) ../kernel/start.o ../libc/libc.a
%.o: %.c
@$(CC) $(CFLAGS) -c $< -o $@

View File

@ -1,12 +1,19 @@
#include <tasking.h>
#include <ipc/vfs.h>
#include <mailboxes.h>
int main() {
int sender;
int size;
vfs_message* msg=get_msg(&sender,&size);
msg->fd=2;
send_msg(1,msg,size);
uint32_t box=mailbox_new(16);
yield();
Message msg;
msg.msg=malloc(sizeof(vfs_message));
mailbox_get_msg(box,&msg,sizeof(vfs_message));
vfs_message* vfs_msg=(vfs_message*)msg.msg;
vfs_msg->fd=2;
msg.to=msg.from;
msg.from=box;
mailbox_send_msg(&msg);
// send_msg(1,msg,size);
yield();
for (;;);
}