babyos2(9)——系统调用

来源:互联网 发布:小猪php在线解密 编辑:程序博客网 时间:2024/06/06 05:31

如果说外部中断是CPU被动地、异步地进入系统空间的一种手段,那么系统调用就是CPU主动地、同步地进入系统空间的手段。
babyos2通过0x80号中断实现系统调用。

void cpu_t::do_common_isr(trap_frame_t* frame){    uint32 trapno = frame->trapno;    if (trapno < IRQ_0) {        do_exception(frame);    }    else if (trapno < IRQ_0 + IRQ_NUM) {        do_interrupt(trapno);    }    else if (trapno == IRQ_SYSCALL) {        do_syscall(frame);    }    else {        console()->kprintf(RED, "Interrupt: %x, NOT KNOWN\n", frame->trapno);    }}void cpu_t::do_syscall(trap_frame_t* frame){    m_syscall.do_syscall(frame);}
void syscall_t::do_syscall(trap_frame_t* frame){    uint32 id = frame->eax;    if (id >= MAX_SYSCALL) {        console()->kprintf(RED, "unknown system call %x, current: %p\n", id, current->m_pid);        frame->eax = -1;    }    else {        frame->eax = system_call_table[id](frame);    }}

系统调用处理通过上面这个函数执行,系统调用号存放在eax中,因为进行系统调用前,会把系统调用号放到eax中:

void print(char *str){    __asm__ volatile("int $0x80" : : "b" (str), "a" (0x00));}

system_call_table是一个表,表中存放了所有支持的系统调用。

/* * guzhoudiaoke@126.com * 2017-10-30 */#ifndef _SYSCALL_H_#define _SYSCALL_H_#include "types.h"//#define SYS_PRINT 0//#define MAX_SYSCALL 1enum {    SYS_PRINT = 0,    SYS_FORK,    SYS_EXEC,    MAX_SYSCALL,};class syscall_t {public:    syscall_t();    ~syscall_t();    void do_syscall(trap_frame_t* frame);private:};#endif

比如目前只支持:
SYS_PRINT,
SYS_FORK,
SYS_EXEC,
三个系统调用。

/* * guzhoudiaoke@126.com * 2017-10-30 */#include "syscall.h"#include "babyos.h"#include "ide.h"#include "string.h"extern int32 sys_print(trap_frame_t* frame);extern int32 sys_fork(trap_frame_t* frame);extern int32 sys_exec(trap_frame_t* frame);static int32 (*system_call_table[])(trap_frame_t* frame) = {    sys_print,    sys_fork,    sys_exec,};int32 sys_print(trap_frame_t* frame){    // FIXME: need copy from user    console()->kprintf(GREEN, "%s", frame->ebx);}

之前做到这里的时候,完成sys_print后,在内核态通过int 0x80试了下,可以正常打印信息,但忘记截图了,这里先不贴了。
下一步是最重要的一步,将会涉及进程,调度,fork,exec,及进入用户空间,会大量用到系统调用。

原创粉丝点击