From 9d92959c61e5f8483012fe71030ef3a338f66dec Mon Sep 17 00:00:00 2001 From: hinus Date: Fri, 30 Jul 2021 10:19:09 +0800 Subject: [PATCH 1/2] Title: ioctl and other little sys calls. Issue: https://gitee.com/hinus/linux_kernel_011/issues/I431WK Description: ioctl and other little sys calls. --- fs/Makefile | 5 ++- fs/ioctl.c | 10 +++++ include/linux/sys.h | 96 ++++++++++++++++++++--------------------- kernel/blk_drv/floppy.c | 2 +- kernel/main.c | 6 +-- kernel/sched.c | 30 +++++++++++++ 6 files changed, 96 insertions(+), 53 deletions(-) create mode 100644 fs/ioctl.c diff --git a/fs/Makefile b/fs/Makefile index e2f2bcb..7229ab7 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -4,7 +4,7 @@ CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno- LDFLAG := -Ttext 0x0 -s --oformat binary -m elf_i386 INCDIR := ../include OBJS := read_write.o buffer.o super.o open.o file_table.o inode.o namei.o fcntl.o char_dev.o \ - bitmap.o truncate.o exec.o + bitmap.o truncate.o exec.o ioctl.o fs.o : $(OBJS) $(LD) -m elf_i386 -r -o $@ $^ @@ -45,6 +45,9 @@ truncate.o : truncate.c exec.o : exec.c $(GCC) $(CCFLAG) -o $@ $< +ioctl.o : ioctl.c + $(GCC) $(CCFLAG) -o $@ $< + clean : -rm *.o diff --git a/fs/ioctl.c b/fs/ioctl.c new file mode 100644 index 0000000..69ca840 --- /dev/null +++ b/fs/ioctl.c @@ -0,0 +1,10 @@ + +#include +#include +#include + +#include +int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { + return 0; +} + diff --git a/include/linux/sys.h b/include/linux/sys.h index e2e4712..94e846b 100644 --- a/include/linux/sys.h +++ b/include/linux/sys.h @@ -11,18 +11,18 @@ extern int sys_close(); //extern int sys_unlink(); extern int sys_execve(); extern int sys_chdir(); -//extern int sys_time(); +extern int sys_time(); //extern int sys_mknod(); //extern int sys_chmod(); //extern int sys_chown(); //extern int sys_break(); //extern int sys_stat(); //extern int sys_lseek(); -//extern int sys_getpid(); +extern int sys_getpid(); //extern int sys_mount(); //extern int sys_umount(); //extern int sys_setuid(); -//extern int sys_getuid(); +extern int sys_getuid(); //extern int sys_stime(); //extern int sys_ptrace(); //extern int sys_alarm(); @@ -32,7 +32,7 @@ extern int sys_fstat(); //extern int sys_stty(); //extern int sys_gtty(); //extern int sys_access(); -//extern int sys_nice(); +extern int sys_nice(); //extern int sys_ftime(); extern int sys_sync(); //extern int sys_kill(); @@ -45,14 +45,14 @@ extern int sys_dup(); //extern int sys_prof(); extern int sys_brk(); //extern int sys_setgid(); -//extern int sys_getgid(); +extern int sys_getgid(); extern int sys_signal(); -//extern int sys_geteuid(); -//extern int sys_getegid(); +extern int sys_geteuid(); +extern int sys_getegid(); //extern int sys_acct(); //extern int sys_phys(); //extern int sys_lock(); -//extern int sys_ioctl(); +extern int sys_ioctl(); //extern int sys_fcntl(); //extern int sys_mpx(); //extern int sys_setpgid(); @@ -62,7 +62,7 @@ extern int sys_ulimit(); //extern int sys_chroot(); //extern int sys_ustat(); //extern int sys_dup2(); -//extern int sys_getppid(); +extern int sys_getppid(); //extern int sys_getpgrp(); //extern int sys_setsid(); //extern int sys_sigaction(); @@ -101,7 +101,7 @@ fn_ptr sys_call_table[] = { 0, //sys_unlink, sys_execve, sys_chdir, - 0, //sys_time, + sys_time, 0, //sys_mknod, 0, //sys_chmod, @@ -109,12 +109,12 @@ fn_ptr sys_call_table[] = { 0, //sys_break, 0, //sys_stat, 0, //sys_lseek, - 0, //sys_getpid, + sys_getpid, 0, //sys_mount, 0, //sys_umount, 0, //sys_setuid, - 0, //sys_getuid, + sys_getuid, 0, //sys_stime, 0, //sys_ptrace, 0, //sys_alarm, @@ -126,7 +126,7 @@ fn_ptr sys_call_table[] = { 0, //sys_gtty, 0, //sys_access, - 0, //sys_nice, + sys_nice, 0, //sys_ftime, sys_sync, 0, //sys_kill, @@ -141,50 +141,50 @@ fn_ptr sys_call_table[] = { sys_brk, 0, // sys_setgid, - 0, // sys_getgid, + sys_getgid, sys_signal, - 0, // sys_geteuid, - 0, // sys_getegid, + sys_geteuid, + sys_getegid, 0, // sys_acct, 0, // sys_phys, 0, // sys_lock, - 0, // sys_ioctl, + sys_ioctl, 0, // sys_fcntl, 0, // sys_mpx, 0, // sys_setpgid, sys_ulimit, -// -// sys_uname, -// sys_umask, -// sys_chroot, -// sys_ustat, -// sys_dup2, -// sys_getppid, -// -// sys_getpgrp, -// sys_setsid, -// sys_sigaction, -// sys_sgetmask, -// sys_ssetmask, -// -// sys_setreuid, -// sys_setregid, -// sys_sigsuspend, -// sys_sigpending, -// sys_sethostname, -// sys_setrlimit, -// sys_getrlimit, -// sys_getrusage, -// sys_gettimeofday, -// sys_settimeofday, -// sys_getgroups, -// sys_setgroups, -// sys_select, -// sys_symlink, -// sys_lstat, -// sys_readlink, -// sys_uselib + + 0, // sys_uname, + 0, // sys_umask, + 0, // sys_chroot, + 0, // sys_ustat, + 0, // sys_dup2, + sys_getppid, + 0, // + 0, // sys_getpgrp, + 0, // sys_setsid, + 0, // sys_sigaction, + 0, // sys_sgetmask, + 0, // sys_ssetmask, + 0, // + 0, // sys_setreuid, + 0, // sys_setregid, + 0, // sys_sigsuspend, + 0, // sys_sigpending, + 0, // sys_sethostname, + 0, // sys_setrlimit, + 0, // sys_getrlimit, + 0, // sys_getrusage, + 0, // sys_gettimeofday, + 0, // sys_settimeofday, + 0, // sys_getgroups, + 0, // sys_setgroups, + 0, // sys_select, + 0, // sys_symlink, + 0, // sys_lstat, + 0, // sys_readlink, + 0, // sys_uselib }; int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr); diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c index 9e559e5..acd73b0 100644 --- a/kernel/blk_drv/floppy.c +++ b/kernel/blk_drv/floppy.c @@ -167,7 +167,7 @@ void rw_interrupt() { } void setup_rw_floppy() { - printk("setup_rw_floppy\n"); + //printk("setup_rw_floppy\n"); setup_DMA(); do_floppy = rw_interrupt; output_byte(command); diff --git a/kernel/main.c b/kernel/main.c index 2bfc461..ba57c43 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -146,12 +146,12 @@ void init() { (void) dup(0); (void) dup(0); - /* if (!(pid=fork())) { printf("read to start shell\n"); execve("/bin/sh",argv,envp); - }*/ + } + /* while (1) { i = read(0, a, 9); a[i - 1] = 0; @@ -174,7 +174,7 @@ void init() { else if (strcmp(a, "sy") == 0) { sync(); } - } + }*/ printf("Free mem: %d bytes\n\r",memory_end-main_memory_start); } diff --git a/kernel/sched.c b/kernel/sched.c index a172eed..8a2b30f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -249,6 +249,36 @@ void do_timer(long cpl) { schedule(); } +int sys_getpid() { + return current->pid; +} + +int sys_getppid() { + return current->p_pptr->pid; +} + +int sys_getuid() { + return current->uid; +} + +int sys_geteuid() { + return current->euid; +} + +int sys_getgid() { + return current->gid; +} + +int sys_getegid() { + return current->egid; +} + +int sys_nice(long increment) { + if (current->priority-increment>0) + current->priority -= increment; + return 0; +} + void sched_init() { int i; struct desc_struct * p; -- Gitee From 1748f59f9aec0fcb47d7e4cb14eaf4d7a2fa3838 Mon Sep 17 00:00:00 2001 From: hinus Date: Fri, 30 Jul 2021 19:57:00 +0800 Subject: [PATCH 2/2] Title: system call 'exit' Issue: https://gitee.com/hinus/linux_kernel_011/issues/I438I9 Description: exit and pause. --- include/linux/sched.h | 18 ++++-- include/linux/sys.h | 8 +-- include/linux/tty.h | 7 +++ include/sys/param.h | 1 + include/sys/wait.h | 6 ++ kernel/Makefile | 5 +- kernel/chr_drv/tty_io.c | 1 + kernel/exit.c | 120 +++++++++++++++++++++++++++++++++++++++- kernel/main.c | 37 ++++++++----- kernel/sched.c | 6 ++ mm/memory.c | 2 +- 11 files changed, 186 insertions(+), 25 deletions(-) create mode 100644 include/sys/wait.h diff --git a/include/linux/sched.h b/include/linux/sched.h index 8c08d6f..dd2d223 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #define TASK_RUNNING 0 @@ -83,11 +84,17 @@ struct task_struct { long signal; struct sigaction sigaction[32]; long blocked; - long pid; + int exit_code; unsigned long start_code,end_code,end_data,brk,start_stack; + long pid,pgrp,session,leader; + int groups[NGROUPS]; struct task_struct *p_pptr, *p_cptr, *p_ysptr, *p_osptr; unsigned short uid,euid,suid; unsigned short gid,egid,sgid; + unsigned long timeout,alarm; + long utime,stime,cutime,cstime,start_time; + + unsigned int flags; /* file info */ int tty; @@ -109,10 +116,13 @@ struct task_struct { 15, \ 15, \ /* signals */ 0,{{},},0, \ - 0, \ -/* ec,brk... */ 0,0,0,0,0, \ +/* ec,brk... */ 0, 0,0,0,0,0, \ +/* pid etc.. */ 0,0,0,0, \ +/* suppl grps*/ {NOGROUP,}, \ &init_task.task, 0, 0, 0,\ - 0,0,0,0,0,0, \ +/* uid etc */ 0,0,0,0,0,0, \ +/* timeout */ 0,0,0,0,0,0,0, \ +/* flags */ 0, \ 0,0022,NULL,NULL,NULL,NULL,0, \ {NULL,}, \ { \ diff --git a/include/linux/sys.h b/include/linux/sys.h index 94e846b..3c7ba08 100644 --- a/include/linux/sys.h +++ b/include/linux/sys.h @@ -1,5 +1,5 @@ extern int sys_setup(); -//extern int sys_exit(); +extern int sys_exit(); extern int sys_fork(); extern int sys_read(); extern int sys_write(); @@ -27,7 +27,7 @@ extern int sys_getuid(); //extern int sys_ptrace(); //extern int sys_alarm(); extern int sys_fstat(); -//extern int sys_pause(); +extern int sys_pause(); //extern int sys_utime(); //extern int sys_stty(); //extern int sys_gtty(); @@ -88,7 +88,7 @@ extern int sys_getppid(); fn_ptr sys_call_table[] = { sys_setup, - 0, /*sys_exit*/ + sys_exit, sys_fork, sys_read, sys_write, @@ -120,7 +120,7 @@ fn_ptr sys_call_table[] = { 0, //sys_alarm, sys_fstat, - 0, //sys_pause, + sys_pause, 0, //sys_utime, 0, //sys_stty, 0, //sys_gtty, diff --git a/include/linux/tty.h b/include/linux/tty.h index fec7ad9..23a76b1 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -34,6 +34,7 @@ struct tty_queue { struct tty_struct { struct termios termios; int pgrp; + int session; int stopped; void (*write)(struct tty_struct * tty); struct tty_queue read_q; @@ -41,6 +42,12 @@ struct tty_struct { struct tty_queue secondary; }; +extern struct tty_struct tty_table[]; +extern int fg_console; + +#define TTY_TABLE(nr) \ +(tty_table + ((nr) ? (((nr) < 64)? (nr)-1:(nr)) : fg_console)) + #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" void con_init(); diff --git a/include/sys/param.h b/include/sys/param.h index 3963ebb..2f23377 100644 --- a/include/sys/param.h +++ b/include/sys/param.h @@ -2,5 +2,6 @@ #define _PARAM_H #define NGROUPS 32 +#define NOGROUP -1 #endif diff --git a/include/sys/wait.h b/include/sys/wait.h new file mode 100644 index 0000000..e34e095 --- /dev/null +++ b/include/sys/wait.h @@ -0,0 +1,6 @@ +#ifndef _SYS_WAIT_H +#define _SYS_WAIT_H + + + +#endif diff --git a/kernel/Makefile b/kernel/Makefile index 7c5d5c0..2d048e0 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 signal.o \ + traps.o fork.o panic.o sys.o signal.o exit.o \ chr_drv/chr_drv.a blk_drv/blk_drv.a ../mm/mm.o ../lib/lib.a ../fs/fs.o system: $(OBJS) @@ -48,6 +48,9 @@ sys.o : sys.c signal.o : signal.c $(GCC) $(CCFLAG) -o $@ $< +exit.o : exit.c + $(GCC) $(CCFLAG) -o $@ $< + chr_drv/chr_drv.a: chr_drv/*.c cd chr_drv; make chr_drv.a; cd .. diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c index bcabc6b..80e704a 100644 --- a/kernel/chr_drv/tty_io.c +++ b/kernel/chr_drv/tty_io.c @@ -34,6 +34,7 @@ struct tty_struct tty_table[] = { }, 0, 0, + 0, con_write, {0, 0, 0, 0, ""}, {0, 0, 0, 0, ""}, diff --git a/kernel/exit.c b/kernel/exit.c index 0bad7ef..0364109 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -12,7 +12,76 @@ extern int sys_pause(); extern int sys_close(int fd); -volatile void do_exit(long code) { +static inline int send_sig(long sig,struct task_struct * p,int priv) { + if (!p) + return -EINVAL; + if (!priv && (current->euid!=p->euid) && !suser()) + return -EPERM; + if ((sig == SIGKILL) || (sig == SIGCONT)) { + if (p->state == TASK_STOPPED) + p->state = TASK_RUNNING; + p->exit_code = 0; + p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) | + (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1))); + } + if ((int) p->sigaction[sig-1].sa_handler == 1) + return 0; + if ((sig >= SIGSTOP) && (sig <= SIGTTOU)) + p->signal &= ~(1<<(SIGCONT-1)); + p->signal |= (1<<(sig-1)); + return 0; +} + +int kill_pg(int pgrp, int sig, int priv) { + struct task_struct **p; + int err,retval = -ESRCH; + int found = 0; + + if (sig<1 || sig>32 || pgrp<=0) + return -EINVAL; + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if ((*p)->pgrp == pgrp) { + if (sig && (err = send_sig(sig,*p,priv))) + retval = err; + else + found++; + } + } + + return(found ? 0 : retval); +} + +int is_orphaned_pgrp(int pgrp) { + struct task_struct **p; + + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if (!(*p) || + ((*p)->pgrp != pgrp) || + ((*p)->state == TASK_ZOMBIE) || + ((*p)->p_pptr->pid == 1)) + continue; + if (((*p)->p_pptr->pgrp != pgrp) && + ((*p)->p_pptr->session == (*p)->session)) + return 0; + } + + return 1; +} + +static int has_stopped_jobs(int pgrp) { + struct task_struct ** p; + + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if ((*p)->pgrp != pgrp) + continue; + if ((*p)->state == TASK_STOPPED) + return(1); + } + + return 0; +} + +void do_exit(long code) { struct task_struct *p; int i; @@ -39,11 +108,60 @@ volatile void do_exit(long code) { (current->p_pptr->session == current->session) && is_orphaned_pgrp(current->pgrp) && has_stopped_jobs(current->pgrp)) { + kill_pg(current->pgrp,SIGHUP,1); + kill_pg(current->pgrp,SIGCONT,1); + } + + current->p_pptr->signal |= (1<<(SIGCHLD-1)); + + if (p = current->p_cptr) { + while (1) { + p->p_pptr = task[1]; + if (p->state == TASK_ZOMBIE) + task[1]->signal |= (1<<(SIGCHLD-1)); + if ((p->pgrp != current->pgrp) && + (p->session == current->session) && + is_orphaned_pgrp(p->pgrp) && + has_stopped_jobs(p->pgrp)) { + kill_pg(p->pgrp,SIGHUP,1); + kill_pg(p->pgrp,SIGCONT,1); + } + + if (p->p_osptr) { + p = p->p_osptr; + continue; + } + + p->p_osptr = task[1]->p_cptr; + task[1]->p_cptr->p_ysptr = p; + task[1]->p_cptr = current->p_cptr; + current->p_cptr = 0; + break; + } + } + + if (current->leader) { + struct task_struct **p; + struct tty_struct *tty; + + if (current->tty >= 0) { + tty = tty_table + current->tty; + if (tty->pgrp>0) + kill_pg(tty->pgrp, SIGHUP, 1); + tty->pgrp = 0; + tty->session = 0; + } + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) + if ((*p)->session == current->session) + (*p)->tty = -1; + } + schedule(); } int sys_exit(int error_code) { do_exit((error_code&0xff)<<8); + return 0; } diff --git a/kernel/main.c b/kernel/main.c index ba57c43..2bd10c4 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -4,6 +4,7 @@ #include inline _syscall0(int, fork); +inline _syscall0(int, pause) inline _syscall1(int, setup, void *, BIOS) inline _syscall0(int, sync) @@ -125,6 +126,7 @@ void main() { "movw %ax, %gs:(%edi)\n\r"); for(;;); + //pause(); } int printf(const char* fmt, ...) { @@ -138,20 +140,9 @@ int printf(const char* fmt, ...) { return i; } -void init() { - int pid, i; +static void easy_shell() { + int i; char a[10]; - setup((void *) &drive_info); - (void)open("/dev/tty0", O_RDWR, 0); - (void) dup(0); - (void) dup(0); - - if (!(pid=fork())) { - printf("read to start shell\n"); - execve("/bin/sh",argv,envp); - } - - /* while (1) { i = read(0, a, 9); a[i - 1] = 0; @@ -174,7 +165,25 @@ void init() { else if (strcmp(a, "sy") == 0) { sync(); } - }*/ + } +} + +static void run_sh() { + int pid; + if (!(pid=fork())) { + printf("read to start shell\n"); + execve("/bin/sh",argv,envp); + } +} + +void init() { + setup((void *) &drive_info); + (void)open("/dev/tty0", O_RDWR, 0); + (void) dup(0); + (void) dup(0); + + //run_sh(); + easy_shell(); printf("Free mem: %d bytes\n\r",memory_end-main_memory_start); } diff --git a/kernel/sched.c b/kernel/sched.c index 8a2b30f..c721efd 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -79,6 +79,12 @@ void schedule() { switch_to(next); } +int sys_pause() { + current->state = TASK_INTERRUPTIBLE; + schedule(); + return 0; +} + static inline void __sleep_on(struct task_struct** p, int state) { struct task_struct* tmp; diff --git a/mm/memory.c b/mm/memory.c index e8a6288..9b6fa72 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -260,6 +260,7 @@ void do_no_page(unsigned long error_code,unsigned long address) { //do_exit(); } + printk("do_no_page, address is 0x%x\n", address); address &= 0xfffff000; tmp = address - current->start_code; @@ -275,7 +276,6 @@ void do_no_page(unsigned long error_code,unsigned long address) { oom(); block = 1 + tmp / BLOCK_SIZE; - printk("do_no_page, tmp, block is %d, %d\n", tmp, block); for (i = 0; i < 4; block++, i++) { -- Gitee