初步实现syscall
This commit is contained in:
parent
e982d72613
commit
982287d730
32
boot/io.asm
32
boot/io.asm
|
@ -5,10 +5,40 @@ global io_in8, io_in16, io_in32
|
|||
global io_out8, io_out16, io_out32
|
||||
global io_load_eflags, io_store_eflags
|
||||
global load_gdtr, load_idtr
|
||||
global tss_flush, gdt_flush, switch_to
|
||||
global tss_flush, gdt_flush, switch_to, copy_page_physical
|
||||
|
||||
section .text
|
||||
|
||||
[GLOBAL copy_page_physical]
|
||||
copy_page_physical:
|
||||
push ebx ; According to __cdecl, we must preserve the contents of EBX.
|
||||
pushf ; push EFLAGS, so we can pop it and reenable interrupts
|
||||
; later, if they were enabled anyway.
|
||||
cli ; Disable interrupts, so we aren't interrupted.
|
||||
; Load these in BEFORE we disable paging!
|
||||
mov ebx, [esp+12] ; Source address
|
||||
mov ecx, [esp+16] ; Destination address
|
||||
|
||||
mov edx, cr0 ; Get the control register...
|
||||
and edx, 0x7fffffff ; and...
|
||||
mov cr0, edx ; Disable paging.
|
||||
|
||||
mov edx, 1024 ; 1024*4bytes = 4096 bytes
|
||||
|
||||
.loop:
|
||||
mov eax, [ebx] ; Get the word at the source address
|
||||
mov [ecx], eax ; Store it at the dest address
|
||||
add ebx, 4 ; Source address += sizeof(word)
|
||||
add ecx, 4 ; Dest address += sizeof(word)
|
||||
dec edx ; One less word to do
|
||||
jnz .loop
|
||||
|
||||
mov edx, cr0 ; Get the control register again
|
||||
or edx, 0x80000000 ; and...
|
||||
mov cr0, edx ; Enable paging.
|
||||
|
||||
popf ; Pop EFLAGS back.
|
||||
pop ebx ; Get the original value of EBX back.
|
||||
|
||||
switch_to:
|
||||
mov eax, [esp+4]
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "../include/queue.h"
|
||||
#include "../include/io.h"
|
||||
|
||||
static KEY_STATUS *key_status;
|
||||
KEY_STATUS *key_status;
|
||||
Queue *key_char_queue;
|
||||
struct key_listener* head_listener;
|
||||
|
||||
|
@ -122,6 +122,7 @@ void init_keyboard(){
|
|||
key_char_queue = create_queue();
|
||||
head_listener = (struct key_listener*) kmalloc(sizeof(struct key_listener));
|
||||
head_listener->func = default_handle;
|
||||
head_listener->lid = 0;
|
||||
|
||||
register_interrupt_handler(0x21,handle_keyboard_input);
|
||||
}
|
||||
|
@ -142,6 +143,59 @@ int handle_keyboard_input(){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void found_listener(int lid,struct key_listener *head,struct key_listener *base,struct key_listener **argv,int first){
|
||||
struct key_listener *t = base;
|
||||
if(t == NULL){
|
||||
argv = NULL;
|
||||
return;
|
||||
}
|
||||
if(t->lid == lid){
|
||||
*argv = t;
|
||||
return;
|
||||
} else{
|
||||
if(!first)
|
||||
if(head->lid == t->lid){
|
||||
argv = NULL;
|
||||
return;
|
||||
}
|
||||
found_listener(lid,head,t->next,argv,0);
|
||||
}
|
||||
}
|
||||
|
||||
struct key_listener* found_listener_id(int lid){
|
||||
struct task_struct *argv = NULL;
|
||||
found_listener(lid,head_listener,head_listener,&argv,1);
|
||||
if(argv == NULL){
|
||||
printf("Cannot found key listener id:[%d].\n",lid);
|
||||
return NULL;
|
||||
}
|
||||
return argv;
|
||||
}
|
||||
|
||||
void remove_listener(int lid){
|
||||
struct key_listener *argv = found_listener_id(lid);
|
||||
if(argv == NULL){
|
||||
printf("Cannot found listener id:[%d].\n",lid);
|
||||
return;
|
||||
}
|
||||
if(argv->lid == 0){
|
||||
printf("[\033driver\036]: Cannot remove default listener.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
kfree(argv);
|
||||
struct key_listener *head = head_listener;
|
||||
struct key_listener *last = NULL;
|
||||
while (1){
|
||||
if(head->lid == argv->lid){
|
||||
last->next = argv->next;
|
||||
return;
|
||||
}
|
||||
last = head;
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
|
||||
void add_listener(struct key_listener* listener){
|
||||
if(listener == NULL) return;
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ void load_idtr(int limit, int addr);
|
|||
|
||||
uint16_t inw(uint16_t port);
|
||||
|
||||
void copy_page_physical(uint32_t,uint32_t);
|
||||
|
||||
extern char read_port(unsigned short port);
|
||||
|
||||
static inline void outb(uint16_t port, uint8_t data) {
|
||||
|
|
|
@ -18,6 +18,7 @@ typedef struct {
|
|||
}KEY_MAP;
|
||||
|
||||
typedef struct key_listener{
|
||||
int lid;
|
||||
void (*func)(uint32_t key,int release,char c);
|
||||
struct key_listener *next;
|
||||
}kl_t;
|
||||
|
@ -25,5 +26,6 @@ typedef struct key_listener{
|
|||
void init_keyboard();
|
||||
int handle_keyboard_input();
|
||||
void add_listener(struct key_listener* listener);
|
||||
void remove_listener(int lid);
|
||||
|
||||
#endif //CRASHPOWEROS_KEYBOARD_H
|
||||
|
|
|
@ -63,6 +63,8 @@ uint32_t first_frame();
|
|||
|
||||
void page_fault(registers_t *regs);
|
||||
|
||||
page_directory_t *clone_directory(page_directory_t *src);
|
||||
|
||||
void flush_tlb();
|
||||
|
||||
void *ksbrk(int incr);
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef CRASHPOWEROS_PCAT_H
|
||||
#define CRASHPOWEROS_PCAT_H
|
||||
|
||||
#include "task.h"
|
||||
#include "fat16.h"
|
||||
|
||||
struct pcat_process{
|
||||
uint8_t is_e;
|
||||
};
|
||||
|
||||
void pcat_launch(struct task_struct *father,struct File *file);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef CRASHPOWEROS_SYSCALL_H
|
||||
#define CRASHPOWEROS_SYSCALL_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define SYSCALL_NUM 10
|
||||
|
||||
#define DEFN_SYSCALL0(fn, num) \
|
||||
int syscall_##fn() \
|
||||
{ \
|
||||
int a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL1(fn, num, P1) \
|
||||
int syscall_##fn(P1 p1) \
|
||||
{ \
|
||||
int a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL2(fn, num, P1, P2) \
|
||||
int syscall_##fn(P1 p1, P2 p2) \
|
||||
{ \
|
||||
int a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL3(fn, num, P1, P2, P3) \
|
||||
int syscall_##fn(P1 p1, P2 p2, P3 p3) \
|
||||
{ \
|
||||
int a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d"((int)p3)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL4(fn, num, P1, P2, P3, P4) \
|
||||
int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4) \
|
||||
{ \
|
||||
int a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d" ((int)p3), "S" ((int)p4)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL5(fn, num) \
|
||||
int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \
|
||||
{ \
|
||||
int a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d" ((int)p3), "S" ((int)p4), "D" ((int)p5)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
void syscall_install();
|
||||
|
||||
#endif
|
|
@ -11,6 +11,7 @@
|
|||
#include "../include/shell.h"
|
||||
#include "../include/date.h"
|
||||
#include "../include/acpi.h"
|
||||
#include "../include/syscall.h"
|
||||
|
||||
extern uint32_t end;
|
||||
extern int status;
|
||||
|
@ -60,6 +61,7 @@ void kernel_main(multiboot_t *multiboot) {
|
|||
init_keyboard();
|
||||
printf("[\035kernel\036]: Keyboard driver load success!\n");
|
||||
|
||||
syscall_install();
|
||||
print_cpu_id();
|
||||
io_sti();
|
||||
|
||||
|
|
|
@ -46,14 +46,14 @@ uint32_t first_frame() {
|
|||
}
|
||||
}
|
||||
}
|
||||
return (uint32_t) -1;
|
||||
return (uint32_t) - 1;
|
||||
}
|
||||
|
||||
void alloc_frame(page_t *page, int is_kernel, int is_writable) {
|
||||
if (page->frame) return;
|
||||
else {
|
||||
uint32_t idx = first_frame();
|
||||
if (idx == (uint32_t) -1) {
|
||||
if (idx == (uint32_t) - 1) {
|
||||
printf("FRAMES_FREE_ERROR: Cannot free frames!\n");
|
||||
asm("cli");
|
||||
for (;;)io_hlt();
|
||||
|
@ -110,57 +110,95 @@ void page_fault(registers_t *regs) {
|
|||
|
||||
printf("[ERROR]: Page fault |");
|
||||
if (present) {
|
||||
printf("Type: present;\n\taddress: %x ", faulting_address);
|
||||
if(current->pid == 0){
|
||||
printf(" ======= Kernel Error ======= ");
|
||||
printf("Type: present;\n\taddress: %x \n", faulting_address);
|
||||
if (current->pid == 0) {
|
||||
printf(" ======= Kernel Error ======= \n");
|
||||
while (1) io_hlt();
|
||||
} else{
|
||||
} else {
|
||||
current->state = TASK_ZOMBIE;
|
||||
printf("Taskkill process PID:%d Name:%s",current->pid,current->name);
|
||||
printf("Taskkill process PID:%d Name:%s\n", current->pid, current->name);
|
||||
}
|
||||
}
|
||||
else if (rw) {
|
||||
} else if (rw) {
|
||||
printf("Type: read-only;\n\taddress: %x", faulting_address);
|
||||
if(current->pid == 0){
|
||||
if (current->pid == 0) {
|
||||
printf(" ======= Kernel Error ======= ");
|
||||
while (1) io_hlt();
|
||||
} else{
|
||||
} else {
|
||||
current->state = TASK_ZOMBIE;
|
||||
printf("Taskkill process PID:%d Name:%s",current->pid,current->name);
|
||||
printf("Taskkill process PID:%d Name:%s", current->pid, current->name);
|
||||
}
|
||||
}
|
||||
else if (us) {
|
||||
} else if (us) {
|
||||
printf("Type: user-mode;\n\taddres: %x", faulting_address);
|
||||
if(current->pid == 0){
|
||||
if (current->pid == 0) {
|
||||
printf(" ======= Kernel Error ======= ");
|
||||
while (1) io_hlt();
|
||||
} else{
|
||||
} else {
|
||||
current->state = TASK_ZOMBIE;
|
||||
printf("Taskkill process PID:%d Name:%s",current->pid,current->name);
|
||||
printf("Taskkill process PID:%d Name:%s", current->pid, current->name);
|
||||
}
|
||||
}
|
||||
else if (reserved) {
|
||||
} else if (reserved) {
|
||||
printf("Type: reserved;\n\taddress: %x", faulting_address);
|
||||
if(current->pid == 0){
|
||||
if (current->pid == 0) {
|
||||
printf(" ======= Kernel Error ======= ");
|
||||
while (1) io_hlt();
|
||||
} else{
|
||||
} else {
|
||||
current->state = TASK_ZOMBIE;
|
||||
printf("Taskkill process PID:%d Name:%s",current->pid,current->name);
|
||||
printf("Taskkill process PID:%d Name:%s", current->pid, current->name);
|
||||
}
|
||||
}
|
||||
else if (id) {
|
||||
printf("Type: decode address;\n\taddress: %x", faulting_address);
|
||||
if(current->pid == 0){
|
||||
printf(" ======= Kernel Error ======= ");
|
||||
} else if (id) {
|
||||
printf("Type: decode address;\n\taddress: %x\n", faulting_address);
|
||||
if (current->pid == 0) {
|
||||
printf(" ======= Kernel Error ======= \n");
|
||||
while (1) io_hlt();
|
||||
} else{
|
||||
} else {
|
||||
current->state = TASK_ZOMBIE;
|
||||
printf("Taskkill process PID:%d Name:%s",current->pid,current->name);
|
||||
printf("Taskkill process PID:%d Name:%s\n", current->pid, current->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) {
|
||||
page_table_t *table = (page_table_t *) kmalloc_ap(sizeof(page_table_t), physAddr);
|
||||
memset(table, 0, sizeof(page_directory_t));
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 1024; i++) {
|
||||
if (!src->pages[i].frame)
|
||||
continue;
|
||||
alloc_frame(&table->pages[i], 0, 0);
|
||||
if (src->pages[i].present) table->pages[i].present = 1;
|
||||
if (src->pages[i].rw) table->pages[i].rw = 1;
|
||||
if (src->pages[i].user) table->pages[i].user = 1;
|
||||
if (src->pages[i].accessed)table->pages[i].accessed = 1;
|
||||
if (src->pages[i].dirty) table->pages[i].dirty = 1;
|
||||
copy_page_physical(src->pages[i].frame * 0x1000, table->pages[i].frame * 0x1000);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
page_directory_t *clone_directory(page_directory_t *src) {
|
||||
uint32_t phys;
|
||||
page_directory_t *dir = (page_directory_t *) kmalloc_ap(sizeof(page_directory_t), &phys);
|
||||
memset(dir, 0, sizeof(page_directory_t));
|
||||
|
||||
uint32_t offset = (uint32_t) dir->tablesPhysical - (uint32_t) dir;
|
||||
dir->physicalAddr = phys + offset;
|
||||
int i;
|
||||
for (i = 0; i < 1024; i++) {
|
||||
if (!src->tables[i])
|
||||
continue;
|
||||
if (kernel_directory->tables[i] == src->tables[i]) {
|
||||
dir->tables[i] = src->tables[i];
|
||||
dir->tablesPhysical[i] = src->tablesPhysical[i];
|
||||
} else {
|
||||
uint32_t phys;
|
||||
dir->tables[i] = clone_table(src->tables[i], &phys);
|
||||
dir->tablesPhysical[i] = phys | 0x07;
|
||||
}
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
void init_page() {
|
||||
uint32_t mem_end_page = 0xFFFFFFFF; // 4GB Page
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#include "../include/syscall.h"
|
||||
#include "../include/isr.h"
|
||||
|
||||
void syscall_handler(registers_t *regs){
|
||||
if (regs->eax >= SYSCALL_NUM)
|
||||
return;
|
||||
|
||||
void *location = NULL;//syscalls[regs->eax];
|
||||
|
||||
int ret;
|
||||
asm volatile (" \
|
||||
push %1; \
|
||||
push %2; \
|
||||
push %3; \
|
||||
push %4; \
|
||||
push %5; \
|
||||
call *%6; \
|
||||
pop %%ebx; \
|
||||
pop %%ebx; \
|
||||
pop %%ebx; \
|
||||
pop %%ebx; \
|
||||
pop %%ebx; \
|
||||
" : "=a" (ret) : "r" (regs->edi), "r" (regs->esi), "r" (regs->edx), "r" (regs->ecx), "r" (regs->ebx), "r" (location));
|
||||
regs->eax = ret;
|
||||
}
|
||||
|
||||
void syscall_install(){
|
||||
register_interrupt_handler(0x80,syscall_handler);
|
||||
}
|
|
@ -95,7 +95,7 @@ struct task_struct* found_task_pid(int pid){
|
|||
found_task(pid,running_proc_head,running_proc_head,&argv,1);
|
||||
if(argv == NULL){
|
||||
printf("Cannot found task Pid:[%d].\n",pid);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
return argv;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ void change_task_to(struct task_struct *next) {
|
|||
struct task_struct *prev = current;
|
||||
current = next;
|
||||
|
||||
//switch_page_directory(current->pgd_dir);
|
||||
switch_page_directory(current->pgd_dir);
|
||||
switch_to(&(prev->context), &(current->context));
|
||||
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ int32_t kernel_thread(int (*fn)(void *), void *arg,char* name) {
|
|||
new_task->state = TASK_RUNNABLE;
|
||||
new_task->stack = current;
|
||||
new_task->pid = now_pid++;
|
||||
new_task->pgd_dir = (page_directory_t *) kmalloc_a(sizeof(page_directory_t));
|
||||
new_task->pgd_dir = kernel_directory;
|
||||
|
||||
new_task->name = name;
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#include "../include/pcat.h"
|
||||
#include "../include/keyboard.h"
|
||||
#include <stddef.h>
|
||||
|
||||
struct task_struct *father_pcat;
|
||||
struct pcat_process *this_process;
|
||||
uint32_t pid_pcat;
|
||||
extern KEY_STATUS *key_status;
|
||||
|
||||
void pcat_key_listener(uint32_t key,int release,char c){
|
||||
|
||||
}
|
||||
|
||||
void start_pcat_thread(){
|
||||
this_process = (struct pcat_process*) kmalloc(sizeof(struct pcat_process));
|
||||
struct key_listener *listener = (struct key_listener*) kmalloc(sizeof(struct key_listener));
|
||||
listener->func = pcat_key_listener;
|
||||
listener->func = 2;
|
||||
add_listener(listener);
|
||||
while (1){
|
||||
if(key_status->is_ctrl){
|
||||
if(this_process->is_e){
|
||||
kfree(this_process);
|
||||
start_task(father_pcat);
|
||||
task_kill(get_current());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void pcat_launch(struct task_struct *father,struct File *file){
|
||||
father_pcat = father;
|
||||
pid_pcat = kernel_thread(start_pcat_thread,NULL,"CPOS-PCAT");
|
||||
wait_task(father);
|
||||
while (1){
|
||||
if(father->state != TASK_SLEEPING) break;
|
||||
}
|
||||
}
|
|
@ -5,8 +5,7 @@
|
|||
#include "../include/task.h"
|
||||
#include "../include/cmos.h"
|
||||
#include "../include/fat16.h"
|
||||
#include "../include/timer.h"
|
||||
#include "../include/io.h"
|
||||
#include "../include/pcat.h"
|
||||
|
||||
extern Queue *key_char_queue;
|
||||
|
||||
|
@ -211,6 +210,23 @@ void cmd_debug(){
|
|||
printf("ESI: 0x%08x | EDI 0x%08x | EBP 0x%08x | EFLAGS 0x%08x\n",esi,edi,ebp,get_current()->context.eflags);
|
||||
}
|
||||
|
||||
void cmd_pcat(int argc,char **argv){
|
||||
if (argc == 1) {
|
||||
|
||||
return;
|
||||
}
|
||||
char name[8] = {0};
|
||||
char ext[3] = {0};
|
||||
analyse_fullname(argv[1], name, ext);
|
||||
int isfind = find_file(name, ext, 0);
|
||||
struct File* file;
|
||||
if(isfind){
|
||||
file = open_file(argv[1]);
|
||||
} else file = create_file(argv[1]);
|
||||
|
||||
pcat_launch(get_current(),file);
|
||||
}
|
||||
|
||||
void setup_shell(){
|
||||
vga_clear();
|
||||
printf("%s for x86 [Version %s] \n",OS_NAME, OS_VERSION);
|
||||
|
@ -256,6 +272,8 @@ void setup_shell(){
|
|||
cmd_shutdown();
|
||||
else if (!strcmp("debug", argv[0]))
|
||||
cmd_debug();
|
||||
else if (!strcmp("pcat", argv[0]))
|
||||
cmd_pcat(argc,argv);
|
||||
else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) {
|
||||
vga_writestring("-=[\037CrashPowerShell Helper\036]=-\n");
|
||||
vga_writestring("help ? h \032Print shell help info.\036\n");
|
||||
|
@ -271,6 +289,7 @@ void setup_shell(){
|
|||
vga_writestring("reset \032Reset OS.\036\n");
|
||||
vga_writestring("shutdown exit \032Shutdown OS.\036\n");
|
||||
vga_writestring("debug \032Print os debug info.\036\n");
|
||||
vga_writestring("pcat [filename] \032Launch pcat application.\036\n");
|
||||
} else printf("\033[Shell]: Unknown command '%s'.\036\n", argv[0]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue