Get all lost changes

This commit is contained in:
pjht 2019-02-10 20:55:08 -06:00
parent f1139feb75
commit 675fc7a0ab
11 changed files with 374 additions and 138 deletions

View File

@ -1,50 +1,109 @@
#include "paging.h"
#include "paging_helpers.h"
#include "tasking_helpers.h"
#include "tasking.h"
#include "../tasking.h"
#include "isr.h"
#include "../../libc/stdlib.h"
#include "../../libc/stdio.h"
#include "memory.h"
#include <stdint.h>
#define STACK_PAGES 2
typedef struct Task {
uint32_t esp,ebp;
uint32_t eip,cr3;
struct Task *next;
uint32_t pid;
} Task;
uint32_t next_pid;
Task* tasks_tail=NULL;
Task* tasks_head=NULL;
Task* current_task=NULL;
uint32_t next_pid=0;
static Task* currentTask;
static Task* headTask;
void tasking_init() {
Task* task=malloc(sizeof(Task*));
task->cr3=((uint32_t)page_directory)-0xC0000000;
currentTask=NULL;
next_pid=0;
headTask=createTask(NULL);
currentTask=headTask;
}
Task* createTaskEax(void* eip,uint32_t eax) {
Task* task=malloc(sizeof(Task));
task->regs.eax=eax;
task->regs.ebx=0;
task->regs.ecx=0;
task->regs.edx=0;
task->regs.esi=0;
task->regs.edi=0;
asm volatile("pushfl; movl (%%esp), %%eax; movl %%eax, %0; popfl;":"=m"(task->regs.eflags)::"%eax");
task->regs.eip=(uint32_t)eip;
asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(task->regs.cr3)::"%eax");
task->regs.esp=(uint32_t)alloc_memory(1);
task->regs.ebp=0;
task->msg_store=NULL;
task->rd=0;
task->wr=0;
task->next=NULL;
task->pid=next_pid;
next_pid++;
tasks_tail=task;
tasks_head=task;
current_task=task;
if (currentTask) {
currentTask->next=task;
}
return task;
}
Task* createTask(void* eip) {
return createTaskEax(eip,0);
}
void send_msg(uint32_t pid,char* msg) {
for (Task* task=headTask;task!=NULL;task=task->next) {
if (task->pid==pid) {
if (task->msg_store==NULL) {
task->msg_store=malloc(sizeof(char*)*256);
task->sender_store=malloc(sizeof(uint32_t)*256);
}
task->msg_store[task->wr]=msg;
task->sender_store[task->wr]=currentTask->pid;
task->wr++;
if (task->wr==task->rd) {
task->wr--;
}
}
}
}
char* get_msg(uint32_t* sender) {
if (!currentTask->msg_store) {
return NULL;
}
if (currentTask->msg_store[currentTask->rd]==NULL) {
currentTask->rd++;
if (currentTask->msg_store[currentTask->rd]==NULL) {
currentTask->rd--;
return NULL;
}
}
*sender=currentTask->sender_store[currentTask->rd];
char* data=currentTask->msg_store[currentTask->rd];
currentTask->msg_store[currentTask->rd]=NULL;
currentTask->sender_store[currentTask->rd]=0;
currentTask->rd++;
if (currentTask->rd>currentTask->wr) {
currentTask->rd=currentTask->wr-1;
}
return data;
}
uint32_t fork() {
uint32_t eip=readEip();
if (eip==0x12345) {
printf("CHILD\n");
return currentTask->pid;
}
Task* task=createTaskEax(eip,0x12345);
return 0;
}
void yield() {
if (!current_task) {
return;
Task* task=currentTask->next;
if (!task) {
task=headTask;
}
Task* next=current_task->next;
if (next==0) {
next=tasks_head;
}
uint32_t eip=read_eip();
if (eip==0x12345) {
return;
}
current_task->eip=eip;
asm volatile("mov %%esp, %0" : "=r"(current_task->esp));
asm volatile("mov %%ebp, %0" : "=r"(current_task->ebp));
current_task=next;
load_page_directory((uint32_t*)next->cr3);
set_regs(next->esp,next->ebp,next->eip);
Task* oldCurr=currentTask;
currentTask=task;
switchTask(&oldCurr->regs, &currentTask->regs);
}

22
cpu/i386/tasking.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef INT_TASKING_H
#define INT_TASKING_H
#include <stdint.h>
typedef struct {
uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3;
} Registers;
typedef struct Task {
Registers regs;
struct Task* next;
char** msg_store;
uint32_t* sender_store;
uint32_t msg_indx;
uint8_t rd;
uint8_t wr;
uint32_t pid;
} Task;
#endif

View File

@ -1,21 +0,0 @@
global set_regs
set_regs:
mov eax, [esp+4]
mov [esp_strg], eax
mov eax, [esp+8]
mov [ebp_strg], eax
mov eax, [esp+12]
mov [eip_strg], eax
mov esp, [esp_strg]
mov ebp, [ebp_strg]
mov eax, 0x12345
jmp [eip_strg]
esp_strg:resd 1
ebp_strg:resd 1
eip_strg:resd 1
global read_eip
read_eip:
pop eax
jmp eax

View File

@ -1,2 +1,9 @@
void set_regs(uint32_t esp,uint32_t ebp,uint32_t eip);
uint32_t read_eip();
#ifndef TASKING_HELPERS_H
#define TASKING_HELPERS_H
#include "tasking.h"
void switchTask(Registers *from, Registers *to);
uint32_t readEip();
#endif

View File

@ -0,0 +1,53 @@
.section .text
.global switchTask
switchTask:
pusha
pushf
mov %cr3, %eax #Push CR3
push %eax
mov 44(%esp), %eax #The first argument, where to save
mov %ebx, 4(%eax)
mov %ecx, 8(%eax)
mov %edx, 12(%eax)
mov %esi, 16(%eax)
mov %edi, 20(%eax)
mov 36(%esp), %ebx #EAX
mov 40(%esp), %ecx #IP
mov 20(%esp), %edx #ESP
add $4, %edx #Remove the return value ;)
mov 16(%esp), %esi #EBP
mov 4(%esp), %edi #EFLAGS
mov %ebx, (%eax)
mov %edx, 24(%eax)
mov %esi, 28(%eax)
mov %ecx, 32(%eax)
mov %edi, 36(%eax)
pop %ebx #CR3
mov %ebx, 40(%eax)
push %ebx #Goodbye again ;)
mov 48(%esp), %eax #Now it is the new object
mov 4(%eax), %ebx #EBX
mov 8(%eax), %ecx #ECX
mov 12(%eax), %edx #EDX
mov 16(%eax), %esi #ESI
mov 20(%eax), %edi #EDI
mov 28(%eax), %ebp #EBP
push %eax
mov 36(%eax), %eax #EFLAGS
push %eax
popf
pop %eax
mov 24(%eax), %esp #ESP
push %eax
mov 40(%eax), %eax #CR3
mov %eax, %cr3
pop %eax
push %eax
mov 32(%eax), %eax #EIP
xchg (%esp), %eax #We do not have any more registers to use as tmp storage
mov (%eax), %eax #EAX
ret #This ends all!
.global readEip
readEip:
pop %eax
jmp %eax

View File

@ -1,7 +1,11 @@
#ifndef TASKING_H
#define TASKING_H
#include "i386/tasking.h"
void tasking_init();
void yield();
uint32_t fork();
Task* createTask(void* eip);
void send_msg(uint32_t pid,char* msg);
char* get_msg(uint32_t* sender);
#endif

View File

@ -35,6 +35,11 @@ uint32_t initrd_sz;
devbuf* kbd_buf;
/*
pop %eax; \
or $0x200,%eax; \
push %eax; \
*/
void switch_to_user_mode() {
// Set up a stack structure for switching to user mode.
asm volatile(" \
@ -49,9 +54,6 @@ void switch_to_user_mode() {
pushl $0x23; \
pushl %eax; \
pushf; \
pop %eax; \
or $0x200,%eax; \
push %eax; \
pushl $0x1B; \
push $1f; \
iret; \
@ -168,40 +170,49 @@ void read_initrd(multiboot_info_t* mbd) {
}
}
void init() {
klog("INFO","Beginning initialization");
//createTask(vfs_task);
// while (vfs_initialized==0) {
// //yield();
// klog("INFO","NO_VFS");
// }
// klog("INFO","VFS");
// init_devfs();
// screen_init();
// kbd_buf=devbuf_init();
// add_dev(console_dev_drv,"console");
stdout=fopen("/dev/console","w");
// while (stdout==NO_FD) {
// yield();
// }
// klog("INFO","STDOUT");
// stdin=fopen("/dev/console","r");
// stderr=fopen("/dev/console","w");
// yield();
// send_msg(0,"Hello");
// yield();
// while (1) {
// uint32_t sender;
// char* msg=get_msg(&sender);
// if (msg) {
// // Handle message here
// }
// yield();
// }
while(1) {
yield();
}
}
void main(multiboot_info_t* mbd) {
cpu_init();
init_vfs();
init_devfs();
read_initrd(mbd);
add_dev(initrd_dev_drv,"initrd");
init_initrd();
mount("/","/dev/initrd","initrd");
screen_init();
kbd_buf=devbuf_init();
add_dev(console_dev_drv,"console");
stdout=fopen("/dev/console","w");
stdin=fopen("/dev/console","r");
stderr=fopen("/dev/console","w");
ps2_init();
serial_init();
parallel_init();
if (!stdout) {
FILE* serial0=fopen("/dev/ttyS0","w");
if (serial0) {
stdout=serial0;
stderr=serial0;
}
}
timer_init();
// klog("INFO","Waiting for 1 second");
// wait(1000);
pci_init();
//pppp_init();
tasking_init();
//port_byte_out(0,0);
switch_to_user_mode();
printf("U");
for(;;);
//switch_to_user_mode();
createTask(init);
while (1) {
yield();
}
}
void got_key(char key) {

View File

@ -5,12 +5,18 @@
int vfprintf(FILE* stream,const char* format,va_list arg);
void klog(char* level,char* s,...) {
if (stdout) {
if (stdout!=NO_FD) {
va_list arg;
va_start(arg,s);
printf("[%s] ",level);
vfprintf(stdout,s,arg);
printf("\n");
va_end(arg);
} else {
screen_write_string("[");
screen_write_string(level);
screen_write_string("] ");
screen_write_string(s);
screen_write_string("\n");
}
}

View File

@ -3,6 +3,7 @@
#include "../libc/stdlib.h"
#include "../libc/stdio.h"
#include "../libc/string.h"
#include "../cpu/tasking.h"
#include "vfs.h"
typedef struct _vfs_mapping_struct {
char* mntpnt;
@ -10,17 +11,22 @@ typedef struct _vfs_mapping_struct {
struct _vfs_mapping_struct* next;
} vfs_mapping;
#define MAX_FILES 512
#define BMAP_SZ (MAX_FILES/8)
char** drv_names;
fs_drv* drvs;
uint32_t max_drvs;
uint32_t next_drv_indx;
vfs_mapping* head_mapping;
vfs_mapping* tail_mapping;
char vfs_initialized=0;
FILE* stdin=NULL;
FILE* stdout=NULL;
FILE* stderr=NULL;
uint32_t stdin=NO_FD;
uint32_t stdout=NO_FD;
uint32_t stderr=NO_FD;
FILE** files=NULL;
char* filebmap;
int vfsstrcmp(const char* s1,const char* s2) {
int i;
@ -31,6 +37,33 @@ int vfsstrcmp(const char* s1,const char* s2) {
return s1[i] - s2[i];
}
char vfs_get_bmap_bit(uint32_t byte_idx,char offset) {
char byte=filebmap[byte_idx];
char bit=byte&(1<<offset);
return bit>>offset;
}
void vfs_set_bmap_bit(uint32_t byte_idx,char offset,char bit) {
char byte=filebmap[byte_idx];
byte&=(bit<<offset);
filebmap[byte_idx]=byte;
}
uint32_t get_fd() {
for(int i=0;i<BMAP_SZ;i++) {
for (int j=0;j<8;j++) {
if (vfs_get_bmap_bit(i,j)==0) {
uint32_t idx=i*8+j;
vfs_set_bmap_bit(i,j,1);
return idx;
}
yield();
}
yield();
}
return NO_FD;
}
void init_vfs() {
drvs=malloc(sizeof(fs_drv)*32);
drv_names=malloc(sizeof(fs_drv)*32);
@ -38,6 +71,12 @@ void init_vfs() {
next_drv_indx=0;
head_mapping=NULL;
tail_mapping=NULL;
filebmap=malloc(sizeof(char)*(BMAP_SZ));
for(int i=0;i<BMAP_SZ;i++) {
filebmap[i]=0;
}
files=malloc(sizeof(FILE*)*(MAX_FILES));
vfs_initialized=1;
}
uint32_t register_fs(fs_drv drv,const char* type) {
@ -84,37 +123,34 @@ char mount(char* mntpnt,char* dev,char* type) {
}
}
FILE* fopen(const char* filename,const char* mode) {
vfs_mapping* mnt=head_mapping;
vfs_mapping* mntpnt=NULL;
const char* path;
uint32_t mntpnt_len=0;
for (;mnt!=NULL;mnt=mnt->next) {
char* root=mnt->mntpnt;
if (strlen(root)>mntpnt_len) {
if (vfsstrcmp(root,filename)==0) {
mntpnt=mnt;
mntpnt_len=strlen(root);
uint32_t fopen(const char* filename,const char* mode) {
char* msg=malloc(sizeof(char)*(6+strlen(mode)+1+strlen(filename)+1));
strcpy("fopen ",msg);
for (int i=0;i<strlen(mode);i++) {
msg[6+i]=mode[i];
}
msg[6+strlen(mode)]=" ";
for (int i=0;i<strlen(filename);i++) {
msg[6+strlen(mode)+1+i]=filename[i];
}
msg[6+strlen(mode)+1+strlen(filename)+1]='\0';
klog("INFO",msg);
return NO_FD;
send_msg(2,msg);
yield();
uint32_t sender;
char* fd_str=get_msg(&sender);
while (fd_str==NULL) {
yield();
char* fd_str=get_msg(&sender);
}
if (mntpnt) {
path=filename+mntpnt_len;
FILE* stream=malloc(sizeof(FILE));
stream->mntpnt=mntpnt->mntpnt;
stream->path=path;
stream->type=mntpnt->type;
stream->pos=0;
stream->eof=0;
char ok=drvs[mntpnt->type](FSOP_OPEN,stream,NULL,NULL);
if (ok) {
return stream;
} else {
free(stream);
return NULL;
uint32_t fd;
uint32_t number=0;
for (int i=0;i<strlen(fd_str);i++) {
number+=(fd_str[i]-0x30);
number*=10;
}
}
return NULL;
return number;
}
int fgetc(FILE* stream) {
@ -124,7 +160,7 @@ int fgetc(FILE* stream) {
}
int getc() {
return fgetc(stdin);
return fgetc(files[stdin]);
}
char* fgets(char* str,int count,FILE* stream) {
@ -167,7 +203,7 @@ int fputc(int c,FILE* stream) {
}
int putc(int c) {
return fputc(c,stdout);
return fputc(c,files[stdout]);
}
int fputs(const char* s,FILE* stream) {
@ -179,7 +215,7 @@ int fputs(const char* s,FILE* stream) {
}
int puts(const char* s) {
return fputs(s,stdout);
return fputs(s,files[stdout]);
}
int vfprintf(FILE* stream,const char* format,va_list arg) {
@ -246,7 +282,7 @@ int printf(const char* format,...) {
va_list arg;
int code;
va_start(arg,format);
code=vfprintf(stdout,format,arg);
code=vfprintf(files[stdout],format,arg);
va_end(arg);
if (code) {
return strlen(format);
@ -274,3 +310,56 @@ int fclose(FILE* stream) {
free(stream);
return 0;
}
void vfs_task() {
init_vfs();
while (1) {
uint32_t sender;
char* msg=get_msg(&sender);
if (msg) {
char* cmd=strtok(msg," ");
if (strcmp(cmd,"fopen")==0) {
int fd=get_fd();
if (fd==NO_FD) {
send_msg(sender,"4294967295");
}
char* mode=strtok(NULL," ");
char* filename=strtok(NULL,"");
vfs_mapping* mnt=head_mapping;
vfs_mapping* mntpnt=NULL;
const char* path;
uint32_t mntpnt_len=0;
for (;mnt!=NULL;mnt=mnt->next) {
char* root=mnt->mntpnt;
if (strlen(root)>mntpnt_len) {
if (vfsstrcmp(root,filename)==0) {
mntpnt=mnt;
mntpnt_len=strlen(root);
}
}
}
if (mntpnt) {
path=filename+mntpnt_len;
FILE* stream=malloc(sizeof(FILE));
stream->mntpnt=mntpnt->mntpnt;
stream->path=path;
stream->type=mntpnt->type;
stream->pos=0;
stream->eof=0;
char ok=drvs[mntpnt->type](FSOP_OPEN,stream,NULL,NULL);
if (ok) {
files[fd]=stream;
char* str=malloc(sizeof(char)*11);
int_to_ascii(fd,str);
send_msg(sender,str);
} else {
free(stream);
send_msg(sender,"4294967295");
}
}
send_msg(sender,"4294967295");
}
}
yield();
}
}

View File

@ -12,10 +12,14 @@ typedef enum {
FSOP_UMOUNT
} fs_op;
#define NO_FD 0xFFFFFFFF
extern char vfs_initialized;
typedef char (*fs_drv)(fs_op op,FILE* stream,void* data1,void* data2);
void init_vfs();
uint32_t register_fs(fs_drv drv,const char* type);
char mount(char* mntpnt,char* dev,char* type);
void vfs_task();
#endif

View File

@ -11,16 +11,18 @@ typedef struct {
int eof;
} FILE;
#define NO_FD 0xFFFFFFFF
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 3
#define EOF -1
extern FILE* stdin;
extern FILE* stdout;
extern FILE* stderr;
extern uint32_t stdin;
extern uint32_t stdout;
extern uint32_t stderr;
FILE* fopen(const char* filename,const char* mode);
uint32_t fopen(const char* filename,const char* mode);
int fgetc(FILE* stream);
int getc();
char* fgets(char* str,int count,FILE* stream);