diff --git a/fs/Makefile b/fs/Makefile index 28fa41a280392fe8f7d8a1935566792208291843..dffd2a8f9247b3ecf53639553ae2aa07c8bed162 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -1,6 +1,6 @@ GCC := gcc LD := ld -CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno-stack-protector -fno-pic -c -m32 +CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno-stack-protector -fno-pic -c -m32 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 \ diff --git a/fs/ioctl.c b/fs/ioctl.c index 076a29aaa99ad4dba2aa7053fe5ee68b68e92f5f..df570f51b8361ac6fbf1456c42d3dbda4d166886 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -4,7 +4,7 @@ #include -int tty_ioctl(int dev, int cmd, int arg); +extern int tty_ioctl(int dev, int cmd, int arg); extern int pipe_ioctl(struct m_inode *pino, int cmd, int arg); typedef int (*ioctl_ptr)(int dev,int cmd,int arg); @@ -20,9 +20,6 @@ static ioctl_ptr ioctl_table[]={ NULL, /* /dev/lp */ NULL}; /* named pipes */ -int tty_ioctl(int dev, int cmd, int arg) { - return 0; -} int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct file * filp; diff --git a/fs/read_write.c b/fs/read_write.c index 004c982570457d7dfc81c66b099e8f2b506fbb22..632b2923b7d036a8625104ef0b7d1a45c4783e2b 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -4,6 +4,7 @@ #include #include +#include extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos); extern int read_pipe(struct m_inode * inode, char * buf, int count); diff --git a/include/asm/segment.h b/include/asm/segment.h index 8d51e34a9dda1f0e220f30349796eab7dca0989d..faf0d1b45cb79125fb097edf7b9736e6a73d1eb6 100644 --- a/include/asm/segment.h +++ b/include/asm/segment.h @@ -1,41 +1,19 @@ #ifndef _SEGMENT_H #define _SEGMENT_H -static inline unsigned char get_fs_byte(const char * addr) { - unsigned register char _v; - __asm__ ("movb %%fs:%1,%0":"=r" (_v):"m" (*addr)); - return _v; -} - -static inline void put_fs_byte(char val,char *addr) { - __asm__ ("movb %0,%%fs:%1"::"r" (val),"m" (*addr)); -} - -extern inline unsigned long get_fs_long(const unsigned long *addr) { - unsigned long _v; - __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); - return _v; -} - -extern inline void put_fs_long(unsigned long val,unsigned long * addr) { - __asm__ ("movl %0,%%fs:%1"::"r" (val),"m" (*addr)); -} - -extern inline unsigned long get_fs() { - unsigned short _v; - __asm__("mov %%fs,%%ax":"=a" (_v):); - return _v; -} - -extern inline unsigned long get_ds() { - unsigned short _v; - __asm__("mov %%ds,%%ax":"=a" (_v):); - return _v; -} - -extern inline void set_fs(unsigned long val) { - __asm__("mov %0,%%fs"::"a" ((unsigned short) val)); -} +inline unsigned char get_fs_byte(const char * addr); + +inline void put_fs_byte(char val,char *addr); + +inline unsigned long get_fs_long(const unsigned long *addr) ; + +inline void put_fs_long(unsigned long val,unsigned long * addr) ; + +inline unsigned long get_fs(); + +inline unsigned long get_ds(); + +inline void set_fs(unsigned long val); #endif diff --git a/include/termios.h b/include/termios.h index 1490605d6ccf059eee5430a415819cc51f873210..6079df27927e1c8a14dd69550a3c481eb04a4483 100644 --- a/include/termios.h +++ b/include/termios.h @@ -3,6 +3,16 @@ #define TTY_BUF_SIZE 1024 +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + #define NCCS 17 struct termios { unsigned short c_iflag; @@ -13,16 +23,53 @@ struct termios { unsigned char c_cc[NCCS]; }; - +#define VINTR 0 +#define VQUIT 1 #define VERASE 2 #define VKILL 3 #define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 #define VSTART 8 #define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 -#define FIONREAD 0x541B -#define TIOCINQ FIONREAD +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD // iflag #define IGNBRK 0000001 @@ -66,4 +113,10 @@ struct termios { #define PENDIN 0040000 #define IEXTEN 0100000 +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + #endif diff --git a/kernel/Makefile b/kernel/Makefile index 2d048e04685e0357c5eb4f66e96012c1318bba4f..0f254382788b14932da6d7b6bec5c66396615f81 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -3,8 +3,9 @@ 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 exit.o \ - chr_drv/chr_drv.a blk_drv/blk_drv.a ../mm/mm.o ../lib/lib.a ../fs/fs.o + traps.o fork.o panic.o sys.o signal.o exit.o segment.o \ + ../fs/fs.o ../mm/mm.o \ + chr_drv/chr_drv.a blk_drv/blk_drv.a ../lib/lib.a system: $(OBJS) $(LD) $(LDFLAG) -M -e startup_32 -o $@ $^ > System.map @@ -51,6 +52,9 @@ signal.o : signal.c exit.o : exit.c $(GCC) $(CCFLAG) -o $@ $< +segment.o : segment.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/Makefile b/kernel/chr_drv/Makefile index 7fbf851db6cfc94cc088b686e0137f477b58b1fd..4839d77670eee325d2feb5c7381808563a7f2c66 100644 --- a/kernel/chr_drv/Makefile +++ b/kernel/chr_drv/Makefile @@ -1,8 +1,8 @@ AR := ar LD := ld GCC := gcc -CCFLAG := -m32 -I../../include -nostdinc -ffreestanding -fno-pic -Wall -fomit-frame-pointer -fno-stack-protector -c -std=gnu11 -OBJS := tty_io.o console.o keyboard.o kboard.o +CCFLAG := -m32 -I../../include -nostdinc -ffreestanding -fno-pic -Wall -fomit-frame-pointer -fno-stack-protector -c +OBJS := tty_io.o console.o keyboard.o kboard.o tty_ioctl.o chr_drv.a : $(OBJS) $(AR) rcs $@ $^ @@ -20,6 +20,9 @@ keyboard.o : keyboard.S console.o : console.c $(GCC) $(CCFLAG) -o $@ $< +tty_ioctl.o : tty_ioctl.c + $(GCC) $(CCFLAG) -o $@ $< + clean : -rm *.o -rm chr_drv.a diff --git a/kernel/chr_drv/kboard.c b/kernel/chr_drv/kboard.c index 04883bc5662b01fde9b20b1a08dd07240529b4bc..d67272b8dbe2d44d6de4b52f4543daf1a46cf8a1 100644 --- a/kernel/chr_drv/kboard.c +++ b/kernel/chr_drv/kboard.c @@ -100,7 +100,7 @@ static char key_map[0x7f] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 127, 9, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', - 13, 0, + 10, 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', @@ -112,11 +112,11 @@ static char key_map[0x7f] = { 0,0,0,0,0,0,0,0,0,0}; static char shift_map[0x7f] = { - 0,27, - '!', '@', '#', '$', '%', '^', '&', '*','(',')','_','+', + 0,27, + '!', '@', '#', '$', '%', '^', '&', '*','(',')','_','+', 127,9, 'Q','W','E','R','T','Y','U','I','O','P','{','}', - 13,0, + 10,0, 'A','S','D','F','G','H','J','K','L',':','\"', '~',0, '|','Z','X','C','V','B','N','M','<','>','?', diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c index 9c3b7e951c08c326324f0782f3c386be75f11098..99918aa70a327a0f9261726386f7a28f2715945b 100644 --- a/kernel/chr_drv/tty_io.c +++ b/kernel/chr_drv/tty_io.c @@ -73,6 +73,22 @@ static void sleep_if_full(struct tty_queue * queue) { sti(); } +int tty_signal(int sig, struct tty_struct *tty) { + if (is_orphaned_pgrp(current->pgrp)) + return -EIO; + + (void) kill_pg(current->pgrp,sig,1); + if ((current->blocked & (1<<(sig-1))) || + ((int) current->sigaction[sig-1].sa_handler == 1)) + return -EIO; + + else if (current->sigaction[sig-1].sa_handler) + return -EINTR; + + else + return -ERESTARTSYS; +} + int tty_read(unsigned channel, char * buf, int nr) { struct tty_struct * tty; char c, * b=buf; @@ -99,7 +115,6 @@ int tty_read(unsigned channel, char * buf, int nr) { return (b - buf); } else { -// printk("tty_read:%c\n", c); put_fs_byte(c,b++); if (!--nr) break; diff --git a/kernel/chr_drv/tty_ioctl.c b/kernel/chr_drv/tty_ioctl.c new file mode 100644 index 0000000000000000000000000000000000000000..7e0c8b03319510f5d9f25f979e1446840c6c865e --- /dev/null +++ b/kernel/chr_drv/tty_ioctl.c @@ -0,0 +1,168 @@ +#include +#include + +#include +#include +#include + +#include +#include +#include + +extern int tty_signal(int sig, struct tty_struct *tty); + +static void flush(struct tty_queue * queue) { + cli(); + queue->head = queue->tail; + sti(); +} + +static void wait_until_sent(struct tty_struct * tty) { +} + +static void send_break(struct tty_struct * tty) { +} + +static int get_termios(struct tty_struct * tty, struct termios * termios) { + int i; + + verify_area(termios, sizeof (*termios)); + for (i=0 ; i< (sizeof (*termios)) ; i++) + put_fs_byte( ((char *)&tty->termios)[i] , i+(char *)termios ); + return 0; +} + +static int set_termios(struct tty_struct * tty, struct termios * termios, + int channel) { + int i, retsig; + + if ((current->tty == channel) && (tty->pgrp != current->pgrp)) { + retsig = tty_signal(SIGTTOU, tty); + if (retsig == -ERESTARTSYS || retsig == -EINTR) + return retsig; + } + + for (i=0 ; i< (sizeof (*termios)) ; i++) + ((char *)&tty->termios)[i]=get_fs_byte(i+(char *)termios); + return 0; +} + +static int get_termio(struct tty_struct * tty, struct termio * termio) { + int i; + struct termio tmp_termio; + + verify_area(termio, sizeof (*termio)); + tmp_termio.c_iflag = tty->termios.c_iflag; + tmp_termio.c_oflag = tty->termios.c_oflag; + tmp_termio.c_cflag = tty->termios.c_cflag; + tmp_termio.c_lflag = tty->termios.c_lflag; + tmp_termio.c_line = tty->termios.c_line; + for(i=0 ; i < NCC ; i++) + tmp_termio.c_cc[i] = tty->termios.c_cc[i]; + for (i=0 ; i< (sizeof (*termio)) ; i++) + put_fs_byte( ((char *)&tmp_termio)[i] , i+(char *)termio ); + return 0; +} + +static int set_termio(struct tty_struct * tty, struct termio * termio, + int channel) { + int i, retsig; + struct termio tmp_termio; + + if ((current->tty == channel) && (tty->pgrp != current->pgrp)) { + retsig = tty_signal(SIGTTOU, tty); + if (retsig == -ERESTARTSYS || retsig == -EINTR) + return retsig; + } + + for (i=0 ; i< (sizeof (*termio)) ; i++) + ((char *)&tmp_termio)[i]=get_fs_byte(i+(char *)termio); + *(unsigned short *)&tty->termios.c_iflag = tmp_termio.c_iflag; + *(unsigned short *)&tty->termios.c_oflag = tmp_termio.c_oflag; + *(unsigned short *)&tty->termios.c_cflag = tmp_termio.c_cflag; + *(unsigned short *)&tty->termios.c_lflag = tmp_termio.c_lflag; + tty->termios.c_line = tmp_termio.c_line; + for(i=0 ; i < NCC ; i++) + tty->termios.c_cc[i] = tmp_termio.c_cc[i]; + return 0; +} + +int tty_ioctl(int dev, int cmd, int arg) { + struct tty_struct * tty; + + if (MAJOR(dev) == 5) { + dev=current->tty; + if (dev<0) + panic("tty_ioctl: dev<0"); + } else + dev=MINOR(dev); + + tty = tty_table + dev; + + switch (cmd) { + case TCGETS: + return get_termios(tty,(struct termios *) arg); + case TCSETSF: + flush(&tty->read_q); /* fallthrough */ + case TCSETSW: + wait_until_sent(tty); /* fallthrough */ + case TCSETS: + return set_termios(tty,(struct termios *) arg, dev); + case TCGETA: + return get_termio(tty,(struct termio *) arg); + case TCSETAF: + flush(&tty->read_q); /* fallthrough */ + case TCSETAW: + wait_until_sent(tty); /* fallthrough */ + case TCSETA: + return set_termio(tty,(struct termio *) arg, dev); + case TCSBRK: + if (!arg) { + wait_until_sent(tty); + send_break(tty); + } + return 0; + case TCXONC: + switch (arg) { + case TCOOFF: + tty->stopped = 1; + tty->write(tty); + return 0; + case TCOON: + tty->stopped = 0; + tty->write(tty); + return 0; + case TCIOFF: + if (STOP_CHAR(tty)) + PUTCH(STOP_CHAR(tty),tty->write_q); + return 0; + case TCION: + if (START_CHAR(tty)) + PUTCH(START_CHAR(tty),tty->write_q); + return 0; + } + return -EINVAL; + case TCFLSH: + if (arg==0) + flush(&tty->read_q); + else if (arg==1) + flush(&tty->write_q); + else if (arg==2) { + flush(&tty->read_q); + flush(&tty->write_q); + } else + return -EINVAL; + case TIOCOUTQ: + verify_area((void *) arg,4); + put_fs_long(CHARS(tty->write_q),(unsigned long *) arg); + return 0; + case TIOCINQ: + verify_area((void *) arg,4); + put_fs_long(CHARS(tty->secondary), + (unsigned long *) arg); + return 0; + default: + return -EINVAL; + } +} + diff --git a/kernel/segment.c b/kernel/segment.c new file mode 100644 index 0000000000000000000000000000000000000000..35b941491563007ed90e755ab7f1a0ade58b7f68 --- /dev/null +++ b/kernel/segment.c @@ -0,0 +1,38 @@ +#include + +inline unsigned char get_fs_byte(const char * addr) { + unsigned register char _v; + __asm__ ("movb %%fs:%1,%0":"=r" (_v):"m" (*addr)); + return _v; +} + +inline void put_fs_byte(char val,char *addr) { + __asm__ ("movb %0,%%fs:%1"::"r" (val),"m" (*addr)); +} + +inline unsigned long get_fs_long(const unsigned long *addr) { + unsigned long _v; + __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); + return _v; +} + +inline void put_fs_long(unsigned long val,unsigned long * addr) { + __asm__ ("movl %0,%%fs:%1"::"r" (val),"m" (*addr)); +} + +inline unsigned long get_fs() { + unsigned short _v; + __asm__("mov %%fs,%%ax":"=a" (_v):); + return _v; +} + +inline unsigned long get_ds() { + unsigned short _v; + __asm__("mov %%ds,%%ax":"=a" (_v):); + return _v; +} + +inline void set_fs(unsigned long val) { + __asm__("mov %0,%%fs"::"a" ((unsigned short) val)); +} + diff --git a/kernel/sys_call.S b/kernel/sys_call.S index f8853607c245a756132c9b7d719e021e1ef42664..8285c48f9e399cc6f5caa3429158b1434c2d8744 100644 --- a/kernel/sys_call.S +++ b/kernel/sys_call.S @@ -32,6 +32,9 @@ sa_restorer = 12 int_msg: .asciz "In kernel interrupt\n\r" +show_ind: + .asciz "sys call %d\n\r" + .align 4 reschedule: pushl $ret_from_sys_call @@ -52,6 +55,12 @@ system_call: movl $0x17, %edx movw %dx, %fs + pushl %eax + pushl $show_ind + call printk + popl %eax + popl %eax + call *sys_call_table(, %eax, 4) pushl %eax