From f7327c3b37cc079315ca4a92295f2624d3c2c67b Mon Sep 17 00:00:00 2001 From: acevest Date: Sun, 22 Sep 2024 18:43:40 +0800 Subject: [PATCH] =?utf8?q?=E8=B0=83=E6=95=B4=E5=90=84=E4=BB=BB=E5=8A=A1?= =?utf8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- drivers/ata.c | 2 - fs/buffer.c | 5 ++ kernel/fork.c | 3 + kernel/printk.c | 18 +++-- kernel/task_disk.c | 5 +- kernel/task_init.c | 163 ++++++++++++++++++++++++++++++++++++++++++++- kernel/task_root.c | 148 ++++------------------------------------ 7 files changed, 190 insertions(+), 154 deletions(-) diff --git a/drivers/ata.c b/drivers/ata.c index 6f3a444..97cea06 100644 --- a/drivers/ata.c +++ b/drivers/ata.c @@ -402,9 +402,7 @@ void read_partition_table(ide_drive_t *drv, uint32_t mbr_ext_offset, uint32_t lb part->lba_start = lba_offset; uint32_t size = pt.lba_end; part->lba_end = part->lba_start + size; - ENTER_CRITICAL_ZONE; printk("part[%02d] %02X %10u %-10u\n", part_id, pt.type, lba_offset, part->lba_end - 1); - EXIT_CRITICAL_ZONE; } // 每个分区16个字节 diff --git a/fs/buffer.c b/fs/buffer.c index 597eae6..244543b 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -133,6 +133,10 @@ again: // 把它从free_list上删掉 list_del_init(&b->node); + // FIXME + irq_restore(iflags); + + // 虽然此时该bbuffer_t上的ref_count为0但其可能还有I/O操作没有完成 // 因为可能有的进程调用了write、read后再直接调用brelse // 所以需要在此等待其结束 @@ -145,6 +149,7 @@ again: atomic_set(&(b->ref_count), 1); b->uptodate = 0; + return b; } diff --git a/kernel/fork.c b/kernel/fork.c index c4e1b46..961d854 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -98,12 +98,15 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { // printd("child regs: %x %x\n", child_regs, regs); memcpy(child_regs, regs, sizeof(*regs)); + //child_regs->eflags |= 0x200; + if (flags & FORK_KRNL) { strcpy(tsk->name, (char *)(child_regs->eax)); child_regs->eax = 0; } else { child_regs->eip = *((unsigned long *) && fork_child); } + printk("%s fork %s EFLAGS %08x\n", current->name, tsk->name, regs->eflags); // 这一句已经不需要了,通过fork_child已经能给子进程返回0了 // child_regs->eax = 0; diff --git a/kernel/printk.c b/kernel/printk.c index 3934245..44f71e7 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -25,41 +25,39 @@ void serial_write(const char *buf, size_t size); extern tty_t *const default_tty; int printk(const char *fmtstr, ...) { - char pkbuf[1024]; - // ENTER_CRITICAL_ZONE; + static char pkbuf[1024]; + ENTER_CRITICAL_ZONE; char *args = (char *)(((char *)&fmtstr) + 4); int size = vsprintf(pkbuf, fmtstr, args); tty_write(default_tty, pkbuf, (size_t)size); serial_write(pkbuf, (size_t)size); - // EXIT_CRITICAL_ZONE; + EXIT_CRITICAL_ZONE; return 0; } extern tty_t *const debug_tty; int printd(const char *fmtstr, ...) { - char pdbuf[1024]; - // ENTER_CRITICAL_ZONE; + static char pdbuf[1024]; + ENTER_CRITICAL_ZONE; char *args = (char *)(((char *)&fmtstr) + 4); int size = vsprintf(pdbuf, fmtstr, args); tty_write(debug_tty, pdbuf, (size_t)size); serial_write(pdbuf, (size_t)size); - // EXIT_CRITICAL_ZONE; + EXIT_CRITICAL_ZONE; return 0; } extern tty_t *const monitor_tty; int printlo(unsigned int xpos, unsigned int ypos, const char *fmtstr, ...) { - char plobuf[1024]; - + static char plobuf[1024]; char *args = (char *)(((char *)&fmtstr) + 4); - int size = vsprintf(plobuf, fmtstr, args); - ENTER_CRITICAL_ZONE; + int size = vsprintf(plobuf, fmtstr, args); tty_write_at(monitor_tty, xpos, ypos, plobuf, (size_t)size); diff --git a/kernel/task_disk.c b/kernel/task_disk.c index 2ee9381..e78883d 100644 --- a/kernel/task_disk.c +++ b/kernel/task_disk.c @@ -16,10 +16,6 @@ void ata_read_identify(int drv, int disable_intr); void ata_pio_read_data(int drv_no, int sect_cnt, void *dst); void ata_dma_read_ext(int drv, uint64_t pos, uint16_t count, void *dest); -void disk_init() { - // ... -} - void send_disk_request(disk_request_t *r) { if (NULL == r) { panic("null disk request"); @@ -102,6 +98,7 @@ void disk_task_entry(void *arg) { assert(MAKE_DISK_DEV(drv_no, part_id) == r->dev); uint64_t pos = r->pos + drv->partions[part_id].lba_start; + //printk("pos %lu partid %d lba end %lu\n", pos, part_id, drv->partions[part_id].lba_end); assert(pos < drv->partions[part_id].lba_end); // init_completion(&ide_ctrl->intr_complete); diff --git a/kernel/task_init.c b/kernel/task_init.c index 7064470..141f98c 100644 --- a/kernel/task_init.c +++ b/kernel/task_init.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -10,17 +11,175 @@ #include #include int sysc_wait(int ticks); +void kernel_task(char *name, void *entry, void *arg); + + +// 测试用的代码 +// 这里存的是下标对应的每个扇区的最后2个字节 +// hexdump -C HD.IMG | less 看的,如果镜像文件有变动需要更新这里 +uint16_t hd_sect_data_fingerprint[] = { + 0xAA55, // 0 + 0x0820, // 1 + 0x4d89, // 2 + 0xeb1d, // 3 + 0x1009 // 4 +}; + +uint64_t debug_sect_nr = 0; + +uint64_t get_next_deubug_sect_nr() { + debug_sect_nr++; +#if 0 + debug_sect_nr %= sizeof(hd_sect_data_fingerprint) / sizeof(uint16_t); +#else + if (debug_sect_nr >= sizeof(hd_sect_data_fingerprint) / sizeof(uint16_t)) { + debug_sect_nr = 0; + } +#endif + return debug_sect_nr; +} + +void verify_hd_data(uint64_t sect_nr, uint16_t *buf, const char *name) { + uint16_t vfp = hd_sect_data_fingerprint[sect_nr]; + + uint16_t fp = buf[255]; + + if (fp == vfp) { + // printk("%s verification passed sect %lu fp %04x\n", name, sect_nr, fp); + } else { + printk("%s verification failed sect %lu fp %04x right %04x\n", name, sect_nr, fp, vfp); + panic("verify hd data fail"); + } +} + +// 保存它们不跨64KB +u16 disk_buf1[256] __attribute__((__aligned__(512))); +u16 disk_buf2[256] __attribute__((__aligned__(512))); + +void taskA_entry() { + current->priority = 7; + + while (1) { + sysc_wait(7); + + uint64_t sect_nr = get_next_deubug_sect_nr(); + memset(disk_buf1, 0, 512); + + disk_request_t r; + r.dev = MAKE_DISK_DEV(0, 0); + r.command = DISK_REQ_READ; + r.pos = sect_nr; + r.count = 1; + r.buf = disk_buf1; + r.bb = 0; + + send_disk_request(&r); + + // verify_hd_data(sect_nr, disk_buf1, current->name); + +#if 1 + for (int i = 0; i < 2; i++) { + asm("hlt;"); + } +#endif + } +} + +void taskB_entry() { + current->priority = 13; + + while (1) { + sysc_wait(7); + // uint64_t sect_nr = get_next_deubug_sect_nr(); + // memset(disk_buf2, 0, 512); + // disk_request_t r; + // r.dev = MAKE_DISK_DEV(2, 0); + // r.command = DISK_REQ_READ; + // r.pos = sect_nr; + // r.count = 1; + // r.buf = disk_buf2; + // r.bb = 0; + + // send_disk_request(&r); + // // verify_hd_data(sect_nr, disk_buf2, current->name); + +#if 0 + // for (int i = 0; i < 1; i++) { + // asm("hlt;"); + // } +#endif + } +} + +void taskC_entry() { + current->priority = 17; + + while (1) { + sysc_wait(100); + +#if 1 + for (int i = 0; i < 7; i++) { + asm("hlt;"); + } +#endif + } +} + + void init_task_entry() { current->priority = 10; +// pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)current)) - 1; +// child_regs->eflags |= 0x200; +#if 1 + // 有一点点垃圾事情需要处理 + // 之前内核初始化都是在关中断下进行的 + // 这就段时间有可能按键盘,然而键盘不把数据读出来就不会触发下一次中断 + // 所以得先清空一下键盘 + inb(0x60); +#endif + + +#if 1 + extern __attribute__((regparm(0))) long sysc_mkdir(const char *path, int mode); + sysc_mkdir("/root", 0777); + sysc_mkdir("/root/aaa", 0777); + + { + namei_t ni; + const char *path = "/root"; + path_init(path, 0, &ni); + path_walk(path, &ni); + } +#endif + +#if 1 + kernel_task("ide/0", disk_task_entry, (void *)0); + void ide_read_partions(); ide_read_partions(); void ata_read_ext2_sb(); ata_read_ext2_sb(); +#endif + +#if 0 + extern int ide_read_partions_done; + while(!ide_read_partions_done) { + printk("wait for hard disk partition table done\n"); + sysc_wait(1); + } +#endif + +#if 1 + kernel_task("ide/1", disk_task_entry, (void *)1); + kernel_task("user", user_task_entry, NULL); + kernel_task("tskA", taskA_entry, NULL); + kernel_task("tskB", taskB_entry, NULL); + kernel_task("tskC", taskC_entry, NULL); +#endif while (1) { - asm("sti;hlt;"); - sysc_wait(2); + sysc_wait(1); } } diff --git a/kernel/task_root.c b/kernel/task_root.c index ee369cd..63572b2 100644 --- a/kernel/task_root.c +++ b/kernel/task_root.c @@ -53,153 +53,29 @@ void kernel_task(char *name, void *entry, void *arg) { int pid = do_fork(®s, FORK_KRNL); - printd("kernel[%s] task pid is %d\n", name, pid); -} - -// 测试用的代码 -// 这里存的是下标对应的每个扇区的最后2个字节 -// hexdump -C HD.IMG | less 看的,如果镜像文件有变动需要更新这里 -uint16_t hd_sect_data_fingerprint[] = { - 0xAA55, // 0 - 0x0820, // 1 - 0x4d89, // 2 - 0xeb1d, // 3 - 0x1009 // 4 -}; - -uint64_t debug_sect_nr = 0; - -uint64_t get_next_deubug_sect_nr() { - debug_sect_nr++; -#if 0 - debug_sect_nr %= sizeof(hd_sect_data_fingerprint) / sizeof(uint16_t); -#else - if (debug_sect_nr >= sizeof(hd_sect_data_fingerprint) / sizeof(uint16_t)) { - debug_sect_nr = 0; - } -#endif - return debug_sect_nr; -} - -void verify_hd_data(uint64_t sect_nr, uint16_t *buf, const char *name) { - uint16_t vfp = hd_sect_data_fingerprint[sect_nr]; - - uint16_t fp = buf[255]; - - if (fp == vfp) { - // printk("%s verification passed sect %lu fp %04x\n", name, sect_nr, fp); - } else { - printk("%s verification failed sect %lu fp %04x right %04x\n", name, sect_nr, fp, vfp); - panic("verify hd data fail"); - } -} - -// 保存它们不跨64KB -u16 disk_buf1[256] __attribute__((__aligned__(512))); -u16 disk_buf2[256] __attribute__((__aligned__(512))); - -void taskA_entry() { - current->priority = 7; - - while (1) { - sysc_wait(97); - - uint64_t sect_nr = get_next_deubug_sect_nr(); - memset(disk_buf1, 0, 512); - - disk_request_t r; - r.dev = MAKE_DISK_DEV(0, 0); - r.command = DISK_REQ_READ; - r.pos = sect_nr; - r.count = 1; - r.buf = disk_buf1; - r.bb = 0; - - send_disk_request(&r); - - // verify_hd_data(sect_nr, disk_buf1, current->name); - - for (int i = 0; i < 2; i++) { - asm("hlt;"); - } - } -} - -void taskB_entry() { - current->priority = 13; - - while (1) { - sysc_wait(7); - // uint64_t sect_nr = get_next_deubug_sect_nr(); - // memset(disk_buf2, 0, 512); - // disk_request_t r; - // r.dev = MAKE_DISK_DEV(2, 0); - // r.command = DISK_REQ_READ; - // r.pos = sect_nr; - // r.count = 1; - // r.buf = disk_buf2; - // r.bb = 0; - - // send_disk_request(&r); - // // verify_hd_data(sect_nr, disk_buf2, current->name); - - // for (int i = 0; i < 1; i++) { - // asm("hlt;"); - // } - } -} - -void taskC_entry() { - current->priority = 17; - - while (1) { - sysc_wait(100); - - for (int i = 0; i < 7; i++) { - asm("hlt;"); - } - } + printd("kernel pid %d %s\n", pid, name); } // 从multiboot.S进入这里 void root_task_entry() { - sti(); + printk("%08x %s %u %u\n", current, current->name, current->ticks, current->priority); - extern __attribute__((regparm(0))) long sysc_mkdir(const char *path, int mode); - sysc_mkdir("/root", 0777); - sysc_mkdir("/root/aaa", 0777); +#if 0 + pt_regs_t *regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)(&root_task))) - 1; - { - namei_t ni; - const char *path = "/root"; - path_init(path, 0, &ni); - path_walk(path, &ni); + uint32_t *p = (uint32_t *) (TASK_SIZE + (unsigned long)(&root_task)) - 1; + for(int i=0; i<16; i++) { + *p = 0x1200 | i; + p--; } +#endif - // 有一点点垃圾事情需要处理 - // 之前内核初始化都是在关中断下进行的 - // 这就段时间有可能按键盘,然而键盘不把数据读出来就不会触发下一次中断 - // 所以得先清空一下键盘 - inb(0x60); - // - void disk_init(); - disk_init(); + sti(); kernel_task("init", init_task_entry, NULL); - kernel_task("ide/0", disk_task_entry, (void *)0); - kernel_task("ide/1", disk_task_entry, (void *)1); - kernel_task("user", user_task_entry, NULL); - - // for (int i = 0; i < 100; i++) { - // asm("hlt;"); - // } - -#if 1 - kernel_task("tskA", taskA_entry, NULL); - kernel_task("tskB", taskB_entry, NULL); - kernel_task("tskC", taskC_entry, NULL); -#endif + + schedule(); current->priority = 1; while (1) { -- 2.44.0