Core: make vfs do the work
authorLiu Aleaxander <Aleaxander@gmail.com>
Thu, 11 Jun 2009 07:54:43 +0000 (15:54 +0800)
committerLiu Aleaxander <Aleaxander@gmail.com>
Thu, 11 Jun 2009 07:54:43 +0000 (15:54 +0800)
it works, but it broke somewhere; it can't display the menu correctly.

core/cache.c
core/cache.h
core/diskstart.inc
core/ext2.c
core/extern.inc
core/extlinux.asm
core/fs.c
core/include/fs.h
core/load_config.c [deleted file]

index 4198420..b0fbee7 100644 (file)
  * The cache buffer are pointed to by a cache_head structure.
  */
 
-static struct cache_struct cache_head, cache[MAX_CACHE_ENTRIES];
-static int cache_block_size;
-static int cache_entries;
-
 /**
  * cache_init:
  *
@@ -25,29 +21,30 @@ static int cache_entries;
  * regs->eax.l stores the block size(in bits not bytes)
  *
  */
-void cache_init(com32sys_t * regs)
+void cache_init(struct device *dev, int block_size_shift)
 {
     struct cache_struct *prev, *cur;
-    char *data = core_cache_buf;
-    int block_size_shift = regs->eax.l;
+    char *data = dev->cache_data;
+    static __lowmem struct cache_struct cache_head, cache[MAX_CACHE_ENTRIES];
     int i;
+
+    dev->cache_head = &cache_head;
+    dev->cache_block_size = 1 << block_size_shift;
+    dev->cache_entries = dev->cache_size >> block_size_shift;
+    if (dev->cache_entries > MAX_CACHE_ENTRIES)
+        dev->cache_entries = MAX_CACHE_ENTRIES;
     
-    cache_block_size = 1 << block_size_shift;
-    cache_entries = sizeof(core_cache_buf) >> block_size_shift;
-    if (cache_entries > MAX_CACHE_ENTRIES)
-        cache_entries = MAX_CACHE_ENTRIES;
-    
-    cache_head.prev = &cache[cache_entries-1];
+    cache_head.prev = &cache[dev->cache_entries-1];
     cache_head.prev->next = &cache_head;
     prev = &cache_head;
     
-    for (i = 0; i < cache_entries; i++) {
+    for (i = 0; i < dev->cache_entries; i++) {
         cur = &cache[i];
         cur->block = 0;
         cur->prev  = prev;
         prev->next = cur;
         cur->data  = data;
-        data += cache_block_size;
+        data += dev->cache_block_size;
         prev = cur++;
     }
 }
@@ -74,10 +71,10 @@ void cache_init(com32sys_t * regs)
  * @return: the data stores at gs:si
  *
  */
-struct cache_struct* get_cache_block(block_t block)
+struct cache_struct* get_cache_block(struct device *dev, block_t block)
 {
     /* let's find it from the end, 'cause the endest is the freshest */
-    struct cache_struct *cs = cache_head.prev;
+    struct cache_struct *cs = dev->cache_head->prev;
     struct cache_struct *head,  *last;
     int i;
 
@@ -97,7 +94,7 @@ struct cache_struct* get_cache_block(block_t block)
     if (cs->block == block) 
         goto out;
     
-    for (i = 0; i < cache_entries; i ++) {
+    for (i = 0; i < dev->cache_entries; i ++) {
         if (cs->block == block)
             break;
         else
@@ -105,11 +102,11 @@ struct cache_struct* get_cache_block(block_t block)
     }
     
     /* missed, so we need to load it */
-    if (i == cache_entries) {        
+    if (i == dev->cache_entries) {        
         /* store it at the head of real cache */
-        cs = cache_head.next;        
+        cs = dev->cache_head->next;        
         cs->block = block;
-        getoneblk(cs->data, block, cache_block_size);
+        getoneblk(cs->data, block, dev->cache_block_size);
 
         missed ++;
     } 
@@ -119,8 +116,8 @@ struct cache_struct* get_cache_block(block_t block)
     cs->next->prev = cs->prev;    
     
     /* add to just before head node */
-    last = cache_head.prev;
-    head = &cache_head;
+    last = dev->cache_head->prev;
+    head = dev->cache_head;
     
     last->next = cs;
     cs->prev = last;
@@ -128,15 +125,34 @@ struct cache_struct* get_cache_block(block_t block)
     cs->next = head;    
     
  out:
-#if 0 /* testing how efficiency the cache is */
     total_read ++;
+#if 0 /* testing how efficiency the cache is */
     if (total_read % 5 == 0) 
         printf("total_read %d\tmissed %d\n", total_read, missed);
 #endif
 
     /* in fact, that would never be happened */
     if ((char *)(cs->data) > (char*)0x100000)
-        printf("the buffer addres higher than 1M limit\n\r");
+        printf("the buffer addres higher than 1M limit\n");
     
     return cs;
 }    
+
+
+/**
+ * Just print the sector, and according the LRU algorithm, 
+ * Left most value is the most least secotr, and Right most 
+ * value is the most Recent sector. I see it's a Left Right Used
+ * (LRU) algorithm; Just kidding:)
+ */
+void print_cache(struct device *dev)
+{
+        int i = 0;
+        struct cache_struct *cs = dev->cache_head;
+        for (; i < dev->cache_entries; i++) {
+                cs = cs->next;
+                printf("%d(%p) ", cs->block, cs->data);
+        }
+
+        printf("\n");
+}
index 65df6cd..7518bc8 100644 (file)
@@ -4,8 +4,9 @@
 #include <stdint.h>
 #include <com32.h>
 #include "disk.h"
+#include "fs.h"
 
-#define MAX_CACHE_ENTRIES  0x064 /* I'm not sure it's the max */
+#define MAX_CACHE_ENTRIES  0x10 /* I find even this is enough:) */
 
 /* The cache structure */
 struct cache_struct {
@@ -17,8 +18,8 @@ struct cache_struct {
 
 
 /* functions defined in cache.c */
-void cache_init(com32sys_t *regs);
-
-struct cache_struct* get_cache_block(block_t);
+void cache_init(struct device *, int);
+struct cache_struct* get_cache_block(struct device *, block_t);
+void print_cache(struct device *);
 
 #endif /* cache.h */
index 38222e0..a08aa28 100644 (file)
@@ -706,6 +706,30 @@ expand_super:
                stosd                           ; Store expanded byte
                loop .loop
 
+
 ;
-; Fall through to the mainline code...
-;
+; Common initialization code
+;
+%include "init.inc"
+%include "cpuinit.inc"
+
+
+%if IS_PXELINUX
+             extern pxe_fs_ops
+             mov eax,pxe_fs_ops
+%else
+ %if IS_EXTLINUX
+             extern ext2_fs_ops
+             mov eax,ext2_fs_ops
+ %elif IS_SYSLINUX
+             extern vfat_fs_ops
+             mov eax,vfat_fs_ops
+ %elif IS_ISOLINUX
+             extern iso_fs_ops
+             mov eax,iso_fs_ops
+ %endif
+             mov dl,[DriveNumber]
+             mov ecx,[bsHidden]
+             mov ebx,[bsHidden+4]
+%endif
+              pm_call fs_init
index 7980930..b89541c 100644 (file)
@@ -4,6 +4,7 @@
 #include "core.h"
 #include "disk.h"
 #include "ext2_fs.h"
+#include "fs.h"
 
 #define FILENAME_MAX_LG2 8
 #define FILENAME_MAX     (1 << FILENAME_MAX_LG2)
@@ -106,10 +107,8 @@ void close_file(struct open_file_t *file)
  * any whitespace.
  *
  */
-void mangle_name(com32sys_t *regs)
+void ext2_mangle_name(char *dst, char *src)
 {
-    char *src = (char *)MK_PTR(regs->ds, regs->esi.w[0]);
-    char *dst = (char *)MK_PTR(regs->es, regs->edi.w[0]);
     char *p = dst;
     int i = FILENAME_MAX -1;
     
@@ -150,7 +149,7 @@ void mangle_name(com32sys_t *regs)
  * @return: the pointer of the group's descriptor
  *
  */ 
-struct ext2_group_desc *get_group_desc(uint32_t group_num)
+struct ext2_group_desc *get_group_desc(struct fs_info *fs, uint32_t group_num)
 {
     block_t block_num;
     uint32_t offset;
@@ -161,7 +160,7 @@ struct ext2_group_desc *get_group_desc(uint32_t group_num)
     offset = group_num % DescPerBlock;
 
     block_num += sb->s_first_data_block + 1;
-    cs = get_cache_block(block_num);
+    cs = get_cache_block(fs->fs_dev, block_num);
 
     desc = (struct ext2_group_desc *)cs->data + offset;
 
@@ -181,7 +180,7 @@ struct ext2_group_desc *get_group_desc(uint32_t group_num)
  * @param: offset, same as block
  *
  */
-void read_inode(uint32_t inode_offset, 
+void read_inode(struct fs_info *fs, uint32_t inode_offset, 
                 struct ext2_inode *dst, struct ext2_group_desc *desc,
                 block_t *block, uint32_t *offset)
 {
@@ -191,7 +190,7 @@ void read_inode(uint32_t inode_offset,
     *block  = inode_offset / InodePerBlock + desc->bg_inode_table;
     *offset = inode_offset % InodePerBlock;
     
-    cs = get_cache_block(*block);
+    cs = get_cache_block(fs->fs_dev, *block);
     
     /* well, in EXT4, the inode structure usually be 256 */
     inode = (struct ext2_inode *)(cs->data + (*offset * (sb->s_inode_size)));
@@ -213,7 +212,7 @@ void read_inode(uint32_t inode_offset,
  *          the first 128 bytes of the inode, stores in ThisInode
  *
  */
-struct open_file_t * open_inode(uint32_t inr, uint32_t *file_len)
+struct open_file_t * open_inode(struct fs_info *fs, uint32_t inr, uint32_t *file_len)
 {
     struct open_file_t *file;
     struct ext2_group_desc *desc;
@@ -232,10 +231,10 @@ struct open_file_t * open_inode(uint32_t inr, uint32_t *file_len)
     inode_group  = inr / sb->s_inodes_per_group;
     
     /* get the group desc */
-    desc = get_group_desc(inode_group);
+    desc = get_group_desc(fs, inode_group);
     
     inode_offset = inr % sb->s_inodes_per_group;
-    read_inode(inode_offset, this_inode, desc, &block_num, &block_off);
+    read_inode(fs, inode_offset, this_inode, desc, &block_num, &block_off);
     
     /* Finally, we need to convet it to sector for now */
     file->file_in_sec = (block_num<<ClustShift) + (block_off>>SECTOR_SHIFT);
@@ -252,7 +251,7 @@ struct open_file_t * open_inode(uint32_t inr, uint32_t *file_len)
 
 
 struct ext4_extent_header * 
-ext4_find_leaf (struct ext4_extent_header *eh, block_t block)
+ext4_find_leaf (struct fs_info *fs, struct ext4_extent_header *eh, block_t block)
 {
     struct ext4_extent_idx *index;
     struct cache_struct *cs;
@@ -279,20 +278,20 @@ ext4_find_leaf (struct ext4_extent_header *eh, block_t block)
         blk = (blk << 32) + index[i].ei_leaf_lo;
         
         /* read the blk to memeory */
-        cs = get_cache_block(blk);
+        cs = get_cache_block(fs->fs_dev, blk);
         eh = (struct ext4_extent_header *)(cs->data);
     }
 }
 
 /* handle the ext4 extents to get the phsical block number */
-uint64_t linsector_extent(block_t block, struct ext2_inode *inode)
+uint64_t linsector_extent(struct fs_info *fs, block_t block, struct ext2_inode *inode)
 {
     struct ext4_extent_header *leaf;
     struct ext4_extent *ext;
     int i;
     uint64_t start;
     
-    leaf = ext4_find_leaf((struct ext4_extent_header*)inode->i_block,block);
+    leaf = ext4_find_leaf(fs, (struct ext4_extent_header*)inode->i_block, block);
     if (! leaf) {
         printf("ERROR, extent leaf not found\n");
         return 0;
@@ -329,7 +328,7 @@ uint64_t linsector_extent(block_t block, struct ext2_inode *inode)
  *
  * @return: the physic block number
  */
-block_t linsector_direct(block_t block, struct ext2_inode *inode)
+block_t linsector_direct(struct fs_info *fs, block_t block, struct ext2_inode *inode)
 {
     struct cache_struct *cs;
     
@@ -342,7 +341,7 @@ block_t linsector_direct(block_t block, struct ext2_inode *inode)
     block -= EXT2_NDIR_BLOCKS;
     if (block < PtrsPerBlock1) {
         block_t ind_block = inode->i_block[EXT2_IND_BLOCK];
-        cs = get_cache_block(ind_block);
+        cs = get_cache_block(fs->fs_dev, ind_block);
         
         return ((block_t *)cs->data)[block];
     }
@@ -351,10 +350,10 @@ block_t linsector_direct(block_t block, struct ext2_inode *inode)
     block -= PtrsPerBlock1;
     if (block < PtrsPerBlock2) {
         block_t dou_block = inode->i_block[EXT2_DIND_BLOCK];
-        cs = get_cache_block(dou_block);
+        cs = get_cache_block(fs->fs_dev, dou_block);
         
         dou_block = ((block_t *)cs->data)[block / PtrsPerBlock1];
-        cs = get_cache_block(dou_block);
+        cs = get_cache_block(fs->fs_dev, dou_block);
         
         return ((block_t*)cs->data)[block % PtrsPerBlock1];
     }
@@ -363,13 +362,13 @@ block_t linsector_direct(block_t block, struct ext2_inode *inode)
     block -= PtrsPerBlock2;
     if (block < PtrsPerBlock3) {
         block_t tri_block = inode->i_block[EXT2_TIND_BLOCK];
-        cs = get_cache_block(tri_block);
+        cs = get_cache_block(fs->fs_dev, tri_block);
         
         tri_block = ((block_t *)cs->data)[block / PtrsPerBlock2];
-        cs = get_cache_block(tri_block);
+        cs = get_cache_block(fs->fs_dev, tri_block);
         
         tri_block = ((block_t *)cs->data)[block % PtrsPerBlock2];
-        cs = get_cache_block(tri_block);
+        cs = get_cache_block(fs->fs_dev, tri_block);
 
         return ((uint32_t*)cs->data)[block % PtrsPerBlock1];
     }
@@ -392,7 +391,7 @@ block_t linsector_direct(block_t block, struct ext2_inode *inode)
  * 
  * @return: physic sector number
  */
-sector_t linsector(sector_t lin_sector)
+sector_t linsector(struct fs_info *fs, sector_t lin_sector)
 {
     block_t block = lin_sector >> ClustShift;
     struct ext2_inode *inode;
@@ -401,9 +400,9 @@ sector_t linsector(sector_t lin_sector)
     inode = this_inode;
 
     if (inode->i_flags & EXT4_EXTENTS_FLAG)
-        block = linsector_extent(block, inode);
+        block = linsector_extent(fs, block, inode);
     else
-        block = (uint32_t)linsector_direct(block, inode);
+        block = (uint32_t)linsector_direct(fs, block, inode);
     
     if (!block) {
         printf("ERROR: something error happend at linsector..\n");
@@ -480,17 +479,13 @@ void getlinsec_ext(char *buf, sector_t sector, int sector_cnt)
  * @return: ECX(of regs), number of bytes read
  *
  */
-void getfssec(com32sys_t *regs)
+uint32_t ext2_getfssec(struct fs_info *fs, char *buf, 
+                       void *open_file, int sectors, int *have_more)
 {
     int sector_left, next_sector, sector_idx;
     int frag_start, con_sec_cnt;
-    int sectors = regs->ecx.w[0];
     int bytes_read = sectors << SECTOR_SHIFT;
-    char *buf;
-    struct open_file_t *file;
-
-    buf = (char *)MK_PTR(regs->es, regs->ebx.w[0]);
-    file = (struct open_file_t *)MK_PTR(regs->ds, regs->esi.w[0]); 
+    struct open_file_t *file = (struct open_file_t *)open_file;
     
     sector_left = (file->file_bytesleft + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
     if (sectors > sector_left)
@@ -501,7 +496,7 @@ void getfssec(com32sys_t *regs)
          * get the frament
          */
         sector_idx  = file->file_sector;
-        next_sector = frag_start = linsector(sector_idx);
+        next_sector = frag_start = linsector(fs, sector_idx);
         con_sec_cnt = 0;                
         
         /* get the consective sectors count */
@@ -517,7 +512,7 @@ void getfssec(com32sys_t *regs)
             
             sector_idx ++;
             next_sector ++;
-        }while(next_sector == linsector(sectors));                
+        }while(next_sector == linsector(fs, sectors));                
         
 #if 0   
         printf("You are reading stores at sector --0x%x--0x%x\n", 
@@ -528,49 +523,17 @@ void getfssec(com32sys_t *regs)
         file->file_sector += con_sec_cnt;  /* next sector index */
     }while(sectors);
     
-    if (bytes_read >= file->file_bytesleft) {
+    if (bytes_read >= file->file_bytesleft) { 
         bytes_read = file->file_bytesleft;
-        regs->esi.w[0] = 0;  /* do close the file for asm function*/
-    }
+        *have_more = 0;
+    } else
+        *have_more = 1;    
     file->file_bytesleft -= bytes_read;
-    
-    regs->ecx.l = bytes_read;
-}
-
 
-
-/* This is the gefssec function that should be called from C function */
-void getfssec_ext(char *buf, struct open_file_t *file, 
-                  int sectors, int *have_more)
-{
-    com32sys_t regs;
-
-    memset(&regs, 0, sizeof regs);
-    
-    /*
-     * for now, even though the buf and file structure are stored
-     * at low address, BUT find: 
-     *
-     * we can't use SEG stuff here, say the address of buf
-     * is 0x800(found in debug), the address would be broken like
-     * this: es = 0x80, bx = 0, while that's not the getfssec 
-     * function need.
-     *
-     * so we just do like:
-     *                   regs.ebx.w[0] = buf;
-     */
-    regs.ebx.w[0] = OFFS_WRT(buf, 0);
-    regs.esi.w[0] = OFFS_WRT(file, 0);
-    regs.ecx.w[0] = sectors;
-    getfssec(&regs);
-
-    *have_more = 1;
-    
-    /* the file is closed ? */
-    if(!file->file_bytesleft)
-        *have_more = 0;
+    return bytes_read;
 }
-    
+
+   
 
 /**
  * find_dir_entry:
@@ -578,21 +541,21 @@ void getfssec_ext(char *buf, struct open_file_t *file,
  * find a dir entry, if find return it or return NULL
  *
  */
-struct ext2_dir_entry* find_dir_entry(struct open_file_t *file, char *filename)
+struct ext2_dir_entry* find_dir_entry(struct fs_info *fs, struct open_file_t *file,char *filename)
 {
     int   have_more;
     char *EndBlock = trackbuf + (SecPerClust << SECTOR_SHIFT);;
     struct ext2_dir_entry *de;
     
     /* read a clust at a time */
-    getfssec_ext(trackbuf, file, SecPerClust, &have_more);        
+    ext2_getfssec(fs, trackbuf, file, SecPerClust, &have_more);        
     de = (struct ext2_dir_entry *)trackbuf;        
     
     while (1) {
         if ((char *)de >= (char *)EndBlock) {
             if (!have_more) 
                 return NULL;
-            getfssec_ext(trackbuf, file,SecPerClust,&have_more);
+            ext2_getfssec(fs, trackbuf, file,SecPerClust,&have_more);
             de = (struct ext2_dir_entry *)trackbuf;
         }
         
@@ -616,7 +579,8 @@ struct ext2_dir_entry* find_dir_entry(struct open_file_t *file, char *filename)
 }
 
 
-char* do_symlink(struct open_file_t *file, uint32_t file_len, char *filename)
+char* do_symlink(struct fs_info *fs, struct open_file_t *file, 
+                 uint32_t file_len, char *filename)
 {
     int  flag, have_more;
     
@@ -633,7 +597,7 @@ char* do_symlink(struct open_file_t *file, uint32_t file_len, char *filename)
         
     } else {                           
         /* slow symlink */
-        getfssec_ext(SymlinkTmpBuf,file,SYMLINK_SECTORS,&have_more);
+        ext2_getfssec(fs, SymlinkTmpBuf,file,SYMLINK_SECTORS,&have_more);
         lnk_end = SymlinkTmpBuf + file_len;
     }
     
@@ -668,29 +632,28 @@ char* do_symlink(struct open_file_t *file, uint32_t file_len, char *filename)
  * @out  : file lenght in bytes, stores in eax
  *
  */
-void searchdir(com32sys_t * regs)
+void ext2_searchdir(char *filename, struct file *file)
 {
     extern int CurrentDir;
     
-    struct open_file_t *file;
+    struct open_file_t *open_file;
     struct ext2_dir_entry *de;
     uint8_t  file_mode;
     uint8_t  SymlinkCtr = MAX_SYMLINKS;        
     uint32_t inr = CurrentDir;
     uint32_t ThisDir = CurrentDir;
     uint32_t file_len;
-    char *filename = (char *)MK_PTR(regs->ds, regs->edi.w[0]);
-    
+        
  begin_path:
     while (*filename == '/') { /* Absolute filename */
         inr = EXT2_ROOT_INO;
         filename ++;
     }
  open:
-    if ((file = open_inode(inr, &file_len)) == NULL)
+    if ((open_file = open_inode(file->fs, inr, &file_len)) == NULL)
         goto err_noclose;
         
-    file_mode = file->file_mode >> S_IFSHIFT;
+    file_mode = open_file->file_mode >> S_IFSHIFT;
     
     /* It's a file */
     if (file_mode == T_IFREG) {
@@ -710,13 +673,13 @@ void searchdir(com32sys_t * regs)
         while (*filename == '/')
             filename ++;
         
-        de = find_dir_entry(file, filename);
+        de = find_dir_entry(file->fs, open_file, filename);
         if (!de) 
             goto err;
         
         inr = de->d_inode;
         filename += de->d_name_len;
-        close_file(file);
+        close_file(open_file);
         goto open;
     }    
     
@@ -732,7 +695,7 @@ void searchdir(com32sys_t * regs)
         if (--SymlinkCtr==0 || file_len>=SYMLINK_SECTORS*SECTOR_SIZE)
             goto err;    /* too many links or symlink too long */
         
-        filename = do_symlink(file, file_len, filename);
+        filename = do_symlink(file->fs, open_file, file_len, filename);
         if (!filename)    
             goto err_noclose;/* buffer overflow */
         
@@ -742,22 +705,52 @@ void searchdir(com32sys_t * regs)
     
     /* Otherwise, something bad ... */
  err:
-    close_file(file);
+    close_file(open_file);
  err_noclose:
     file_len = 0;
-    file = NULL;
-    regs->eflags.l |= EFLAGS_ZF;
+    open_file = NULL;
  done:        
     
-    regs->eax.l = file_len;
-    regs->esi.w[0] = OFFS_WRT(file, 0);
+    file->file_len = file_len;
+    file->open_file = (void*)open_file;
+
+#if 1
+    if (open_file) {
+        printf("file bytesleft: %d\n", open_file->file_bytesleft);
+        printf("file sector   : %d\n", open_file->file_sector);
+        printf("file in sector: %d\n", open_file->file_in_sec);
+        printf("file offsector: %d\n", open_file->file_in_off);
+    }
+#endif
+
+}
+
+void ext2_load_config(com32sys_t *regs)
+{
+    char *config_name = "extlinux.conf";
+    com32sys_t out_regs;
+    
+    strcpy(ConfigName, config_name);
+    *(uint32_t *)CurrentDirName = 0x00002f2e;  
+
+    regs->edi.w[0] = ConfigName;
+    memset(&out_regs, 0, sizeof out_regs);
+    call16(core_open, regs, &out_regs);
+
+    regs->eax.w[0] = out_regs.eax.w[0];
+
+#if 0
+    printf("the zero flag is %s\n", regs->eax.w[0] ?          \
+           "CLEAR, means we found the config file" :
+           "SET, menas we didn't find the config file");
+#endif
 }
 
 
 /**
- * init. the fs meta data, return the block size in eax
+ * init. the fs meta data, return the block size bits.
  */
-void init_fs(com32sys_t *regs)
+int ext2_fs_init(void)
 {
     extern char SuperBlock[1024];
     
@@ -779,5 +772,15 @@ void init_fs(com32sys_t *regs)
     PtrsPerBlock2 = 1 << ((ClustByteShift - 2) * 2);
     PtrsPerBlock3 = 1 << ((ClustByteShift - 2) * 3);
     
-    regs->eax.l = ClustByteShift;
+    return ClustByteShift;
 }
+
+const struct fs_ops ext2_fs_ops = {
+    .fs_name       = "ext2",
+    .fs_init       = ext2_fs_init,
+    .searchdir     = ext2_searchdir,
+    .getfssec      = ext2_getfssec,
+    .mangle_name   = ext2_mangle_name,
+    .unmangle_name = NULL,
+    .load_config   = ext2_load_config
+};
index 086f1dd..fdbe264 100644 (file)
        ; hello.c
        extern hello
 
-       ; cache.c
-       extern cache_init
-
-       ; load_config.c
-       extern load_config
-
-       ; ext2.c
-       extern init_fs, searchdir, getfssec, mangle_name
+       ; fs.c
+       extern fs_init, searchdir, getfssec, mangle_name, load_config
 
 %endif ; EXTERN_INC
index 741566c..be256cf 100644 (file)
@@ -113,21 +113,6 @@ Files              resb MAX_OPEN*open_file_t_size
 ;
 %include "diskstart.inc"
 
-;
-; Common initialization code
-;
-%include "init.inc"
-%include "cpuinit.inc"
-
-;
-; Initialize the ext2 fs meta data
-;
-               pm_call init_fs         ; will return the block size shift in eax(for now, is the sector shift)
-
-;
-; Initialize the metadata cache
-;
-               pm_call cache_init
 
 ;
 ; Now, everything is "up and running"... patch kaboom for more
index f094690..18f0337 100644 (file)
--- a/core/fs.c
+++ b/core/fs.c
@@ -4,7 +4,7 @@
 #include "cache.h"
 
 
-/* The this pointer */
+/* The this fs pointer */
 struct fs_info *this_fs;
 struct fs_info fs;
 struct device dev;
@@ -43,7 +43,7 @@ void getfssec(com32sys_t *regs)
     file.open_file = MK_PTR(regs->ds, regs->esi.w[0]); 
     file.fs = this_fs;
 
-    bytes_read = this_fs->fs_ops->getfssec(buf, file.open_file, sectors, &have_more);
+    bytes_read = this_fs->fs_ops->getfssec(file.fs, buf, file.open_file, sectors, &have_more);
     
     /* if we reach the EOF, set the si to be NULL */
     if (!have_more)
@@ -58,33 +58,68 @@ void searchdir(com32sys_t *regs)
     char *filename = (char *)MK_PTR(regs->ds, regs->edi.w[0]);
     struct file file;
     
+    printf("filename: %s\n", filename);
+
     memset(&file, 0, sizeof file);
     file.fs = this_fs;
     
     this_fs->fs_ops->searchdir(filename, &file);
     regs->esi.w[0] = OFFS_WRT(file.open_file, 0);
     regs->eax.l = file.file_len;
+    if (!file.file_len)
+        regs->eflags.l |= EFLAGS_ZF;
+}
+
+/*
+ * well, I find that in the diskstart.inc, there's no room fow us to
+ * get the edd check result, so we implement a new one here.
+ */
+uint8_t detect_edd(uint8_t device_num)
+{
+    com32sys_t iregs, oregs;
+    
+    /* Sending int 13h func 41h to query EBIOS information */
+    memset(&iregs, 0, sizeof iregs);
+    memset(&oregs, 0, sizeof oregs);
+    
+    /* Get EBIOS support */
+    iregs.eax.w[0] = 0x4100;
+    iregs.ebx.w[0] = 0x55aa;
+    iregs.edx.b[0] = device_num;
+    iregs.eflags.b[0] = 0x3; /* CF set */
+    
+    __intcall(0x13, &iregs, &oregs);
+    
+    /* Detecting EDD support */
+    if (!(oregs.eflags.l & EFLAGS_CF) &&
+        oregs.ebx.w[0] == 0xaa55 && (oregs.ecx.b[0] & 1))
+        return 1;
+    else
+        return 0;
 }
 
 /* 
  * initialize the device structure 
  */
-void device_init(struct device *dev, uint8_t drive_num, 
-                 uint8_t type, sector_t offset)
+void device_init(struct device *dev, uint8_t device_num, sector_t offset)
 {
-    dev->device_number = drive_num;
+    dev->device_number = device_num;
     dev->part_start = offset;
-    dev->type = type;
-    
+
+    dev->type = detect_edd(device_num);
+        
     /* 
      * check if we use cache or not, for now I just know ISO fs 
      * does not use the cache, and I hope the USE_CACHE can detect
      * it correctly.
      *
-     */
+     */    
     if ( USE_CACHE(dev->device_number) ) {
-        static __lowmem char cache_buf[65536];
-        dev->cache_data = cache_buf;
+        /* I can't use __lowmem here, 'cause it will cause the error:
+           "auxseg/lowmem region collides with xfer_buf_seg" */
+        //static __lowmem char cache_buf[65536];
+        dev->cache_data = core_cache_buf;
+        dev->cache_size = sizeof core_cache_buf;
     } else 
         dev->cache_data = NULL;
 
@@ -93,6 +128,17 @@ void device_init(struct device *dev, uint8_t drive_num,
 }
 
 
+/* debug function */
+void dump_dev(struct device *dev)
+{
+    printf("device type:%s\n", dev->type ? "CHS" : "EDD");
+    printf("cache_data: %p\n", dev->cache_data);
+    printf("cache_head: %p\n", dev->cache_head);
+    printf("cache_block_size: %d\n", dev->cache_block_size);
+    printf("cache_entries: %d\n", dev->cache_entries);
+    printf("cache_size: %d\n", dev->cache_size);
+}
+
 /*
  * it will do:
  *    initialize the device structure;
@@ -106,7 +152,7 @@ void fs_init(com32sys_t *regs)
     int blk_shift;
     struct fs_ops *ops = (struct fs_ops*)regs->eax.l;
     
-    device_init(&dev, regs->edx.b[0], regs->edx.b[1], regs->ecx.l);
+    device_init(&dev, regs->edx.b[0], regs->ecx.l);
     
     /* set up the fs stucture */    
     fs.fs_name = ops->fs_name;
@@ -115,9 +161,9 @@ void fs_init(com32sys_t *regs)
     this_fs = &fs;
 
     /* invoke the fs-specific init code */
-    blk_shift = fs.fs_ops->fs_init();
-    
+    blk_shift = fs.fs_ops->fs_init();    
+
     /* initialize the cache */
     if (dev.cache_data)
-        cache_init(&dev, blk_shift);     
+        cache_init(&dev, blk_shift);
 }
index 6805b3b..0cb1bfc 100644 (file)
@@ -5,7 +5,8 @@
 #include "core.h"
 #include "disk.h"
 
-#define USE_CACHE(device_num) (device_num > 0x00 && device_num < 0xfe)
+/* I don't know it's right or not */
+#define USE_CACHE(device_num) (device_num >= 0x00 && device_num < 0xfe)
 
 
 struct fs_info {
@@ -27,13 +28,13 @@ struct fs_ops {
     
     int      (*fs_init)(void);
     void     (*searchdir)(char *, struct file *);
-    uint32_t (*getfssec)(char *, void * , int, int *);
+    uint32_t (*getfssec)(struct fs_info *, char *, void * , int, int *);
     void     (*mangle_name)(char *, char *);
     void     (*unmangle_name)(void);
     void     (*load_config)(com32sys_t *);
 };
 
-//enum dev_type {CHS, EDD};
+enum dev_type {CHS, EDD};
 
 /*
  * Struct device should have all the information about a specific disk
@@ -65,10 +66,14 @@ struct device {
 
     /* 
      * I think we still need the cache_data filed here, 'cause hpa said 
-     * different device has diffrent cache buffer 
+     * different device has diffrent cache buffer, and the following filed
+     * are quite for cache parts. 
      */
-    void *cache_data;
-    struct cache_struct *cache_head;
+    char*    cache_data;
+    struct  cache_struct *cache_head;
+    uint16_t cache_block_size;
+    uint16_t cache_entries;
+    uint32_t cache_size;
 };
 
 
diff --git a/core/load_config.c b/core/load_config.c
deleted file mode 100644 (file)
index 2c81946..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-
-#include "core.h"
-
-
-void load_config(com32sys_t *regs)
-{
-    char *config_name = "extlinux.conf";
-    com32sys_t out_regs;
-    
-    strcpy(ConfigName, config_name);
-    *(uint32_t *)CurrentDirName = 0x00002f2e;  
-
-    regs->edi.w[0] = ConfigName;
-    memset(&out_regs, 0, sizeof out_regs);
-    call16(core_open, regs, &out_regs);
-
-    regs->eax.w[0] = out_regs.eax.w[0];
-
-#if 0
-    printf("the zero flag is %s\n", regs->eax.w[0] ?          \
-           "CLEAR, means we found the config file" :
-           "SET, menas we didn't find the config file");
-#endif
-}