From 2fbfc5405ee0cd0a2c54152d09f094a75724f35b Mon Sep 17 00:00:00 2001 From: AceVest Date: Sun, 20 Jul 2014 12:00:44 +0800 Subject: [PATCH] support read from console --- bin/shell.c | 4 ++ boot/multiboot.S | 19 +----- drivers/console.c | 154 ++++++++++++++++++++++++++++++++++++++++++--- drivers/console.h | 13 ++-- drivers/keyboard.c | 81 ++++++++++++++---------- drivers/vga.c | 15 +++-- fs/ext2.c | 9 --- fs/fs.c | 111 +++----------------------------- fs/open.c | 73 +-------------------- fs/read.c | 17 ++--- fs/write.c | 4 +- include/fs.h | 22 +++++++ include/syscall.h | 1 - kernel/syscall.c | 4 +- lib/syscall.c | 1 - 15 files changed, 259 insertions(+), 269 deletions(-) diff --git a/bin/shell.c b/bin/shell.c index 770862e..bca1539 100644 --- a/bin/shell.c +++ b/bin/shell.c @@ -17,8 +17,12 @@ int systest(); int main() { + while(1) { + char buf[256]; + read(0, buf, 256); + write(0, buf, 256); #if 0 asm("movl $11, %eax;" \ "pushl $1f;" \ diff --git a/boot/multiboot.S b/boot/multiboot.S index 14e8129..18c4a32 100644 --- a/boot/multiboot.S +++ b/boot/multiboot.S @@ -112,7 +112,7 @@ main: movl $init_pgd-KRNLADDR,%ebx movl %ebx,%cr3 - # enable PG + # enable PG WP movl %cr0,%eax orl $0x80010000,%eax movl %eax,%cr0 @@ -123,29 +123,14 @@ main: ljmp $0x08,$Label Label: + call check_kernel addl $8,%esp movl $root_task + TASK_SIZE, %esp call setup_kernel - -#if 0 - movl $0x23, %eax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - pushl %eax - pushl $KRNLADDR - pushl $0x282 - pushl $0x1B - movl $root_task_entry, %eax - pushl %eax - iret -#else movl $root_task_entry, %eax jmpl *%eax -#endif Die: jmp Die # Should never come to here. diff --git a/drivers/console.c b/drivers/console.c index ebf1c9b..045571d 100644 --- a/drivers/console.c +++ b/drivers/console.c @@ -9,27 +9,161 @@ #include #include +#include + +cnsl_t cnsl; + +static bool empty(const cnsl_queue_t *q) +{ + return q->head == q->tail; +} + +static bool full(const cnsl_queue_t *q) +{ + return (q->head + 1) % CNSL_QUEUE_SIZE == q->tail; +} + +static void put(cnsl_queue_t *q, char c) +{ + if(!full(q)) + { + q->data[q->head] = c; + q->head = (q->head + 1) % CNSL_QUEUE_SIZE; + } +} + +static bool get(cnsl_queue_t *q, char *c) +{ + if(!empty(q)) + { + *c = q->data[q->tail]; + q->tail = (q->tail + 1) % CNSL_QUEUE_SIZE; + return true; + } + + return false; +} + +static void clear(cnsl_queue_t *q) +{ + q->head = q->tail = 0; +} + +static void erase(cnsl_queue_t *q) +{ + if(empty(q)) + return; + + if(q->head == 0) + q->head = CNSL_QUEUE_SIZE -1; + else + q->head--; +} -cnsl_queue_t cnsl_rd_q; -cnsl_queue_t cnsl_wr_q; -cnsl_queue_t cnsl_sc_q; static void cnsl_queue_init(cnsl_queue_t *cq) { memset((void *)cq, 0, sizeof(*cq)); - cq->head = 0; cq->tail = 0; init_wait_queue(&cq->wait); +} - //cq->data = kmalloc(CNSL_QUEUE_SIZE, 0); +wait_queue_head_t rdwq; - printk("console queue data addr %08x\n", cq->data); +void cnsl_init() +{ + cnsl_queue_init(&cnsl.rd_q); + cnsl_queue_init(&cnsl.wr_q); + cnsl_queue_init(&cnsl.sc_q); + init_wait_queue(&rdwq); } -void cnsl_init() + +int cnsl_kbd_write(char ch) +{ + if(ch == '\b') + { + if(!empty(&cnsl.wr_q)) + vga_putc(0, '\b', 0x2); + erase(&cnsl.wr_q); + erase(&cnsl.sc_q); + } + else + { + put(&cnsl.wr_q, ch); + put(&cnsl.sc_q, ch); + vga_putc(0, ch, 0x2); + } + + + if(ch == '\n') + { + clear(&cnsl.wr_q); + while(get(&cnsl.sc_q, &ch)) + put(&cnsl.rd_q, ch); + wake_up(&rdwq); + } + +#if 0 + printl(23, "rd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + cnsl.rd_q.data[0], + cnsl.rd_q.data[1], + cnsl.rd_q.data[2], + cnsl.rd_q.data[3], + cnsl.rd_q.data[4], + cnsl.rd_q.data[5], + cnsl.rd_q.data[6], + cnsl.rd_q.data[7], + cnsl.rd_q.data[8], + cnsl.rd_q.data[9]); +#endif +} + + +int cnsl_read(char *buf, size_t count) { - cnsl_queue_init(&cnsl_rd_q); - cnsl_queue_init(&cnsl_wr_q); - cnsl_queue_init(&cnsl_sc_q); + unsigned long flags; + + assert(count > 0); + int cnt = 0; + for(cnt=0; cntstate = TASK_WAIT; + irq_save(flags); + bool r = get(&cnsl.rd_q, &ch); + irq_restore(flags); + + if(r) + { + buf[cnt++] = ch; + + task->state = TASK_RUNNING; + del_wait_queue(&rdwq, &wait); + + if(ch == '\n') + goto end; + + break; + } + + schedule(); + } + + } + +end: + buf[cnt] = 0; + return cnt; } + +chrdev_t cnsl_chrdev = { + .read = cnsl_read +}; diff --git a/drivers/console.h b/drivers/console.h index a18325d..26ba40c 100644 --- a/drivers/console.h +++ b/drivers/console.h @@ -11,7 +11,7 @@ #include -#define CNSL_QUEUE_SIZE 1024 +#define CNSL_QUEUE_SIZE 10 typedef struct cnsl_queue { @@ -21,6 +21,11 @@ typedef struct cnsl_queue char data[CNSL_QUEUE_SIZE]; } cnsl_queue_t; -extern cnsl_queue_t cnsl_rd_q; -extern cnsl_queue_t cnsl_wr_q; -extern cnsl_queue_t cnsl_sc_q; +typedef struct cnsl +{ + cnsl_queue_t rd_q; + cnsl_queue_t wr_q; + cnsl_queue_t sc_q; +} cnsl_t; + +int cnsl_kbd_write(char c); diff --git a/drivers/keyboard.c b/drivers/keyboard.c index 1998cb3..3d790f9 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -29,37 +29,56 @@ void vga_dbg_toggle(); int debug_wait_queue_put(unsigned int v); void ide_dma_pci_lba48(); -unsigned long kbd_cnt = 0; + +void kbd_debug(unsigned char scan_code); + +char kbd_char_tbl[]={0,0, +'1','2','3','4','5','6','7','8','9','0','-','=','\b',0, +'q','w','e','r','t','y','u','i','o','p','[',']','\n',0, +'a','s','d','f','g','h','j','k','l',';','\'','`',0,'\\', +'z','x','c','v','b','n','m',',','.','/',0,0,0,' ', +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) { unsigned char scan_code; - scan_code = inb(0x60); - printl(MPL_KEYBOARD, "keyboard:%d scan code %02x", kbd_cnt++, scan_code); - - if(scan_code == 0x01) // Esc - reboot(); - - printk("[%02x]", scan_code); + scan_code = inb(0x60); - if(scan_code == 0x09) // 8 - ide_dma_pci_lba48(); + kbd_debug(scan_code); - if(scan_code == 0x0B) // 0 + if(0x80 & scan_code) // break code { - asm("cli;"); - while(1); + return ; } - if(scan_code == 0x13) // r - ide_debug(); + unsigned int inx = scan_code & 0xFF; + char ch = kbd_char_tbl[inx]; + cnsl_kbd_write(ch); +} + +void kbd_debug(unsigned char scan_code) +{ + static unsigned long kbd_cnt = 0; + printl(MPL_KEYBOARD, "keyboard:%d scan code %02x", kbd_cnt++, scan_code); - if(scan_code == 0x1F) // s - ide_status(); + if(scan_code == 0x01) // Esc + reboot(); + + printd("[%02x]", scan_code); - if(scan_code == 0x14) // t - debug_sched(); if(scan_code == 0x3B) // F1 vga_switch(0); @@ -79,22 +98,18 @@ void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) if(scan_code == 0x42) // F8 debug_wait_queue_put(7); - if(scan_code == 0x43); // F9 - if(scan_code == 0x44); // F10 - if(scan_code == 0x57); // F11 + if(scan_code == 0x43) // F9 + ide_dma_pci_lba48(); + if(scan_code == 0x44) // F10 + ide_debug(); + if(scan_code == 0x57) // F11 + { + asm("cli;"); + while(1); + } if(scan_code == 0x58) // F12 vga_dbg_toggle(); -#if 1 - cnsl_rd_q.data[0] = (char) scan_code; - wake_up(&cnsl_rd_q.wait); -#endif -} - -int sysc_read_kbd() -{ - DECLARE_WAIT_QUEUE(wait, current); - add_wait_queue(&cnsl_rd_q.wait, &wait); - return 0; + //ide_status(); } diff --git a/drivers/vga.c b/drivers/vga.c index 03ad754..c6fc7b6 100644 --- a/drivers/vga.c +++ b/drivers/vga.c @@ -127,11 +127,14 @@ void vga_scroll_up(vga_screen_t *s) -void vga_putc(vga_screen_t *s, const unsigned char c, const unsigned char color) +void vga_putc(unsigned int nr, unsigned char c, const unsigned char color) { + vga_screen_t *s = vga_screen + nr; + vga_char_t *pv = s->base; bool need_clear = true; + bool need_forward = true; unsigned int old_offset = s->offset; switch(c) @@ -145,10 +148,15 @@ void vga_putc(vga_screen_t *s, const unsigned char c, const unsigned char color) case '\t': set_offset(s, (xpos(s) + 1 + TAB_MASK) & ~TAB_MASK, ypos(s)); break; + case '\b': + set_offset(s, xpos(s) - 1, ypos(s)); + c = ' '; + need_forward = false; + // NO BREAK default: need_clear = false; pv[s->offset] = vga_char(c, color); - set_offset(s, xpos(s)+1, ypos(s)); + set_offset(s, xpos(s)+(need_forward?1 : 0), ypos(s)); break; } @@ -170,11 +178,10 @@ void vga_puts(unsigned int nr, const char *buf, unsigned char color) return ; char *p = (char *) buf; - vga_screen_t *s = vga_screen + nr; while(*p) { - vga_putc(s, *p, color); + vga_putc(nr, *p, color); p++; } } diff --git a/fs/ext2.c b/fs/ext2.c index 346f012..cd8731e 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -255,12 +255,3 @@ void ext2_setup_fs() -void setup_fs() -{ - ext2_setup_fs(); -} - -unsigned int namei(const char *path) -{ - return ext2_search_inpath(path); -} diff --git a/fs/fs.c b/fs/fs.c index 5b03ed2..06879b3 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -13,113 +13,22 @@ #include #include #include -#define SECT_SIZE 512 - -#if 0 -File file_table[NR_FILES] __attribute__ ((__aligned__(PAGE_SIZE))) = {{0,},}; -extern unsigned int ext2_start_sect; -void hd_read(dev_t dev, u64 sect_nr, void *buf, u32 count); -void init_file_table(); -void save_boot_part(int n, pPartition p, u32 base_sect); -void read_ext_part(u32 base, u32 offset); -void setup_fs() -{ - int i, minor; - pPartition p; - unsigned char *buf; - - - init_file_table(); - - - minor = DEV_MINOR(ROOT_DEV); - buf = (unsigned char *) get_virt_pages(1); - hd_read(ROOT_DEV, 0, buf, SECT_SIZE); - - - for(i=0; i<4; i++) - { - p = (pPartition)(buf+PARTS_POS) + i; - if(p->Type == 0) - continue; - - //save_boot_part(i+1, p, p->AbsoluteSectNo); - save_boot_part(i, p, p->AbsoluteSectNo); - - printk("hd%d\tbase: %08x size: %08x type:%02x", - i, p->AbsoluteSectNo, p->PartitionSize, p->Type); - if(p->Type == 0x05) - { - printk("\tExtend\n"); - //read_ext_part(p->AbsoluteSectNo, 0); - } - else - printk("\n"); - } - - - printk("ext2_start_sect: %x\n", ext2_start_sect); +extern chrdev_t cnsl_chrdev; - return ; -} - -void init_file_table() -{ - int i; +chrdev_t *chrdev[CHRDEV_SIZE] = { + &cnsl_chrdev +}; - for(i=0; iType == 0x05) - panic("partition should not be extended"); - - int minor = DEV_MINOR(ROOT_DEV); - - if(minor-1 == n) - ext2_start_sect = base_sect; + ext2_setup_fs(); } -static unsigned int ext_part = 5; -void read_ext_part(u32 base, u32 offset) +unsigned int namei(const char *path) { - unsigned char *buf; - pPartition p; - buf = get_virt_pages(1); - - //printk("^^^^^^^^^:%08x\n", base+offset); - hd_read(ROOT_DEV, base+offset, buf, SECT_SIZE); - int i; - - for(i=0; i<4; i++) - { - p = (pPartition)(buf+PARTS_POS) + i; - if(p->Type == 0x00) - continue; - - if(p->Type != 0x05) - { - - //save_boot_part(ext_part, p, 0); - printk(" hd%d\tbase: %08x size: %08x type:%02x\n", - ext_part++, base+p->AbsoluteSectNo, - p->PartitionSize, p->Type); - } - else - { - read_ext_part(base, p->AbsoluteSectNo); - } - } - - printk("\n"); - - free_virt_pages(buf); + return ext2_search_inpath(path); } -#endif diff --git a/fs/open.c b/fs/open.c index 73fb164..a7dfbe9 100644 --- a/fs/open.c +++ b/fs/open.c @@ -20,76 +20,5 @@ int sysc_open(const char *path, int flags, mode_t mode) { -#if 0 - assert(mode == 0); // unsupport now... - assert(flags == O_RDONLY); // support only... - - int ino_nr, i, fd; - pInode inode; - - /* 先获取文件的i节点号 */ - ino_nr = get_inode_nr(path); - if(ino_nr == EXT2_BAD_INO) - return -ENOENT; - - /* 找到空的文件描述符句柄 */ - for(i=0; ifps[i] == NULL) - break; - if(i == NR_OPENS) - return -EMFILE; - fd = i; - - - /* 找到空的描述符或已经打开的描述符 */ - int empt_nr, fdt_nr; - pFile pf; - empt_nr = fdt_nr = -1; - for(i=0, pf=file_table; iino_nr == ino_nr) - { - fdt_nr = i; - break; - } - else if(pf->ino_nr == 0) - { - empt_nr = i; - } - } - - if(fdt_nr != -1) - { - pf = file_table+fdt_nr; - } - else if(empt_nr != -1) - { - pf = file_table+empt_nr; - } - else - { - return -EMFILE; - } - - - if(pf->ino_nr == ino_nr) - { - pf->count++; - current->fps[fd] = pf; - return fd; - } - - inode = find_empty_inode(); - if(inode == NULL) - return -ENOMEM; - - get_inode(ino_nr, inode); - - pf->count = 1; - pf->ino_nr = ino_nr; - pf->inode = inode; - current->fps[fd] = pf; - - return fd; -#endif + return 0; } diff --git a/fs/read.c b/fs/read.c index 21db990..7d7307b 100644 --- a/fs/read.c +++ b/fs/read.c @@ -17,19 +17,12 @@ int sysc_read(int fd, void *buf, size_t count) { -#if 0 if(fd<0 || fd>=NR_OPENS) return -EBADF; - pFile fp = current->fps[fd]; - assert(fp != NULL); - - pInode inode = fp->inode; - assert(inode->i_size > 0); // 目前只能这样支持 - if(inode->i_size > MAX_SUPT_FILE_SIZE) - return -EFAULT; - - - return read_file(inode, buf, count); -#endif + // only support char device + // only support read from console. + // ignore fd + chrdev_t *p = chrdev[CHRDEV_CNSL]; + return p->read(buf, count); } diff --git a/fs/write.c b/fs/write.c index cebc502..efb85e7 100644 --- a/fs/write.c +++ b/fs/write.c @@ -15,7 +15,7 @@ */ -extern void vga_puts(const char *buf, unsigned char color); +extern void vga_puts(unsigned int nr, const char *buf, unsigned char color); int sysc_write(int fd, const char *buf, unsigned long size) { if(size < 0) return -1; @@ -23,7 +23,7 @@ int sysc_write(int fd, const char *buf, unsigned long size) switch(fd) { case 0: - vga_puts(buf, 0xF); + vga_puts(0, buf, 0xF); break; default: return -1; diff --git a/include/fs.h b/include/fs.h index 43337f2..daf312e 100644 --- a/include/fs.h +++ b/include/fs.h @@ -46,6 +46,28 @@ unsigned int namei(const char *path); #define MAX_SUPT_FILE_SIZE (EXT2_IND_BLOCK*EXT2_BLOCK_SIZE) + + + +typedef struct chrdev +{ + int (*read)(char *buf, size_t count); +} chrdev_t; + +enum { + CHRDEV_CNSL, + CHRDEV_SIZE +}; + +extern chrdev_t *chrdev[]; + +typedef struct +{ + +} file_t; + + + #if 0 #define NR_FILES (PAGE_SIZE/sizeof(File)) #define NR_INODES (2*NR_FILES) diff --git a/include/syscall.h b/include/syscall.h index 64cb5d0..3ea6fcf 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -41,7 +41,6 @@ int _syscall5(int nr, unsigned long a, unsigned long b, unsigned long c, unsigne enum { SYSC_WRITE, - SYSC_READ_KBD, SYSC_REBOOT, SYSC_FORK, SYSC_CLONE, diff --git a/kernel/syscall.c b/kernel/syscall.c index a87f14c..91084b4 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -67,9 +67,7 @@ void init_sysc_handler_table() sysc_handler_table[nr] = (unsigned long) sym; \ }while(0); - /* 有没有一种宏定义可以把大写直接转成小写? */ _sysc_(SYSC_WRITE, sysc_write); - _sysc_(SYSC_READ_KBD, sysc_read_kbd); _sysc_(SYSC_REBOOT, sysc_reboot); _sysc_(SYSC_FORK, sysc_fork); _sysc_(SYSC_EXEC, sysc_exec); @@ -81,7 +79,7 @@ void init_sysc_handler_table() _sysc_(SYSC_TEST, sysc_test); } -int sysc_bad_syscnr() +int sysc_bad_syscnr() { int sysc_nr; asm("":"=a"(sysc_nr)); diff --git a/lib/syscall.c b/lib/syscall.c index b9dc9e2..d781aa9 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -9,7 +9,6 @@ #define SYSENTER_ASM \ - "movl $11,%%eax;" \ "pushl $1f;" \ "pushl %%ecx;" \ "pushl %%edx;" \ -- 2.44.0