🆕 syscall模块,实现了第一个系统调用函数sys_printf

This commit is contained in:
fslongjin 2022-02-16 14:07:53 +08:00
parent 7238e3c13a
commit d3a5048f66
11 changed files with 219 additions and 8 deletions

View File

@ -56,7 +56,7 @@ bximage
- [ ] IPC进程间通信
- [ ] 第一个系统调用函数
- [x] 第一个系统调用函数
- [ ] 在物理平台上启动DragonOS

View File

@ -56,7 +56,7 @@ bximage
- [ ] IPC
- [ ] First system call function
- [x] First system call function
- [ ] Start dragonos on the physical platform

View File

@ -10,8 +10,8 @@ all: kernel
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary kernel ../bin/kernel/kernel.bin
kernel: head.o entry.o main.o printk.o trap.o mm.o irq.o 8259A.o process.o
ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o exception/8259A.o mm/mm.o process/process.o -T link.lds
kernel: head.o entry.o main.o printk.o trap.o mm.o irq.o 8259A.o process.o syscall.o
ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o exception/8259A.o mm/mm.o process/process.o syscall/syscall.o -T link.lds
head.o: head.S
gcc -E head.S > head.s # 预处理
@ -46,6 +46,8 @@ mm.o: mm/mm.c
process.o: process/process.c
gcc -mcmodel=large -fno-builtin -m64 -c process/process.c -o process/process.o
syscall.o: syscall/syscall.c
gcc -mcmodel=large -fno-builtin -m64 -c syscall/syscall.c -o syscall/syscall.o
clean:
rm -rf $(GARBAGE)

View File

@ -99,6 +99,46 @@ Err_Code:
jmp ret_from_exception
//
//
ENTRY(system_call)
// sysenter
sti;
subq $0x38, %rsp
cld;
pushq %rax
movq %es, %rax
pushq %rax
movq %ds, %rax
pushq %rax
pushq %rbp
pushq %rdi
pushq %rsi
pushq %rdx
pushq %rcx
pushq %rbx
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r14
pushq %r15
movq $0x10, %rdx
movq %rdx, %ds
movq %rdx, %es
// rspsystem_call_function
movq %rsp, %rdi
callq system_call_function
//
ENTRY(ret_from_system_call)
movq %rax, 0x80(%rsp) // raxrax

View File

@ -212,7 +212,21 @@ void do_general_protection(struct pt_regs * regs, unsigned long error_code)
printk("[ ");
printk_color(RED, BLACK, "ERROR");
printk(" ] do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, regs->rsp, regs->rip);
return;
if(error_code & 0x01)
printk_color(RED,BLACK,"The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n");
if(error_code & 0x02)
printk_color(RED,BLACK,"Refers to a gate descriptor in the IDT;\n");
else
printk_color(RED,BLACK,"Refers to a descriptor in the GDT or the current LDT;\n");
if((error_code & 0x02) == 0)
if(error_code & 0x04)
printk_color(RED,BLACK,"Refers to a segment or gate descriptor in the LDT;\n");
else
printk_color(RED,BLACK,"Refers to a descriptor in the current GDT;\n");
printk_color(RED,BLACK,"Segment Selector Index:%#010x\n",error_code & 0xfff8);
while (1)
;
}

View File

@ -10,6 +10,7 @@
#include "exception/irq.h"
#include "mm/mm.h"
#include "process/process.h"
#include "syscall/syscall.h"
unsigned int *FR_address = (unsigned int *)0xffff800000a00000; //帧缓存区的地址
// char fxsave_region[512] __attribute__((aligned(16)));
@ -84,6 +85,9 @@ void system_initialize()
// 初始化中断模块
init_irq();
// 先初始化系统调用模块
syscall_init();
// 再初始化进程模块。顺序不能调转
process_init();
}

View File

@ -3,6 +3,8 @@
#include "../exception/gate.h"
#include "../common/printk.h"
#include "../common/kprint.h"
#include "../syscall/syscall.h"
#include "../syscall/syscall_num.h"
/**
* @brief
@ -28,6 +30,7 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs));
}
/**
* @brief
*
@ -35,6 +38,12 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
void user_level_function()
{
kinfo("Program (user_level_function) is runing...");
kinfo("Try to enter syscall id 15...");
enter_syscall(15,0,0,0,0,0,0,0,0);
enter_syscall(SYS_PRINTF, (ul)"test_sys_printf\n", 0,0,0,0,0,0,0);
kinfo("Return from syscall id 15...");
while(1);
}
@ -169,6 +178,10 @@ int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigne
return do_fork(&regs, flags, 0, 0);
}
/**
* @brief
*
*/
void process_init()
{
@ -188,8 +201,7 @@ void process_init()
initial_mm.stack_start = _stack_start;
// 向MSR寄存器组中的 IA32_SYSENTER_CS寄存器写入内核的代码段的地址
wrmsr(0x174, KERNEL_CS);
// 初始化进程和tss
set_TSS64(initial_thread.rbp, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1, initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);

View File

@ -13,11 +13,12 @@
#include "../common/cpu.h"
#include "../common/glib.h"
#include "../mm/mm.h"
#include "../syscall/syscall.h"
#include "ptrace.h"
extern unsigned long _stack_start; // 导出内核层栈基地址定义在head.S
extern void ret_from_intr(void); // 导出从中断返回的函数定义在entry.S
extern void ret_from_system_call(void); // 导出从中断返回的函数定义在entry.S
// 进程的内核栈大小 32K
#define STACK_SIZE 32768

72
kernel/syscall/syscall.c Normal file
View File

@ -0,0 +1,72 @@
#include "syscall.h"
#include "../process/process.h"
// 导出系统调用入口函数定义在entry.S中
extern void system_call(void);
/**
* @brief entry.S中跳转到这里
*
* @param regs 3,rax存储系统调用号
* @return ul
*/
ul system_call_function(struct pt_regs *regs)
{
return system_call_table[regs->rax](regs);
}
/**
* @brief
*
*/
void syscall_init()
{
// 向MSR寄存器组中的 IA32_SYSENTER_CS寄存器写入内核的代码段的地址
wrmsr(0x174, KERNEL_CS);
// 向MSR寄存器组中的 IA32_SYSENTER_ESP寄存器写入内核进程的rbp在syscall入口中会将rsp减去相应的数值
wrmsr(0x175, current_pcb->thread->rbp);
// 向MSR寄存器组中的 IA32_SYSENTER_EIP寄存器写入系统调用入口的地址。
wrmsr(0x176, (ul)system_call);
}
long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
{
long err_code;
__asm__ __volatile__("leaq sysexit_return_address(%%rip), %%rdx \n\t"
"movq %%rsp, %%rcx \n\t"
"movq %2, %%r8 \n\t"
"movq %3, %%r9 \n\t"
"movq %4, %%r10 \n\t"
"movq %5, %%r11 \n\t"
"movq %6, %%r12 \n\t"
"movq %7, %%r13 \n\t"
"movq %8, %%r14 \n\t"
"movq %9, %%r15 \n\t"
"sysenter \n\t"
"sysexit_return_address: \n\t"
: "=a"(err_code)
: "0"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6), "m"(arg7)
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
return err_code;
}
/**
* @brief
*
* arg1和arg2均为0时
*
* @param regs
* @param arg0
* @param arg1
* @param arg2
* @return ul
*/
ul sys_printf(struct pt_regs *regs)
{
if(regs->r9 == 0 &&regs->r10 == 0)
printk((char*)regs->r8);
else printk_color(regs->r9, regs->r10, (char*)regs->r8);
return 0;
}

62
kernel/syscall/syscall.h Normal file
View File

@ -0,0 +1,62 @@
#pragma once
#include "../common/glib.h"
#include "../common/kprint.h"
#include "../process/ptrace.h"
// 定义最大系统调用数量
#define MAX_SYSTEM_CALL_NUM 128
#define ESYSCALL_NOT_EXISTS 1
typedef unsigned long (*system_call_t)(struct pt_regs *regs);
extern void ret_from_system_call(void); // 导出从系统调用返回的函数定义在entry.S
/**
* @brief
*
*/
void syscall_init();
/**
* @brief
*
* @param syscall_id id
* @return long
*/
long enter_syscall(ul syscall_id,ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7);
/**
* @brief
*
* @param regs 3
* @return ul
*/
ul system_call_not_exists(struct pt_regs *regs)
{
kerror("System call [ ID #%d ] not exists.", regs->rax);
return ESYSCALL_NOT_EXISTS;
}
/**
* @brief
*
* arg1和arg2均为0时
*
* @param regs
* @param arg0
* @param arg1
* @param arg2
* @return ul
*/
ul sys_printf(struct pt_regs *regs);
system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
{
[0] = system_call_not_exists,
[1] = sys_printf,
[2 ... MAX_SYSTEM_CALL_NUM - 1] = system_call_not_exists
};

View File

@ -0,0 +1,4 @@
#pragma once
#define SYS_NOT_EXISTS 0
#define SYS_PRINTF 1