Add a kernel serial driver and a yieldToPID function.

This commit is contained in:
pjht 2019-08-04 13:14:35 -05:00
parent 88a7cf61f0
commit 99522efde5
17 changed files with 518 additions and 99 deletions

View File

@ -1,24 +0,0 @@
set pagination off
target remote localhost:1234
symbol-file kernel/kernel.elf
add-symbol-file vfs/vfs
b tasking.c:123
commands
silent
disable breakpoints
symbol-file kernel/kernel.elf
p task->pid
if task->pid==2
add-symbol-file vfs/vfs
enable breakpoints
else
enable breakpoints 1
c
end
c
end
b main
commands
disable breakpoints 1
end

View File

@ -1,71 +0,0 @@
set pagination off
target remote localhost:1234
symbol-file kernel/kernel.elf
printf "Start at kernel\n"
b tasking.c:123
commands
silent
if task->pid==0
printf "Yield to the kernel\n"
else
if task->pid==1
printf "Yield to init\n"
else
if task->pid==2
printf "Yield to the VFS\n"
else
if task->pid==3
printf "Yield to fsdrv\n"
else
printf "Yield to unknown\n"
end
end
end
end
c
end
b tasking.c:35
commands
silent
if next_pid==0
printf "Kernel task registered\n"
else
if next_pid==1
printf "Init created\n"
else
if next_pid==2
printf "VFS created\n"
else
if next_pid==3
printf "fsdrv created\n"
else
printf "Unknown task created\n"
end
end
end
end
c
end
b mailboxes.c:14
commands
silent
printf "Mailbox %d created.\n",next_box
c
end
b mailboxes.c:27
commands
silent
printf "Message sent from box %d to box %d\n",user_msg->from,user_msg->to
c
end
b mailboxes.c:48
commands
silent
if mailbox.msg_store[mailbox.rd].size==0
printf "Box %d attempted to get a message, but there were none.\n",box
else
printf "Box %d got a message from box %d.\n",box,mailbox.msg_store[mailbox.rd].from
end
c
end
c

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ vfs/vfs
fsdrv/fsdrv
initrd/*
iso/boot/initrd.tar
serout

View File

@ -15,7 +15,7 @@ NASM = $(shell cat psinfo/$(PLAT)/nasm.txt)
EMU = $(shell cat psinfo/$(PLAT)/emu.txt)
GDB = $(shell cat psinfo/$(PLAT)/gdb.txt)
CFLAGS = -Isysroot/usr/include -Wextra -Wall -Wno-unused-parameter -g -ffreestanding
QFLAGS = -hda ext2.img -m 2G -boot d -cdrom os.iso -serial vc #-chardev socket,id=s1,port=3000,host=localhost -serial chardev:s1
QFLAGS = -hda ext2.img -m 2G -boot d -cdrom os.iso -serial file:serout #-chardev socket,id=s1,port=3000,host=localhost -serial chardev:s1
CWD = $(shell pwd)
.PHONY: sysroot

View File

@ -169,7 +169,7 @@ int main(char* initrd, uint32_t initrd_sz) {
yield(); // Bochs fails here
datapos=find_loc("fsdrv",initrd);
load_task(datapos,initrd);
yield();
yieldToPID(3);
FILE* file;
do {
vga_write_string("CALLING FOPEN\n");

View File

@ -2,6 +2,7 @@
#include "paging.h"
#include "isr.h"
#include "pmem.h"
#include "serial.h"
#include "../tasking.h"
void cpu_init(struct multiboot_boot_header_tag* tags) {
@ -11,4 +12,5 @@ void cpu_init(struct multiboot_boot_header_tag* tags) {
pmem_init(tags);
paging_init();
tasking_init();
serial_init();
}

View File

@ -225,6 +225,8 @@ void isr_handler(registers_t r) {
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);
} else if (r.eax==15) {
tasking_yieldToPID(r.ebx);
}
break;
}

View File

@ -3,18 +3,21 @@
#include <string.h>
#include <stdint.h>
#include <mailboxes.h>
#include "serial.h"
Mailbox* mailboxes=(Mailbox*)0xF6400000;
uint32_t next_box=1;
uint32_t kernel_mailbox_new(uint16_t size) {
if (next_box==262144) {
serial_printf("Attempted to create a mailbox, but failed\n");
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);
serial_printf("Created mailbox %d\n",next_box);
next_box++;
return next_box-1;
}
@ -41,11 +44,13 @@ void kernel_mailbox_send_msg(Message* user_msg) {
mailbox.wr=mailbox.size-1;
}
}
serial_printf("Message sent from box %d to box %d\n",user_msg->from,user_msg->to);
}
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) {
serial_printf("Box %d attempted to get a message, but there were none.\n",box);
mailbox.rd++;
if (mailbox.rd==mailbox.size) {
mailbox.rd=0;
@ -66,6 +71,7 @@ void kernel_mailbox_get_msg(uint32_t box, Message* recv_msg, uint32_t buffer_sz)
if (buffer_sz>mailbox.msg_store[mailbox.rd].size) {
recv_msg->size=mailbox.msg_store[mailbox.rd].size;
recv_msg->from=0;
serial_printf("Box %d attempted to get the message from box %d, but the buffer was too small.\n",box,mailbox.msg_store[mailbox.rd].from);
return;
}
memcpy(recv_msg->msg,mailbox.msg_store[mailbox.rd].msg,mailbox.msg_store[mailbox.rd].size);
@ -81,4 +87,5 @@ void kernel_mailbox_get_msg(uint32_t box, Message* recv_msg, uint32_t buffer_sz)
mailbox.rd=mailbox.size-1;
}
}
serial_printf("Box %d got a message from box %d.\n",box,mailbox.msg_store[mailbox.rd].from);
}

12
kernel/cpu/i386/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

172
kernel/cpu/i386/serial.c Normal file
View File

@ -0,0 +1,172 @@
#include "ports.h"
#include "../../cpu/i386/isr.h"
#include "serial.h"
#include <stdio.h>
#include <string.h>
#include <devbuf.h>
#include <stdint.h>
#define SERIAL_LINE_ENABLE_DLAB 0x80
static char configured[]={0,0,0,0};
static int data_port(int com) {
switch (com) {
case 0: return 0x3f8;
case 1: return 0x2f8;
case 2: return 0x3e8;
case 3: return 0x2e8;
}
return 0;
}
static int int_port(int com) {
switch (com) {
case 0: return 0x3f9;
case 1: return 0x2f9;
case 2: return 0x3e9;
case 3: return 0x2e9;
}
return 0;
}
static int fifo_port(int com) {
switch (com) {
case 0: return 0x3fa;
case 1: return 0x2fa;
case 2: return 0x3ea;
case 3: return 0x2ea;
}
return 0;
}
static int line_cmd_port(int com) {
switch (com) {
case 0: return 0x3fb;
case 1: return 0x2fb;
case 2: return 0x3eb;
case 3: return 0x2eb;
}
return 0;
}
static int modem_port(int com) {
switch (com) {
case 0: return 0x3fc;
case 1: return 0x2fc;
case 2: return 0x3ec;
case 3: return 0x2ec;
}
return 0;
}
static int line_stat_port(int com) {
switch (com) {
case 0: return 0x3fd;
case 1: return 0x2fd;
case 2: return 0x3ed;
case 3: return 0x2ed;
}
return 0;
}
static int scratch_port(int com) {
switch (com) {
case 0: return 0x3ff;
case 1: return 0x2ff;
case 2: return 0x3ef;
case 3: return 0x2ef;
}
return 0;
}
static void configure_baud_rate(uint32_t divisor,int com) {
port_byte_out(line_cmd_port(com),SERIAL_LINE_ENABLE_DLAB);
port_byte_out(data_port(com),(divisor>>8)&0xFF);
port_byte_out(data_port(com),divisor&0xFF);
}
static int is_transmit_fifo_empty(int com) {
return port_byte_in(line_stat_port(com))&0x20;
}
static void configure(uint32_t com, uint32_t rate) {
configure_baud_rate(115200/rate,com);
port_byte_out(line_cmd_port(com),0x03);
port_byte_out(fifo_port(com),0xC7);
port_byte_out(modem_port(com),0x03);
port_byte_out(int_port(com),0x01);
}
void serial_init() {
port_byte_out(scratch_port(0),0xaa);
if (port_byte_in(scratch_port(0))==0xaa) {
configure(0,9600);
configured[0]=1;
}
}
static void serial_putc(char c) {
if (c=='\n') {
while (!is_transmit_fifo_empty(0)) continue;
port_byte_out(data_port(0),'\r');
while (!is_transmit_fifo_empty(0)) continue;
port_byte_out(data_port(0),'\n');
} else {
while (!is_transmit_fifo_empty(0)) continue;
port_byte_out(data_port(0),c);
}
}
void serial_write_string(const char* s) {
if (!configured[0]) return;
for (int i=0;s[i]!='\0';i++) {
serial_putc(s[i]);
}
}
void serial_printf(const char* format,...) {
va_list arg;
va_start(arg,format);
for(;*format!='\0';format++) {
if(*format!='%') {
serial_putc(*format);
continue;
}
format++;
switch(*format) {
case 'c': {
int i=va_arg(arg,int);
serial_putc(i);
break;
}
case 'd': {
int i=va_arg(arg,int); //Fetch Decimal/Integer argument
if(i<0) {
i=-i;
serial_putc('-');
}
char str[11];
int_to_ascii(i,str);
serial_write_string(str);
break;
}
// case 'o': {
// int i=va_arg(arg,unsigned int); //Fetch Octal representation
// puts(convert(i,8));
// break;
// }
case 's': {
char* s=va_arg(arg,char*);
serial_write_string(s);
break;
}
case 'x': {
uint32_t i=va_arg(arg,uint32_t);
char str[11];
str[0]='\0';
hex_to_ascii(i,str);
serial_write_string(str);
break;
}
}
}
}

8
kernel/cpu/i386/serial.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef SERIAL_H
#define SERIAL_H
void serial_init();
void serial_write_string(const char* s);
void serial_printf(const char* format,...);
#endif

View File

@ -11,6 +11,7 @@
#include <stdint.h>
#include <stdlib.h>
#include "../halt.h"
#include "serial.h"
#define STACK_PAGES 2
extern void task_init();
@ -22,6 +23,7 @@ uint32_t next_pid;
Task* currentTask;
static Task* headTask;
static Task* tailTask;
static Task* tasks[32768];
Task* tasking_createTaskCr3KmodeParam(void* eip,void* cr3,char kmode,char param1_exists,uint32_t param1_arg,char param2_exists,uint32_t param2_arg);
void tasking_init(void* esp) {
@ -79,6 +81,7 @@ Task* tasking_createTaskCr3KmodeParam(void* eip,void* cr3,char kmode,char param1
load_address_space(old_cr3);
task->next=NULL;
task->pid=next_pid;
tasks[next_pid]=task;
task->priv=0;
task->errno=0;
if (currentTask) {
@ -89,14 +92,17 @@ Task* tasking_createTaskCr3KmodeParam(void* eip,void* cr3,char kmode,char param1
}
next_pid++;
if (next_pid>1024*32) {
serial_printf("Failed to create a task, as 32k tasks have been created already.\n");
halt(); //Cannot ever create more than 32k tasks, as I don't currently reuse PIDs.
}
if (tailTask) {
tailTask->next=task;
tailTask=task;
}
if (task->pid!=0) {
serial_printf("Created task with PID %d.\n",task->pid);
}
return task;
}
int* tasking_get_errno_address() {
@ -120,6 +126,17 @@ void tasking_yield(registers_t registers) {
if (!task) {
task=headTask;
}
serial_printf("Yielding to PID %d.\n",task->pid);
load_smap(task->cr3);
switch_to_task(task);
}
void tasking_yieldToPID(uint32_t pid) {
Task* task=tasks[pid];
if (!task) {
return;
}
serial_printf("Yielding to PID %d.\n",task->pid);
load_smap(task->cr3);
switch_to_task(task);
}

View File

@ -13,7 +13,7 @@ typedef struct Task {
int errno;
uint32_t pid;
struct Task* next;
}Task;
} Task;
int* tasking_get_errno_address();

View File

@ -6,6 +6,7 @@
void tasking_init();
void tasking_yield();
void tasking_yieldToPID();
Task* tasking_createTask(void* eip);
Task* tasking_createTaskCr3KmodeParam(void* eip,void* cr3,char kmode,char param1_exists,uint32_t param1_arg,char param2_exists,uint32_t param2_arg);
char isPrivleged(uint32_t pid);

View File

@ -27,3 +27,10 @@ void createTaskCr3Param(void* task,void* cr3,uint32_t param1,uint32_t param2) {
int $80; \
"::"b"(task),"c"(cr3),"d"(param1),"S"(param2));
}
void yieldToPID(uint32_t pid) {
asm volatile(" \
mov $15, %%eax; \
int $80; \
"::"b"(pid));
}

284
serout Normal file
View File

@ -0,0 +1,284 @@
Created task with PID 1.
Yielding to PID 1.
Created mailbox 1
Created task with PID 2.
Yielding to PID 2.
Created mailbox 2
Created mailbox 3
Yielding to PID 0.
Yielding to PID 1.
Created task with PID 3.
Yielding to PID 3.
Created mailbox 4
Message sent from box 4 to box 3
Yielding to PID 0.
Yielding to PID 1.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.
Message sent from box 1 to box 3
Yielding to PID 2.
Box 3 got a message from box 0.
Message sent from box 3 to box 1
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Yielding to PID 2.
Box 3 attempted to get a message, but there were none.
Yielding to PID 3.
Box 4 attempted to get a message, but there were none.
Yielding to PID 0.
Yielding to PID 1.
Box 1 got a message from box 0.

View File

@ -4,6 +4,7 @@
#include <stdint.h>
void yield();
void yieldToPID(uint32_t pid);
void createTask(void* task);
void createTaskCr3(void* task,void* cr3);
void createTaskCr3Param(void* task,void* cr3,uint32_t param1,uint32_t param2);