#include <pci.h>
#include <system.h>
#include <semaphore.h>
+#include <wait.h>
+#include <string.h>
+
+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;
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();
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));
ide_cmd_out(0, nsect, sect_nr, HD_CMD_READ_EXT);
}
-DECLARE_MUTEX(mutex);
void init_pci_controller(unsigned int classcode)
{
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)
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);
}
}
}
-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)
{
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,
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * File Name: ext2.c
+ *
+ * Author: Zhao Yanbai [zhaoyanbai@126.com]
+ * Sun Feb 14 15:52:01 2010
+ *
+ * Description: none
+ *
+ *--------------------------------------------------------------------------
+ */
+
+#include <fs.h>
+#include <system.h>
+#include <string.h>
+#include <stat.h>
+
+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; i<filesz; i++)
+ printk("%c", buf[i]);
+#endif
+#if 0
+ unsigned char *p = (char *)kmalloc_old(EXT2_BLOCK_SIZE);
+ ext2_read_block(0, p);
+
+ for(i=0; i<512; i++)
+ printk("%02x ", p[i]);
+#endif
+#if 0
+ int dly = 0xF000000;
+ while(dly--);
+#endif
+}
+
+void ext2_read_block(int block_id, char *buf)
+{
+ u64 sect = EXT2_SECT;
+ sect += block_id*EXT2_SECT_PER_BLOCK;
+
+ //printk("block id: %d sect:%d\n", block_id, sect);
+
+ hd_read(ROOT_DEV, sect, buf, EXT2_BLOCK_SIZE);
+}
+
+
+/*
+ * 写这版ext2_read_inode的时候我想起了2008.12.16在0.2.1中写的
+ * 那个 GetInode. 这两个函数完成的是同样的功能.但是很明显
+ * 之前的那个版本写得那是相当的滑稽幼稚.甚至还有大大的BUG.
+ * 但是正是这些点滴见证着我的内核的成长.
+ */
+int ext2_read_inode(unsigned int n, pInode ino)
+{
+ assert(1<=n && n <= EXT2_INODES_COUNT);
+ if(n == EXT2_BAD_INO) return 0;
+
+ unsigned int gnr; /* inode 所在的group的号 */
+ unsigned int gidx; /* inode 所在的group的偏移 */
+ unsigned int inotbl; /* inode table 的 block id */
+
+
+ gnr = (n-1) / EXT2_INODES_PER_GROUP;
+ gidx = (n-1) % EXT2_INODES_PER_GROUP;
+
+ inotbl = (gdesc+gnr)->bg_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; i<blks; i++)
+ {
+ ext2_read_block(ino->i_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; i<blks; i++)
+ {
+ ext2_read_block(ino->i_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);
+}
/*
- *--------------------------------------------------------------------------
+ * ------------------------------------------------------------------------
* 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 <fs.h>
-#include <system.h>
-#include <string.h>
-#include <stat.h>
-
-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; i<filesz; i++)
- printk("%c", buf[i]);
-#endif
-#if 0
- unsigned char *p = (char *)kmalloc_old(EXT2_BLOCK_SIZE);
- ext2_read_block(0, p);
-
- for(i=0; i<512; i++)
- printk("%02x ", p[i]);
-#endif
-#if 0
- int dly = 0xF000000;
- while(dly--);
-#endif
-}
-
-void ext2_read_block(int block_id, char *buf)
-{
- u64 sect = EXT2_SECT;
- sect += block_id*EXT2_SECT_PER_BLOCK;
-
- //printk("block id: %d sect:%d\n", block_id, sect);
-
- hd_read(ROOT_DEV, sect, buf, EXT2_BLOCK_SIZE);
-}
-
-
-/*
- * 写这版ext2_read_inode的时候我想起了2008.12.16在0.2.1中写的
- * 那个 GetInode. 这两个函数完成的是同样的功能.但是很明显
- * 之前的那个版本写得那是相当的滑稽幼稚.甚至还有大大的BUG.
- * 但是正是这些点滴见证着我的内核的成长.
- */
-int ext2_read_inode(unsigned int n, pInode ino)
-{
- assert(1<=n && n <= EXT2_INODES_COUNT);
- if(n == EXT2_BAD_INO) return 0;
-
- unsigned int gnr; /* inode 所在的group的号 */
- unsigned int gidx; /* inode 所在的group的偏移 */
- unsigned int inotbl; /* inode table 的 block id */
-
-
- gnr = (n-1) / EXT2_INODES_PER_GROUP;
- gidx = (n-1) % EXT2_INODES_PER_GROUP;
-
- inotbl = (gdesc+gnr)->bg_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; i<blks; i++)
- {
- ext2_read_block(ino->i_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; i<blks; i++)
- {
- ext2_read_block(ino->i_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"
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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 <types.h>
+
+#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
*--------------------------------------------------------------------------
*/
-#ifndef _EXT2_H
+#ifndef _EXT2_H
#define _EXT2_H
#include <types.h>
-#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)
*/
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.
*
* 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
/*
* 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
{
u32 i_dir_acl;
u32 i_faddr;
u8 i_osd2[12];
-} Inode,*pInode;
+} ext2_inode_t;
#define EXT2_NAME_LEN 255
u8 name_len;
u8 file_type; /* 目录类型 */
char name[EXT2_NAME_LEN];
-} DirEnt, *pDirEnt;
+} ext2_dirent_t;
/*
* Ext2 目录类型.
};
-#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
#include <types.h>
#include <page.h>
-#include <ext2.h>
+#include <bak.ext2.h>
typedef struct partition
{
{
return head->next == head;
}
-
#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
*--------------------------------------------------------------------------
*/
-#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
{
jiffies++;
- printk("^");
+ printl("^");
printd(MPL_CLOCK, "clock:%d", jiffies);
}
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),
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);
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);
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;
//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);
}
-
}
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, ...)
{
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();
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;
}
// 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"
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)
{
ch += 'A';
}
- *p++ = ch;
+ if(ch != '0')
+ flag = true;
+
+ if(flag || ch != '0')
+ *p++ = ch;
}
+ if(s == p)
+ *p++ = '0';
+
*p = 0;
return s;