From 467dcef637d92fd178c78059a729be7436a136a6 Mon Sep 17 00:00:00 2001 From: hinus Date: Fri, 30 Jul 2021 00:24:16 +0800 Subject: [PATCH] Title: System call 'signal' and 'wait' Issue: https://gitee.com/hinus/linux_kernel_011/issues/I427NR https://gitee.com/hinus/linux_kernel_011/issues/I42WW5 Description: signal and wait. --- fs/exec.c | 9 ++++++ include/linux/mm.h | 1 + include/linux/sched.h | 9 ++++-- include/linux/sys.h | 42 ++++++++++++------------ include/signal.h | 74 +++++++++++++++++++++++++++++++++++++++++++ include/sys/types.h | 1 + kernel/Makefile | 5 ++- kernel/exit.c | 49 ++++++++++++++++++++++++++++ kernel/sched.c | 15 +++++++++ kernel/signal.c | 22 +++++++++++++ kernel/sys.c | 4 +++ lib/wait.c | 11 +++++++ mm/memory.c | 2 +- 13 files changed, 219 insertions(+), 25 deletions(-) create mode 100644 include/signal.h create mode 100644 kernel/exit.c create mode 100644 kernel/signal.c create mode 100644 lib/wait.c diff --git a/fs/exec.c b/fs/exec.c index f839b67..3b5427b 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -201,6 +202,14 @@ int do_execve(unsigned long * eip,long tmp,char * filename, iput(current->executable); current->executable = inode; + current->signal = 0; + for (i=0 ; i<32 ; i++) { + current->sigaction[i].sa_mask = 0; + current->sigaction[i].sa_flags = 0; + if (current->sigaction[i].sa_handler != SIG_IGN) + current->sigaction[i].sa_handler = NULL; + } + for (i=0 ; iclose_on_exec>>i)&1) sys_close(i); diff --git a/include/linux/mm.h b/include/linux/mm.h index e7d2e6d..4dc35da 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -6,6 +6,7 @@ #define PAGE_SIZE 4096 extern unsigned long get_free_page(); +extern unsigned long put_dirty_page(unsigned long page,unsigned long address); extern void free_page(unsigned long addr); extern inline void oom(); diff --git a/include/linux/sched.h b/include/linux/sched.h index 1791e7d..8c08d6f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -21,6 +21,7 @@ #include #include #include +#include #define TASK_RUNNING 0 #define TASK_INTERRUPTIBLE 1 @@ -79,6 +80,9 @@ struct task_struct { long state; long counter; long priority; + long signal; + struct sigaction sigaction[32]; + long blocked; long pid; unsigned long start_code,end_code,end_data,brk,start_stack; struct task_struct *p_pptr, *p_cptr, *p_ysptr, *p_osptr; @@ -104,6 +108,7 @@ struct task_struct { 0, \ 15, \ 15, \ +/* signals */ 0,{{},},0, \ 0, \ /* ec,brk... */ 0,0,0,0,0, \ &init_task.task, 0, 0, 0,\ @@ -112,8 +117,8 @@ struct task_struct { {NULL,}, \ { \ {0, 0}, \ - {0xfff, 0xc0fa00}, \ - {0xfff, 0xc0f200}, \ + {0x9f, 0xc0fa00}, \ + {0x9f, 0xc0f200}, \ }, \ {0, PAGE_SIZE + (long)&init_task, 0x10, 0, 0, 0, 0, (long)&pg_dir, \ 0, 0, 0, 0, 0, 0, 0, 0, \ diff --git a/include/linux/sys.h b/include/linux/sys.h index 5d66342..0a65c9c 100644 --- a/include/linux/sys.h +++ b/include/linux/sys.h @@ -46,7 +46,7 @@ extern int sys_dup(); //extern int sys_brk(); //extern int sys_setgid(); //extern int sys_getgid(); -//extern int sys_signal(); +extern int sys_signal(); //extern int sys_geteuid(); //extern int sys_getegid(); //extern int sys_acct(); @@ -56,7 +56,7 @@ extern int sys_dup(); //extern int sys_fcntl(); //extern int sys_mpx(); //extern int sys_setpgid(); -//extern int sys_ulimit(); +extern int sys_ulimit(); //extern int sys_uname(); //extern int sys_umask(); //extern int sys_chroot(); @@ -135,25 +135,25 @@ fn_ptr sys_call_table[] = { sys_rmdir, sys_dup, -// sys_pipe, -// sys_times, -// sys_prof, -// sys_brk, -// sys_setgid, -// -// sys_getgid, -// sys_signal, -// sys_geteuid, -// sys_getegid, -// sys_acct, -// sys_phys, -// -// sys_lock, -// sys_ioctl, -// sys_fcntl, -// sys_mpx, -// sys_setpgid, -// sys_ulimit, + 0, // sys_pipe, + 0, // sys_times, + 0, // sys_prof, + 0, // sys_brk, + 0, // sys_setgid, + + 0, // sys_getgid, + sys_signal, + 0, // sys_geteuid, + 0, // sys_getegid, + 0, // sys_acct, + 0, // sys_phys, + + 0, // sys_lock, + 0, // sys_ioctl, + 0, // sys_fcntl, + 0, // sys_mpx, + 0, // sys_setpgid, + sys_ulimit, // // sys_uname, // sys_umask, diff --git a/include/signal.h b/include/signal.h new file mode 100644 index 0000000..a5a01f9 --- /dev/null +++ b/include/signal.h @@ -0,0 +1,74 @@ +#ifndef _SIGNAL_H +#define _SIGNAL_H + +#include + +typedef int sig_atomic_t; +typedef unsigned int sigset_t; + +#define _NSIG 32 +#define NSIG _NSIG + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGUNUSED 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 + +#define SA_NOCLDSTOP 1 +#define SA_INTERRUPT 0x20000000 +#define SA_NOMASK 0x40000000 +#define SA_ONESHOT 0x80000000 + +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 +#define SIG_SETMASK 2 + +#define SIG_DFL ((void (*)(int))0) +#define SIG_IGN ((void (*)(int))1) +#define SIG_ERR ((void (*)(int))-1) + +#ifdef notdef +#define sigemptyset(mask) ((*(mask) = 0), 1) +#define sigfillset(mask) ((*(mask) = ~0), 1) +#endif + +struct sigaction { + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; + void (*sa_restorer)(void); +}; + +void (*signal(int _sig, void (*_func)(int)))(int); +int raise(int sig); +int kill(pid_t pid, int sig); +int sigaddset(sigset_t *mask, int signo); +int sigdelset(sigset_t *mask, int signo); +int sigemptyset(sigset_t *mask); +int sigfillset(sigset_t *mask); +int sigismember(sigset_t *mask, int signo); +int sigpending(sigset_t *set); +int sigprocmask(int how, sigset_t *set, sigset_t *oldset); +int sigsuspend(sigset_t *sigmask); +int sigaction(int sig, struct sigaction *act, struct sigaction *oldact); + +#endif diff --git a/include/sys/types.h b/include/sys/types.h index d5c3861..c138035 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -3,6 +3,7 @@ typedef long off_t; +typedef int pid_t; typedef unsigned short mode_t; typedef unsigned short ino_t; typedef unsigned short gid_t; diff --git a/kernel/Makefile b/kernel/Makefile index 157b8f3..7c5d5c0 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -3,7 +3,7 @@ CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno- LDFLAG := -Ttext 0x0 -s --oformat binary -m elf_i386 INCDIR := ../include OBJS := head.o main.o sys_call.o asm.o sched.o printk.o vsprintf.o mktime.o \ - traps.o fork.o panic.o sys.o \ + traps.o fork.o panic.o sys.o signal.o \ chr_drv/chr_drv.a blk_drv/blk_drv.a ../mm/mm.o ../lib/lib.a ../fs/fs.o system: $(OBJS) @@ -45,6 +45,9 @@ mktime.o : mktime.c sys.o : sys.c $(GCC) $(CCFLAG) -o $@ $< +signal.o : signal.c + $(GCC) $(CCFLAG) -o $@ $< + chr_drv/chr_drv.a: chr_drv/*.c cd chr_drv; make chr_drv.a; cd .. diff --git a/kernel/exit.c b/kernel/exit.c new file mode 100644 index 0000000..0bad7ef --- /dev/null +++ b/kernel/exit.c @@ -0,0 +1,49 @@ +#define DEBUG_PROC_TREE + +#include +#include +#include + +#include +#include +#include +#include + +extern int sys_pause(); +extern int sys_close(int fd); + +volatile void do_exit(long code) { + struct task_struct *p; + int i; + + free_page_tables(get_base(current->ldt[1]),get_limit(0x0f)); + free_page_tables(get_base(current->ldt[2]),get_limit(0x17)); + + for (i=0 ; ifilp[i]) + sys_close(i); + } + + iput(current->pwd); + current->pwd = NULL; + iput(current->root); + current->root = NULL; + iput(current->executable); + current->executable = NULL; + iput(current->library); + current->library = NULL; + current->state = TASK_ZOMBIE; + current->exit_code = code; + + if ((current->p_pptr->pgrp != current->pgrp) && + (current->p_pptr->session == current->session) && + is_orphaned_pgrp(current->pgrp) && + has_stopped_jobs(current->pgrp)) { + + +} + +int sys_exit(int error_code) { + do_exit((error_code&0xff)<<8); +} + diff --git a/kernel/sched.c b/kernel/sched.c index 01a9c47..a172eed 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4,6 +4,12 @@ #include #include #include +#include + +#include + +#define _S(nr) (1<<((nr)-1)) +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) #define COUNTER 100 @@ -39,6 +45,15 @@ void schedule() { int i,next,c; struct task_struct ** p; + for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if (!(*p)) + continue; + + if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) && + (*p)->state==TASK_INTERRUPTIBLE) + (*p)->state=TASK_RUNNING; + } + while(1) { c = -1; next = 0; diff --git a/kernel/signal.c b/kernel/signal.c new file mode 100644 index 0000000..018dd04 --- /dev/null +++ b/kernel/signal.c @@ -0,0 +1,22 @@ +#include +#include +#include + +#include +#include + +int sys_signal(int signum, long handler, long restorer) { + struct sigaction tmp; + + if (signum<1 || signum>32 || signum==SIGKILL || signum==SIGSTOP) + return -EINVAL; + + tmp.sa_handler = (void (*)(int)) handler; + tmp.sa_mask = 0; + tmp.sa_flags = SA_ONESHOT | SA_NOMASK; + tmp.sa_restorer = (void (*)(void)) restorer; + handler = (long) current->sigaction[signum-1].sa_handler; + current->sigaction[signum-1] = tmp; + return handler; +} + diff --git a/kernel/sys.c b/kernel/sys.c index 9b2a9d1..8c89258 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -16,6 +16,10 @@ int sys_time(long * tloc) { return i; } +int sys_ulimit() { + return -ENOSYS; +} + int in_group_p(gid_t grp) { int i; if (grp == current->egid) diff --git a/lib/wait.c b/lib/wait.c new file mode 100644 index 0000000..f487d39 --- /dev/null +++ b/lib/wait.c @@ -0,0 +1,11 @@ +#define __LIBRARY__ +#include + +#include + +_syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +pid_t wait(int * wait_stat) { + return waitpid(-1,wait_stat,0); +} + diff --git a/mm/memory.c b/mm/memory.c index 8f7eec9..e8a6288 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -254,7 +254,7 @@ void do_no_page(unsigned long error_code,unsigned long address) { struct m_inode * inode; if (address < TASK_SIZE) - printk("\n\rBAD!! KERNEL PAGE MISSING\n\r"); + printk("\n\rBAD!! KERNEL PAGE MISSING %x\n\r", address); if (address - current->start_code > TASK_SIZE) { printk("Bad things happen: nonexistent page error in do_no_page\n\r"); //do_exit(); -- Gitee