From: AceVest Date: Sun, 6 Jul 2014 14:52:22 +0000 (+0800) Subject: add request to hard disk X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/Bv9ARM.ch05.html?a=commitdiff_plain;h=3a881f64c01a130c00e71ee68881f5e0d67bb0d6;p=kernel.git add request to hard disk --- diff --git a/drivers/ide.c b/drivers/ide.c index 6c11252..ab65b26 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -16,6 +16,11 @@ #include #include #include +#include +#include + +DECLARE_MUTEX(mutex); +void ide_cmd_out(dev_t dev, u32 sect_cnt, u64 sect_nr, u32 cmd); unsigned int HD_CHL0_CMD_BASE = 0x1F0; unsigned int HD_CHL1_CMD_BASE = 0x170; @@ -53,6 +58,78 @@ typedef struct prd unsigned int eot : 1; } prd_t; +typedef struct { + u64_t lba; + u32_t scnt; + char *buf; + bool finish; + list_head_t list; + wait_queue_head_t wait; +} ide_request_t; + +#define IDE_REQ_LIST 0 + +#if IDE_REQ_LIST +LIST_HEAD(ide_request); +#else +ide_request_t ide_request; +#endif + + +void ide_do_read(u64_t lba, u32_t scnt, char *buf) +{ + bool finish = false; + unsigned long flags; + +#if IDE_REQ_LIST + ide_request_t *r = kmalloc(sizeof(ide_request_t), 0); + if(r == 0) + panic("out of memory"); + + memset(r, 0, sizeof(ide_request_t)); +#else + ide_request_t *r = &ide_request; +#endif + + down(&mutex); + + r->lba = lba; + r->scnt= scnt; + r->buf = buf; + r->finish = false; + INIT_LIST_HEAD(&r->list); + init_wait_queue(&r->wait); + + task_union * task = current; + DECLARE_WAIT_QUEUE(wait, task); + add_wait_queue(&r->wait, &wait); + + ide_cmd_out(0, scnt, lba, HD_CMD_READ_EXT); + + while(true) + { + printl("%s pid %d is going to wait\n", __func__, sysc_getpid()); + task->state = TASK_WAIT; + irq_save(flags); + finish = r->finish; + irq_restore(flags); + + if(finish) + break; + + schedule(); + printl("%s pid %d is running\n", __func__, sysc_getpid()); + } + + printl("%s pid %d is really running\n", __func__, sysc_getpid()); + task->state = TASK_RUNNING; + del_wait_queue(&r->wait, &wait); + +#if IDE_REQ_LIST + kfree(r); +#endif +} + unsigned char *data = 0; unsigned int sys_clock(); @@ -113,7 +190,7 @@ void _ide_cmd_out(dev_t dev, u32 sect_cnt, u64 sect_nr, u32 cmd, bool pio) ide_printd(); outb(0x00|(pio?0:HD_CTL_NIEN), REG_CTL(dev)); - outb(0x40|0x00, REG_DEVSEL(dev)); + outb(0x40|0x10, REG_DEVSEL(dev)); outb((u8)((sect_cnt>>8)&0xFF), REG_NSECTOR(dev)); // High outb((u8)((sect_nr>>24)&0xFF), REG_LBAL(dev)); @@ -175,7 +252,6 @@ void ide_debug() ide_cmd_out(0, nsect, sect_nr, HD_CMD_READ_EXT); } -DECLARE_MUTEX(mutex); void init_pci_controller(unsigned int classcode) { @@ -210,8 +286,12 @@ void ide_default_intr() u16_t sig = 0; if(drv.read_mode == HD_CMD_READ_EXT) { +#if IDE_REQ_LIST insl(REG_DATA(0), ide_buf, (512>>2)); sig = *((u16_t *) (ide_buf+510)); +#else + insl(REG_DATA(0), ide_request.buf, ((ide_request.scnt*SECT_SIZE)>>2)); +#endif } if(drv.read_mode == HD_CMD_READ_DMA) @@ -221,10 +301,16 @@ void ide_default_intr() ide_printd(); - printk("hard disk sig %04x read mode %x cnt %d\n", sig, drv.read_mode, drv.irq_cnt); + printl(" hard disk sig %04x read mode %x cnt %d\n", sig, drv.read_mode, drv.irq_cnt); printd(MPL_IDE_INTR, "hard disk sig %x read mode %x cnt %d", sig, drv.read_mode, drv.irq_cnt); outb(PCI_IDE_CMD_STOP, drv.bus_cmd); +#if IDE_REQ_LIST +#else + wake_up(&ide_request.wait); + ide_request.finish = true; +#endif + up(&mutex); } @@ -434,13 +520,20 @@ void ide_init_wait_intr() } } -void ide_init_wait_read(u64 lba, char *buf) +#if 0 +void ide_init_wait_read(u64_t lba, char *buf) { ide_init_buf = buf; ide_intr_func = ide_init_intr; _ide_cmd_out(0, 1, lba, HD_CMD_READ_EXT, true); ide_init_wait_intr(); } +#else +void ide_init_wait_read(u64_t lba, char *buf) +{ + ide_do_read(lba, 1, buf); +} +#endif void ide_read_extended_partition(u64_t lba, unsigned int inx) { diff --git a/drivers/vga.c b/drivers/vga.c index 00c639c..6f422cd 100644 --- a/drivers/vga.c +++ b/drivers/vga.c @@ -41,8 +41,9 @@ typedef struct { unsigned int offset; } vga_screen_t; -#define VGA_MAX_SCREEN_CNT 4 -unsigned int vga_screen_cnt() {return VGA_MAX_SCREEN_CNT;} +#define VGA_SCREEN_CNT 3 +#define VGA_MAX_SCREEN_CNT ((VGA_SCREEN_CNT) + 1) +unsigned int vga_screen_cnt() {return VGA_SCREEN_CNT;} vga_screen_t vga_screen[VGA_MAX_SCREEN_CNT] = { { 0, diff --git a/fs/bak.ext2.c b/fs/bak.ext2.c new file mode 100644 index 0000000..bc0df52 --- /dev/null +++ b/fs/bak.ext2.c @@ -0,0 +1,317 @@ +/* + *-------------------------------------------------------------------------- + * File Name: ext2.c + * + * Author: Zhao Yanbai [zhaoyanbai@126.com] + * Sun Feb 14 15:52:01 2010 + * + * Description: none + * + *-------------------------------------------------------------------------- + */ + +#include +#include +#include +#include + +unsigned int ext2_start_sect; +Inode ext2_root_inode; + +void hd_read(dev_t dev, u64 sect_nr, void *buf, u32 count) { /*TODO*/ } +void ext2_read_block(int block_id, char *buf); +static void ext2_print_group_descriptor(pGroupDesc p); +static void ext2_print_inode(pInode p); +int ext2_search_file(const char *file, const pInode in, pInode out); +//char *ext2_loadfile(const char *path, size_t *file_size); + +/* ext2 super block */ +SuperBlock ext2_sb + __attribute__((__aligned__(PAGE_SIZE))); +Inode inode_table[NR_INODES] + __attribute__((__aligned__(PAGE_SIZE))) = {{0,},}; +/* + * ext2 group descriptor table + * 其大小为一个EXT2_BLOCK_SIZE + */ +static pGroupDesc gdesc; + +void setup_ext2() +{ + int i; + + hd_read(ROOT_DEV, ext2_start_sect+2, EXT2_SB, sizeof(SuperBlock)); + printk("EXT2 SB:%x\n", sizeof(SuperBlock)); + printk("inodes count: %d\n", EXT2_SB->s_inodes_count); + printk("blocks count: %d\n", EXT2_SB->s_blocks_count); + printk("s_magic: %x\n", EXT2_SB->s_magic); + printk("LOG BLOCK SIZE:%x\n", EXT2_SB->s_log_block_size); + printk("Block Size:%d %x\n", EXT2_BLOCK_SIZE, EXT2_BLOCK_SIZE); + + + if(EXT2_SB->s_magic != 0xEF53) + panic("Only Support Ext2 File System..."); + + /* 分配group descriptor table 的内存 */ + gdesc = (pGroupDesc) kmalloc_old(EXT2_BLOCK_SIZE); + if(gdesc == NULL) + panic("out of memory for ext2 group descritpor table"); + /* 初始化ext2 group descriptor table */ + ext2_read_block(EXT2_FIRST_BLOCK_ID+1, (char *)gdesc); +#if 0 + printk("-------%d %d %d", + EXT2_BLOCK_SIZE, EXT2_INODE_SIZE, EXT2_INODES_PER_BLOCK); + for(i=0; i<12; i++) + ext2_print_group_descriptor(gdesc+i); +#endif + + ext2_read_inode(2, &ext2_root_inode); +#if 1 + ext2_print_inode(&ext2_root_inode); +#endif + +#if 0 + Inode boot_ino, grub_ino, grubconf_ino; + int boot_n, grub_n, grubconf_n; + boot_n = ext2_search_file("boot", &ext2_root_inode, &boot_ino); + printk("boot_n:%d size:%d\n", boot_n, boot_ino.i_size); + grub_n = ext2_search_file("grub", &boot_ino, &grub_ino); + printk("grub_n:%d size:%d\n", grub_n, grub_ino.i_size); + grubconf_n = ext2_search_file("grub.conf", + &grub_ino, &grubconf_ino); + printk("grubconf_n:%d size:%d\n", grubconf_n, grubconf_ino.i_size); +#endif +#if 0 + size_t filesz; + char *buf=ext2_loadfile("/boot/grub/grub.conf", &filesz); + + for(i=0; ibg_inode_table; + + // 跳过完整的BLOCK + inotbl += (gidx/EXT2_INODES_PER_BLOCK); + gidx %= EXT2_INODES_PER_BLOCK; + + + char *buf = kmalloc_old(EXT2_BLOCK_SIZE); + if(buf == NULL) + panic("faild read inode. out of memory"); + ext2_read_block(inotbl, buf); + + memcpy((void *)ino,(void*)(((pInode)buf)+gidx), EXT2_INODE_SIZE); + + kfree_old(buf); + + return n; +} +int ext2_read_file(const pInode ino, void *buf, size_t count) +{ + int i, blks; + void *p; + + blks = (ino->i_size+EXT2_BLOCK_SIZE-1)/EXT2_BLOCK_SIZE; + assert(blks>0); + + if(blks > EXT2_NDIR_BLOCKS) + panic("file too large to read"); + + p = kmalloc_old(blks*EXT2_BLOCK_SIZE); + + if(p == NULL) + panic("out of memory when search inode in directory"); + + for(i=0; ii_block[i], + (char *)(i*EXT2_BLOCK_SIZE + (unsigned long)p)); + } + + memcpy(buf, p, count); + + kfree_old(p); + + return count; +} +#if 0 +char *load_inode_content(const pInode ino) +{ + int i, blks; + char *buf; + + blks = (ino->i_size+EXT2_BLOCK_SIZE-1)/EXT2_BLOCK_SIZE; + assert(blks>0); + if(blks > EXT2_NDIR_BLOCKS) + panic("unsupport file large than 12KB"); + + + buf = kmalloc_old(blks*EXT2_BLOCK_SIZE); + if(buf == NULL) + panic("out of memory when search inode in directory"); + for(i=0; ii_block[i], buf + i*EXT2_BLOCK_SIZE); + } + + return buf; +} +#endif + +/* + * 从in中查找file从out返回 + * int 型的函数返回值的意思是inode号 + * 失败则返回的是EXT2_BAD_INO + */ +int ext2_search_file(const char *file, const pInode in, pInode out) +{ + assert(file != NULL); + assert(in != NULL); + assert(S_ISDIR(in->i_mode)); + + char *buf; +#if 0 + buf = load_inode_content(in); +#else + buf = kmalloc_old(in->i_size); + ext2_read_file(in, buf, in->i_size); +#endif + + pDirEnt ent = (pDirEnt)buf; + int len = strlen(file); + int inode_n = EXT2_BAD_INO; + while(ent < (pDirEnt)(buf + in->i_size)) + { + if(ent->name_len == len) + { + if(strncmp(file, ent->name, ent->name_len) == 0) + { + inode_n = ent->inode; +#if 0 + printk("file: %s\n", ent->name); +#endif + break; + } + } + + + ent = (pDirEnt)(ent->rec_len + (unsigned long)ent); + } + kfree_old(buf); + + ext2_read_inode(inode_n, out); + + return inode_n; +} + + +static int get_filename_from_path(const char *path, char *filename) +{ + int i = 0; + + while(*path != '/' && *path != '\0') + { + filename[i++] = *path++; + } + filename[i] = 0; + + + return i; // file name len +} + + +int ext2_get_file_inode_nr(const char *path) +{ + assert(*path++ == '/'); /* 目前只支持从根目录开始的路径 */ + Inode ino = ext2_root_inode; + int ino_nr, len; + char file[EXT2_NAME_LEN]; + + while((len=get_filename_from_path(path, file)) != 0) + { +#if 0 + printk("file: %s ", file); +#endif + ino_nr = ext2_search_file(file, &ino, &ino); + + path += len; + + if(*path != 0) + path++; + } +#if 0 + printk("ino_nr:%d\n", ino_nr); +#endif + return ino_nr; +} + +#if 0 +/* + * 需要自己释放内存 + */ +char *ext2_loadfile(const char *path, size_t *file_size) +{ + char *buf; + buf = load_inode_content(&inode); + *file_size = inode.i_size; + + return buf; +} +#endif + +static void ext2_print_group_descriptor(pGroupDesc p) +{ + printk("block bitmap:%d inode bitmap:%d inode table:%d\n", + p->bg_block_bitmap, + p->bg_inode_bitmap, + p->bg_inode_table); +} + +static void ext2_print_inode(pInode p) +{ + printk("i_mode:%04x i_size:%d i_blocks:%d\n", + p->i_mode, p->i_size, p->i_blocks); +} diff --git a/fs/ext2.c b/fs/ext2.c index bc0df52..b815ed7 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -1,317 +1,9 @@ /* - *-------------------------------------------------------------------------- + * ------------------------------------------------------------------------ * File Name: ext2.c - * - * Author: Zhao Yanbai [zhaoyanbai@126.com] - * Sun Feb 14 15:52:01 2010 - * + * Author: Zhao Yanbai + * Sun Jul 6 13:23:05 2014 * Description: none - * - *-------------------------------------------------------------------------- + * ------------------------------------------------------------------------ */ - -#include -#include -#include -#include - -unsigned int ext2_start_sect; -Inode ext2_root_inode; - -void hd_read(dev_t dev, u64 sect_nr, void *buf, u32 count) { /*TODO*/ } -void ext2_read_block(int block_id, char *buf); -static void ext2_print_group_descriptor(pGroupDesc p); -static void ext2_print_inode(pInode p); -int ext2_search_file(const char *file, const pInode in, pInode out); -//char *ext2_loadfile(const char *path, size_t *file_size); - -/* ext2 super block */ -SuperBlock ext2_sb - __attribute__((__aligned__(PAGE_SIZE))); -Inode inode_table[NR_INODES] - __attribute__((__aligned__(PAGE_SIZE))) = {{0,},}; -/* - * ext2 group descriptor table - * 其大小为一个EXT2_BLOCK_SIZE - */ -static pGroupDesc gdesc; - -void setup_ext2() -{ - int i; - - hd_read(ROOT_DEV, ext2_start_sect+2, EXT2_SB, sizeof(SuperBlock)); - printk("EXT2 SB:%x\n", sizeof(SuperBlock)); - printk("inodes count: %d\n", EXT2_SB->s_inodes_count); - printk("blocks count: %d\n", EXT2_SB->s_blocks_count); - printk("s_magic: %x\n", EXT2_SB->s_magic); - printk("LOG BLOCK SIZE:%x\n", EXT2_SB->s_log_block_size); - printk("Block Size:%d %x\n", EXT2_BLOCK_SIZE, EXT2_BLOCK_SIZE); - - - if(EXT2_SB->s_magic != 0xEF53) - panic("Only Support Ext2 File System..."); - - /* 分配group descriptor table 的内存 */ - gdesc = (pGroupDesc) kmalloc_old(EXT2_BLOCK_SIZE); - if(gdesc == NULL) - panic("out of memory for ext2 group descritpor table"); - /* 初始化ext2 group descriptor table */ - ext2_read_block(EXT2_FIRST_BLOCK_ID+1, (char *)gdesc); -#if 0 - printk("-------%d %d %d", - EXT2_BLOCK_SIZE, EXT2_INODE_SIZE, EXT2_INODES_PER_BLOCK); - for(i=0; i<12; i++) - ext2_print_group_descriptor(gdesc+i); -#endif - - ext2_read_inode(2, &ext2_root_inode); -#if 1 - ext2_print_inode(&ext2_root_inode); -#endif - -#if 0 - Inode boot_ino, grub_ino, grubconf_ino; - int boot_n, grub_n, grubconf_n; - boot_n = ext2_search_file("boot", &ext2_root_inode, &boot_ino); - printk("boot_n:%d size:%d\n", boot_n, boot_ino.i_size); - grub_n = ext2_search_file("grub", &boot_ino, &grub_ino); - printk("grub_n:%d size:%d\n", grub_n, grub_ino.i_size); - grubconf_n = ext2_search_file("grub.conf", - &grub_ino, &grubconf_ino); - printk("grubconf_n:%d size:%d\n", grubconf_n, grubconf_ino.i_size); -#endif -#if 0 - size_t filesz; - char *buf=ext2_loadfile("/boot/grub/grub.conf", &filesz); - - for(i=0; ibg_inode_table; - - // 跳过完整的BLOCK - inotbl += (gidx/EXT2_INODES_PER_BLOCK); - gidx %= EXT2_INODES_PER_BLOCK; - - - char *buf = kmalloc_old(EXT2_BLOCK_SIZE); - if(buf == NULL) - panic("faild read inode. out of memory"); - ext2_read_block(inotbl, buf); - - memcpy((void *)ino,(void*)(((pInode)buf)+gidx), EXT2_INODE_SIZE); - - kfree_old(buf); - - return n; -} -int ext2_read_file(const pInode ino, void *buf, size_t count) -{ - int i, blks; - void *p; - - blks = (ino->i_size+EXT2_BLOCK_SIZE-1)/EXT2_BLOCK_SIZE; - assert(blks>0); - - if(blks > EXT2_NDIR_BLOCKS) - panic("file too large to read"); - - p = kmalloc_old(blks*EXT2_BLOCK_SIZE); - - if(p == NULL) - panic("out of memory when search inode in directory"); - - for(i=0; ii_block[i], - (char *)(i*EXT2_BLOCK_SIZE + (unsigned long)p)); - } - - memcpy(buf, p, count); - - kfree_old(p); - - return count; -} -#if 0 -char *load_inode_content(const pInode ino) -{ - int i, blks; - char *buf; - - blks = (ino->i_size+EXT2_BLOCK_SIZE-1)/EXT2_BLOCK_SIZE; - assert(blks>0); - if(blks > EXT2_NDIR_BLOCKS) - panic("unsupport file large than 12KB"); - - - buf = kmalloc_old(blks*EXT2_BLOCK_SIZE); - if(buf == NULL) - panic("out of memory when search inode in directory"); - for(i=0; ii_block[i], buf + i*EXT2_BLOCK_SIZE); - } - - return buf; -} -#endif - -/* - * 从in中查找file从out返回 - * int 型的函数返回值的意思是inode号 - * 失败则返回的是EXT2_BAD_INO - */ -int ext2_search_file(const char *file, const pInode in, pInode out) -{ - assert(file != NULL); - assert(in != NULL); - assert(S_ISDIR(in->i_mode)); - - char *buf; -#if 0 - buf = load_inode_content(in); -#else - buf = kmalloc_old(in->i_size); - ext2_read_file(in, buf, in->i_size); -#endif - - pDirEnt ent = (pDirEnt)buf; - int len = strlen(file); - int inode_n = EXT2_BAD_INO; - while(ent < (pDirEnt)(buf + in->i_size)) - { - if(ent->name_len == len) - { - if(strncmp(file, ent->name, ent->name_len) == 0) - { - inode_n = ent->inode; -#if 0 - printk("file: %s\n", ent->name); -#endif - break; - } - } - - - ent = (pDirEnt)(ent->rec_len + (unsigned long)ent); - } - kfree_old(buf); - - ext2_read_inode(inode_n, out); - - return inode_n; -} - - -static int get_filename_from_path(const char *path, char *filename) -{ - int i = 0; - - while(*path != '/' && *path != '\0') - { - filename[i++] = *path++; - } - filename[i] = 0; - - - return i; // file name len -} - - -int ext2_get_file_inode_nr(const char *path) -{ - assert(*path++ == '/'); /* 目前只支持从根目录开始的路径 */ - Inode ino = ext2_root_inode; - int ino_nr, len; - char file[EXT2_NAME_LEN]; - - while((len=get_filename_from_path(path, file)) != 0) - { -#if 0 - printk("file: %s ", file); -#endif - ino_nr = ext2_search_file(file, &ino, &ino); - - path += len; - - if(*path != 0) - path++; - } -#if 0 - printk("ino_nr:%d\n", ino_nr); -#endif - return ino_nr; -} - -#if 0 -/* - * 需要自己释放内存 - */ -char *ext2_loadfile(const char *path, size_t *file_size) -{ - char *buf; - buf = load_inode_content(&inode); - *file_size = inode.i_size; - - return buf; -} -#endif - -static void ext2_print_group_descriptor(pGroupDesc p) -{ - printk("block bitmap:%d inode bitmap:%d inode table:%d\n", - p->bg_block_bitmap, - p->bg_inode_bitmap, - p->bg_inode_table); -} - -static void ext2_print_inode(pInode p) -{ - printk("i_mode:%04x i_size:%d i_blocks:%d\n", - p->i_mode, p->i_size, p->i_blocks); -} +#include "ext2.h" diff --git a/include/bak.ext2.h b/include/bak.ext2.h new file mode 100644 index 0000000..a5474d2 --- /dev/null +++ b/include/bak.ext2.h @@ -0,0 +1,238 @@ +/* + *-------------------------------------------------------------------------- + * File Name: ext2.h + * + * Description: 当然.几乎来自Linux 内核. + * + * + * Author: Zhao Yanbai [zhaoyanbai@126.com] + * + * Version: 1.0 + * Create Date: Fri Dec 26 22:43:43 2008 + * Last Update: Fri Dec 26 22:43:43 2008 + * + *-------------------------------------------------------------------------- + */ + +#ifndef _EXT2_H +#define _EXT2_H + +#include + +#define EXT2_BAD_INO 1 +#define EXT2_ROOT_INO 2 +#define EXT2_BOOT_LOADER_INO 5 +#define EXT2_UNDEL_DIR_INO 6 + +#define EXT2_MIN_BLOCK_SIZE 1024 +#define EXT2_MAX_BLOCK_SIZE 4096 +#define EXT2_MIN_BLOCK_LOG_SIZE 10 + +#define EXT2_SB (&ext2_sb) +#define EXT2_SECT (ext2_start_sect) + +#ifndef EXT2_SB +#error "Please define EXT2_SB" +#endif + +#define EXT2_BLOCK_SIZE (EXT2_MIN_BLOCK_SIZE << \ + (EXT2_SB)->s_log_block_size) + +#define EXT2_SECT_PER_BLOCK (EXT2_BLOCK_SIZE/512) + +#define EXT2_BLOCK_SIZE_BITS ((EXT2_SB)->s_log_block_size + 10) +#define EXT2_INODE_SIZE ((EXT2_SB)->s_inode_size) +#define EXT2_INODES_PER_BLOCK (EXT2_BLOCK_SIZE/EXT2_INODE_SIZE) +#define EXT2_FIRST_INO ((EXT2_SB)->s_first_ino) +/* + * 表示第一个块号. 因为SuperBlock总是从第三个扇区开始的所以如果块的大小 + * 是1024的话SuperBlock的块号是1.而如果块的大小是2048或4096则SuperBlock + * 的块号是0 + */ +#define EXT2_FIRST_BLOCK_ID (EXT2_BLOCK_SIZE == 1024) + +#define EXT2_BLOCKS_PER_GROUP ((EXT2_SB)->s_blocks_per_group) +#define EXT2_DESC_PER_BLOCK ((EXT2_SB)->s_desc_per_block) +#define EXT2_INODES_PER_GROUP ((EXT2_SB)->s_inodes_per_group) +#define EXT2_INODES_COUNT ((EXT2_SB)->s_inodes_count) + +/* + * ------------------------------------------------------------------------ + * EXT2 FILE SYSTEM PART + * ------------------------------------------------------------------------ + */ +typedef struct ext2_superblock +{ +/* + u32 s_inodes_count; + u32 s_blocks_count; + u32 s_r_blocks_count; + u32 s_free_blocks_count; + u32 s_free_inodes_count; + u32 s_first_data_block; + u32 s_log_block_size; + u32 s_log_frag_size; + u32 s_blocks_per_group; + u32 s_frags_per_group; + u32 s_inodes_per_group; + + // So Much Items + // I do not want to write down ... +*/ + u32 s_inodes_count; /* Inodes count */ + u32 s_blocks_count; /* Blocks count */ + u32 s_r_blocks_count; /* Reserved blocks count */ + u32 s_free_blocks_count; /* Free blocks count */ + u32 s_free_inodes_count; /* Free inodes count */ + u32 s_first_data_block; /* First Data Block */ + u32 s_log_block_size; /* Block size */ + u32 s_log_frag_size; /* Fragment size */ + u32 s_blocks_per_group; /* # Blocks per group */ + u32 s_frags_per_group; /* # Fragments per group */ + u32 s_inodes_per_group; /* # Inodes per group */ + u32 s_mtime; /* Mount time */ + u32 s_wtime; /* Write time */ + u16 s_mnt_count; /* Mount count */ + u16 s_max_mnt_count; /* Maximal mount count */ + u16 s_magic; /* Magic signature */ + u16 s_state; /* File system state */ + u16 s_errors; /* Behaviour when detecting errors */ + u16 s_minor_rev_level; /* minor revision level */ + u32 s_lastcheck; /* time of last check */ + u32 s_checkinterval; /* max. time between checks */ + u32 s_creator_os; /* OS */ + u32 s_rev_level; /* Revision level */ + u16 s_def_resuid; /* Default uid for reserved blocks */ + u16 s_def_resgid; /* Default gid for reserved blocks */ + /* + * These fields are for EXT2_DYNAMIC_REV superblocks only. + * + * Note: the difference between the compatible feature set and + * the incompatible feature set is that if there is a bit set + * in the incompatible feature set that the kernel doesn't + * know about, it should refuse to mount the filesystem. + * + * e2fsck's requirements are more strict; if it doesn't know + * about a feature in either the compatible or incompatible + * feature set, it must abort and not try to meddle with + * things it doesn't understand... + */ + u32 s_first_ino; /* First non-reserved inode */ + u16 s_inode_size; /* size of inode structure */ + u16 s_block_group_nr; /* block group # of this superblock */ + u32 s_feature_compat; /* compatible feature set */ + u32 s_feature_incompat; /* incompatible feature set */ + u32 s_feature_ro_compat; /* readonly-compatible feature set */ + u8 s_uuid[16]; /* 128-bit uuid for volume */ + char s_volume_name[16]; /* volume name */ + char s_last_mounted[64]; /* directory where last mounted */ + u32 s_algorithm_usage_bitmap; /* For compression */ + /* + * Performance hints. Directory preallocation should only + * happen if the EXT2_COMPAT_PREALLOC flag is on. + */ + u8 s_prealloc_blocks;/* Nr of blocks to try to preallocate*/ + u8 s_prealloc_dir_blocks;/* Nr to preallocate for dirs */ + u16 s_padding1; + /* + * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. + */ + u8 s_journal_uuid[16]; /* uuid of journal superblock */ + u32 s_journal_inum; /* inode number of journal file */ + u32 s_journal_dev; /* device number of journal file */ + u32 s_last_orphan; /* start of list of inodes to delete */ + u32 s_hash_seed[4]; /* HTREE hash seed */ + u8 s_def_hash_version; /* Default hash version to use */ + u8 s_reserved_char_pad; + u16 s_reserved_word_pad; + u32 s_default_mount_opts; + u32 s_first_meta_bg; /* First metablock block group */ + u32 s_reserved[190];/* Padding to the end of the block */ +} SuperBlock,*pSuperBlock; + +extern SuperBlock ext2_sb; + + +typedef struct ext2_group_descriptor +{ + u32 bg_block_bitmap; + u32 bg_inode_bitmap; + u32 bg_inode_table; + u16 bg_free_blocks_count; + u16 bg_free_inodes_count; + u16 bg_used_dirs_count; + u16 bg_pad; + u32 bg_reserved[3]; +} GroupDesc,*pGroupDesc; + +#define EXT2_NDIR_BLOCKS (12) +#define EXT2_IND_BLOCK (EXT2_NDIR_BLOCKS) +#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) +#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) +#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) + + +typedef struct ext2_inode +{ + u16 i_mode; + u16 i_uid; + u32 i_size; + u32 i_atime; + u32 i_ctime; + u32 i_mtime; + u32 i_dtime; + u16 i_gid; + u16 i_links_count; + u32 i_blocks; + u32 i_flags; + u32 i_osd1; + u32 i_block[EXT2_N_BLOCKS]; + u32 i_generation; + u32 i_file_acl; + u32 i_dir_acl; + u32 i_faddr; + u8 i_osd2[12]; +} Inode,*pInode; + + +#define EXT2_NAME_LEN 255 +typedef struct ext2_dir_ent +{ + u32 inode; + u16 rec_len; + u8 name_len; + u8 file_type; /* 目录类型 */ + char name[EXT2_NAME_LEN]; +} DirEnt, *pDirEnt; + +/* + * Ext2 目录类型. + * 到目前为止只有低3位有效. + */ +enum +{ + EXT2_FT_UNKNOWN, + EXT2_FT_REG_FILE, + EXT2_FT_DIR, + EXT2_FT_CHRDEV, + EXT2_FT_BLKDEV, + EXT2_FT_FIFO, + EXT2_FT_SOCK, + EXT2_FT_SYMLINK, + EXT2_FT_MAX +}; + + +#define EXT2_DIR_PAD 4 +#define EXT2_DIR_ROUND (EXT2_DIR_PAD-1) +#define EXT2_DIR_REC_LEN(name_len) (((name_len)+8+EXT2_DIR_ROUND) & \ + ~EXT2_DIR_ROUND) +#define EXT2_MAX_REC_LEN ((1<<16)-1) + + +extern int ext2_read_inode(unsigned int n, pInode inode); +extern int ext2_get_file_inode(const char *path, pInode inode); +extern int ext2_read_file(const pInode ino, void *buf, size_t count); + + +#endif //_EXT2_H diff --git a/include/ext2.h b/include/ext2.h index f105ed8..befc6b2 100644 --- a/include/ext2.h +++ b/include/ext2.h @@ -14,29 +14,21 @@ *-------------------------------------------------------------------------- */ -#ifndef _EXT2_H +#ifndef _EXT2_H #define _EXT2_H #include -#define EXT2_BAD_INO 1 -#define EXT2_ROOT_INO 2 +#define EXT2_BAD_INO 1 +#define EXT2_ROOT_INO 2 #define EXT2_BOOT_LOADER_INO 5 -#define EXT2_UNDEL_DIR_INO 6 +#define EXT2_UNDEL_DIR_INO 6 -#define EXT2_MIN_BLOCK_SIZE 1024 -#define EXT2_MAX_BLOCK_SIZE 4096 -#define EXT2_MIN_BLOCK_LOG_SIZE 10 +#define EXT2_MIN_BLOCK_SIZE 1024 +#define EXT2_MAX_BLOCK_SIZE 4096 +#define EXT2_MIN_BLOCK_LOG_SIZE 10 -#define EXT2_SB (&ext2_sb) -#define EXT2_SECT (ext2_start_sect) - -#ifndef EXT2_SB -#error "Please define EXT2_SB" -#endif - -#define EXT2_BLOCK_SIZE (EXT2_MIN_BLOCK_SIZE << \ - (EXT2_SB)->s_log_block_size) +#define EXT2_BLOCK_SIZE (EXT2_MIN_BLOCK_SIZE << (EXT2_SB)->s_log_block_size) #define EXT2_SECT_PER_BLOCK (EXT2_BLOCK_SIZE/512) @@ -63,47 +55,31 @@ */ typedef struct ext2_superblock { -/* - u32 s_inodes_count; - u32 s_blocks_count; - u32 s_r_blocks_count; - u32 s_free_blocks_count; - u32 s_free_inodes_count; - u32 s_first_data_block; - u32 s_log_block_size; - u32 s_log_frag_size; - u32 s_blocks_per_group; - u32 s_frags_per_group; - u32 s_inodes_per_group; - - // So Much Items - // I do not want to write down ... -*/ - u32 s_inodes_count; /* Inodes count */ - u32 s_blocks_count; /* Blocks count */ + u32 s_inodes_count; /* Inodes count */ + u32 s_blocks_count; /* Blocks count */ u32 s_r_blocks_count; /* Reserved blocks count */ - u32 s_free_blocks_count; /* Free blocks count */ - u32 s_free_inodes_count; /* Free inodes count */ - u32 s_first_data_block; /* First Data Block */ + u32 s_free_blocks_count; /* Free blocks count */ + u32 s_free_inodes_count; /* Free inodes count */ + u32 s_first_data_block; /* First Data Block */ u32 s_log_block_size; /* Block size */ - u32 s_log_frag_size; /* Fragment size */ - u32 s_blocks_per_group; /* # Blocks per group */ - u32 s_frags_per_group; /* # Fragments per group */ - u32 s_inodes_per_group; /* # Inodes per group */ - u32 s_mtime; /* Mount time */ - u32 s_wtime; /* Write time */ - u16 s_mnt_count; /* Mount count */ - u16 s_max_mnt_count; /* Maximal mount count */ - u16 s_magic; /* Magic signature */ - u16 s_state; /* File system state */ - u16 s_errors; /* Behaviour when detecting errors */ - u16 s_minor_rev_level; /* minor revision level */ - u32 s_lastcheck; /* time of last check */ - u32 s_checkinterval; /* max. time between checks */ + u32 s_log_frag_size; /* Fragment size */ + u32 s_blocks_per_group; /* # Blocks per group */ + u32 s_frags_per_group; /* # Fragments per group */ + u32 s_inodes_per_group; /* # Inodes per group */ + u32 s_mtime; /* Mount time */ + u32 s_wtime; /* Write time */ + u16 s_mnt_count; /* Mount count */ + u16 s_max_mnt_count; /* Maximal mount count */ + u16 s_magic; /* Magic signature */ + u16 s_state; /* File system state */ + u16 s_errors; /* Behaviour when detecting errors */ + u16 s_minor_rev_level; /* minor revision level */ + u32 s_lastcheck; /* time of last check */ + u32 s_checkinterval; /* max. time between checks */ u32 s_creator_os; /* OS */ - u32 s_rev_level; /* Revision level */ - u16 s_def_resuid; /* Default uid for reserved blocks */ - u16 s_def_resgid; /* Default gid for reserved blocks */ + u32 s_rev_level; /* Revision level */ + u16 s_def_resuid; /* Default uid for reserved blocks */ + u16 s_def_resgid; /* Default gid for reserved blocks */ /* * These fields are for EXT2_DYNAMIC_REV superblocks only. * @@ -118,14 +94,14 @@ typedef struct ext2_superblock * things it doesn't understand... */ u32 s_first_ino; /* First non-reserved inode */ - u16 s_inode_size; /* size of inode structure */ - u16 s_block_group_nr; /* block group # of this superblock */ - u32 s_feature_compat; /* compatible feature set */ - u32 s_feature_incompat; /* incompatible feature set */ + u16 s_inode_size; /* size of inode structure */ + u16 s_block_group_nr; /* block group # of this superblock */ + u32 s_feature_compat; /* compatible feature set */ + u32 s_feature_incompat; /* incompatible feature set */ u32 s_feature_ro_compat; /* readonly-compatible feature set */ - u8 s_uuid[16]; /* 128-bit uuid for volume */ - char s_volume_name[16]; /* volume name */ - char s_last_mounted[64]; /* directory where last mounted */ + u8 s_uuid[16]; /* 128-bit uuid for volume */ + char s_volume_name[16]; /* volume name */ + char s_last_mounted[64]; /* directory where last mounted */ u32 s_algorithm_usage_bitmap; /* For compression */ /* * Performance hints. Directory preallocation should only @@ -137,21 +113,18 @@ typedef struct ext2_superblock /* * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. */ - u8 s_journal_uuid[16]; /* uuid of journal superblock */ - u32 s_journal_inum; /* inode number of journal file */ - u32 s_journal_dev; /* device number of journal file */ - u32 s_last_orphan; /* start of list of inodes to delete */ - u32 s_hash_seed[4]; /* HTREE hash seed */ - u8 s_def_hash_version; /* Default hash version to use */ + u8 s_journal_uuid[16]; /* uuid of journal superblock */ + u32 s_journal_inum; /* inode number of journal file */ + u32 s_journal_dev; /* device number of journal file */ + u32 s_last_orphan; /* start of list of inodes to delete */ + u32 s_hash_seed[4]; /* HTREE hash seed */ + u8 s_def_hash_version; /* Default hash version to use */ u8 s_reserved_char_pad; u16 s_reserved_word_pad; u32 s_default_mount_opts; - u32 s_first_meta_bg; /* First metablock block group */ - u32 s_reserved[190];/* Padding to the end of the block */ -} SuperBlock,*pSuperBlock; - -extern SuperBlock ext2_sb; - + u32 s_first_meta_bg; /* First metablock block group */ + u32 s_reserved[190]; /* Padding to the end of the block */ +} ext2_sb_t; typedef struct ext2_group_descriptor { @@ -192,7 +165,7 @@ typedef struct ext2_inode u32 i_dir_acl; u32 i_faddr; u8 i_osd2[12]; -} Inode,*pInode; +} ext2_inode_t; #define EXT2_NAME_LEN 255 @@ -203,7 +176,7 @@ typedef struct ext2_dir_ent u8 name_len; u8 file_type; /* 目录类型 */ char name[EXT2_NAME_LEN]; -} DirEnt, *pDirEnt; +} ext2_dirent_t; /* * Ext2 目录类型. @@ -223,16 +196,11 @@ enum }; -#define EXT2_DIR_PAD 4 -#define EXT2_DIR_ROUND (EXT2_DIR_PAD-1) -#define EXT2_DIR_REC_LEN(name_len) (((name_len)+8+EXT2_DIR_ROUND) & \ - ~EXT2_DIR_ROUND) -#define EXT2_MAX_REC_LEN ((1<<16)-1) - +#define EXT2_DIR_PAD 4 +#define EXT2_DIR_ROUND (EXT2_DIR_PAD-1) +#define EXT2_DIR_REC_LEN(name_len) (((name_len)+8+EXT2_DIR_ROUND) & ~EXT2_DIR_ROUND) +#define EXT2_MAX_REC_LEN ((1<<16)-1) -extern int ext2_read_inode(unsigned int n, pInode inode); -extern int ext2_get_file_inode(const char *path, pInode inode); -extern int ext2_read_file(const pInode ino, void *buf, size_t count); #endif //_EXT2_H diff --git a/include/fs.h b/include/fs.h index b55d307..fb4676c 100644 --- a/include/fs.h +++ b/include/fs.h @@ -15,7 +15,7 @@ #include #include -#include +#include typedef struct partition { diff --git a/include/list.h b/include/list.h index ddd7d51..f3118ce 100644 --- a/include/list.h +++ b/include/list.h @@ -96,4 +96,3 @@ static inline int list_empty(list_head_t *head) { return head->next == head; } - diff --git a/include/printk.h b/include/printk.h index eaa3f13..bd4c2fc 100644 --- a/include/printk.h +++ b/include/printk.h @@ -17,7 +17,8 @@ #pragma once void switch_printk_screen(); -int printk(char *fmtstr, ...); +int printk(const char *fmtstr, ...); +int printl(const char *fmtstr, ...); int printd(unsigned int line, const char *fmtstr, ...); // monitor print line diff --git a/include/string.h b/include/string.h index 33c80c4..393bebf 100644 --- a/include/string.h +++ b/include/string.h @@ -14,18 +14,18 @@ *-------------------------------------------------------------------------- */ -#ifndef _STRING_H +#ifndef _STRING_H #define _STRING_H #include "types.h" -char *strcpy(char *dest, const char *src); -size_t strlen(const char *str); +char *strcpy(char *dest, const char *src); +size_t strlen(const char *str); int strcmp(const char *a, const char *b); int strncmp(const char *a, const char *b, size_t count); -char *strcat(char *dest, const char *src); +char *strcat(char *dest, const char *src); void *memcpy(void *dest, const void *src, size_t size); -void memset(char *dest, char ch, size_t size); +void memset(void *dest, char ch, size_t size); #endif //_STRING_H diff --git a/kernel/clock.c b/kernel/clock.c index cf9ecae..370a159 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -24,6 +24,6 @@ void clk_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) { jiffies++; - printk("^"); + printl("^"); printd(MPL_CLOCK, "clock:%d", jiffies); } diff --git a/kernel/cpuid.c b/kernel/cpuid.c index 13660ff..383cb81 100644 --- a/kernel/cpuid.c +++ b/kernel/cpuid.c @@ -21,10 +21,10 @@ do{\ printk(" %s",fea);\ }while(0); -typedef struct reg{ unsigned long eax,ebx,ecx,edx; }Reg,*pReg; -Reg cpuid(unsigned long op) +typedef struct reg{ unsigned long eax,ebx,ecx,edx; } reg_t; +reg_t cpuid(unsigned long op) { - Reg r; + reg_t r; asm("cpuid;" :"=a"(r.eax), "=b"(r.ebx), @@ -39,15 +39,13 @@ Reg cpuid(unsigned long op) void detect_cpu() { - Reg r; + reg_t r; unsigned short int cpu_sn[6]; //serial number int i; /**********************Get CPU Name********************************/ - char cpu_name[13]; - - //printk("Detecting CPU... "); - + char cpu_name[13]; + r=cpuid(0); memcpy(cpu_name + 0, &r.ebx, 4); memcpy(cpu_name + 4, &r.edx, 4); @@ -56,7 +54,7 @@ void detect_cpu() printk("%s ",cpu_name); /**********************Get Processor Brand String******************/ - char pbs[50]; //processor brand string + char pbs[50]; //processor brand string r = cpuid(0x80000002); memcpy(pbs + 0 , &r.eax, 4); memcpy(pbs + 4 , &r.ebx, 4); @@ -72,13 +70,14 @@ void detect_cpu() memcpy(pbs + 36 , &r.ebx, 4); memcpy(pbs + 40 , &r.ecx, 4); memcpy(pbs + 44 , &r.edx, 4); - printk("Model Name: %s\n",pbs); - printk("%s", pbs); + pbs[48] = 0; + printk("Model Name: %s",pbs); /**********************Get Number of Processors********************/ - int pn;//number of logical processors in one physical processor + int pn;//number of logical processors in one physical processor r=cpuid(1); pn = ((r.ebx & 0x00FF0000) >> 16); + printk(" x %d Cores\n",pn); /**********************Get the CPU's Feature***********************/ int fv = r.edx; @@ -114,12 +113,11 @@ void detect_cpu() //TEST_FEATURE(fv, 30, "Reserved") TEST_FEATURE(fv, 31, "pbe") - printk(" x %d Cores\n",pn); + printk("\n"); if(!((1UL<<11) & fv)) { printk("Your CPU Do Not Support SYSENTER/SYSEXIT\n"); while(1); } - } diff --git a/kernel/printk.c b/kernel/printk.c index 5818ee8..3830e23 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -36,6 +36,15 @@ int printk(const char *fmtstr, ...) return 0; } +char plbuf[1024]; +int printl(const char *fmtstr, ...) +{ + char *args = (char*)(((char*)&fmtstr)+4); + vsprintf(pkbuf, fmtstr, args); + vga_puts(3, pkbuf, 0x4); + return 0; +} + char pdbuf[1024]; int printd(unsigned int line, const char *fmtstr, ...) { diff --git a/kernel/setup.c b/kernel/setup.c index 2e78ea7..a6558a8 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -83,9 +83,9 @@ void setup_kernel() setup_tasks(); setup_irqs(); - switch_printk_screen(); + //switch_printk_screen(); setup_pci(); - switch_printk_screen(); + //switch_printk_screen(); void ide_init(); ide_init(); switch_printk_screen(); diff --git a/lib/string.c b/lib/string.c index 93c292f..82663bf 100644 --- a/lib/string.c +++ b/lib/string.c @@ -68,7 +68,8 @@ void *memcpy(void *dest, const void *src, size_t size) return dest; } -void memset(char *dest, char ch, size_t size) +void memset(void *dest, char ch, size_t size) { - while(size--) *dest++ = ch; + char *d = (char *) dest; + while(size--) *d++ = ch; } diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 8e268e6..d5c057e 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -2,6 +2,7 @@ // vsprintf.c (C) Zhao Yanbai // wed, 30 Jul 2008 14:47 +0800 // Add %012d %012x %12d %12x Support Mon, 20 Jul 2009 19:30:34 +// Add %u Support Sun, 06 Jul 2014 12:07:54 // ======================================================================== #include "string.h" @@ -174,8 +175,7 @@ char *itox(char *s, unsigned int n) char *p = s; char ch; int i; - - if(n==0){*p++='0';*p=0;return s;} + bool flag = false; for(i=28; i>=0; i-=4) { @@ -191,9 +191,16 @@ char *itox(char *s, unsigned int n) ch += 'A'; } - *p++ = ch; + if(ch != '0') + flag = true; + + if(flag || ch != '0') + *p++ = ch; } + if(s == p) + *p++ = '0'; + *p = 0; return s;