Successed in converting the cache code to C
authorLiu Aleaxander <Aleaxander@gmail.com>
Tue, 2 Jun 2009 20:42:41 +0000 (04:42 +0800)
committerLiu Aleaxander <Aleaxander@gmail.com>
Tue, 2 Jun 2009 20:42:41 +0000 (04:42 +0800)
It works well for extlinux(seems broken with ldlinux).
With the printf function can not work well in the format string, like %d,
I introduced a new function itoa(), that convert the number to string, for
debugging.

core/Makefile
core/cache.c
core/cache.h
core/extlinux.asm
core/hello.c
core/include/core.h
core/layout.inc
core/ldlinux.asm

index df3310e..2e28c93 100644 (file)
@@ -34,7 +34,6 @@ CODEPAGE = cp865
 # The targets to build in this directory...
 BTARGET  = kwdhash.gen \
           ldlinux.bss ldlinux.sys ldlinux.bin \
-          pxelinux.0 isolinux.bin isolinux-debug.bin \
           extlinux.bin extlinux.bss extlinux.sys
 
 # All primary source files for the main syslinux files
index aaa9000..c2c7a91 100644 (file)
@@ -1,7 +1,8 @@
 #include "core.h"
-
 #include "cache.h"
+
 #include <stdio.h>
+#include <string.h>
 
 
 /*
@@ -16,7 +17,6 @@
 
 
 static struct cache_struct cache_head, cache[MAX_CACHE_ENTRIES];
-static __u8 cache_data[65536];
 static int cache_block_size;
 static int cache_entries;
 
@@ -24,18 +24,18 @@ static int cache_entries;
  * cache_init:
  *
  * Initialize the cache data structres.
- * regs->eax.l stores the block size
+ * regs->eax.l stores the block size(in bits not bytes)
  *
  */
 void cache_init(com32sys_t * regs)
 {
         struct cache_struct *prev, *cur;
-        __u8 *data = cache_data;
-        int block_size = regs->eax.l;
+        char *data = core_cache_buf;
+        int block_size_shift = regs->eax.l;
         int i;
 
-        cache_block_size = block_size;
-        cache_entries = sizeof cache_data / block_size;
+        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;
         
@@ -49,20 +49,18 @@ void cache_init(com32sys_t * regs)
                 cur->prev  = prev;
                 prev->next = cur;
                 cur->data  = data;
-                data += block_size;
+                data += cache_block_size;
                 prev = cur++;
         }
 }
 
 
-extern void getlinsec(void);
-
-void getoneblk(char *buf, __u32 block, int block_size)
+void getoneblk(char *buf, uint32_t block, int block_size)
 {
-        int sec_per_block = block_size / 512; /* 512==sector size */
+        int sec_per_block = block_size >> 9; /* 512==sector size */
         com32sys_t regs;
         
-        
+        memset(&regs, 0, sizeof(regs) );
 
         regs.eax.l = block * sec_per_block;
         regs.ebp.l = sec_per_block;
@@ -87,6 +85,11 @@ void getoneblk(char *buf, __u32 block, int block_size)
  * rm and pm, c and asm, we call call it from C file, so no need 
  * com32sys_t *regs any more.
  *
+ * I just found that I was tring to do a stupid thing!
+ * I haven't change the fs code to c, so for now the cache is based
+ * on SECTOR SIZE but not block size. While we can fix it easily by 
+ * make the block size be the sector size.
+ *
  * @return: the data stores at gs:si
  *
  */
@@ -95,11 +98,20 @@ void get_cache_block(com32sys_t * regs)
     /* let's find it from the end, 'cause the endest is the freshest */
     struct cache_struct *cs = cache_head.prev;
     struct cache_struct *head,  *last;
-    __u32 block = regs->eax.l;
+    uint32_t block = regs->eax.l;
     int i;
+
+    static int total_read;
+    static int missed;
+    char buf[10];
     
+#if 0
+    itoa(buf, block);
+    myputs(buf);
+    myputs(" this is what we are looking cache for block\n\r");
+#endif
+
     if ( !block ) {
-        extern void myputs(const char *);
         myputs("ERROR: we got a ZERO block number that's not we want!\n");
         return;
     }
@@ -123,7 +135,23 @@ void get_cache_block(com32sys_t * regs)
         
         cs->block = block;
         getoneblk(cs->data, block, cache_block_size);
+
+        missed ++;
+    } 
+    
+    total_read ++;
+
+#if 0 /* testing how efficiency the cache is */
+    if ( total_read % 5 == 0 ) {
+        itoa(buf, total_read);
+        myputs("total_read ");
+        myputs(buf);
+        myputs("\tmissed ");
+        itoa(buf, missed);
+        myputs(buf);
+        myputs("\n\r");
     }
+#endif
     
     /* remove cs from current position in list */
     cs->prev->next = cs->next;
@@ -140,6 +168,10 @@ void get_cache_block(com32sys_t * regs)
     cs->next = head;
     
  out:
+    /* in fact, that would never be happened */
+    if ( (char *)(cs->data) > (char*)0x100000 )
+        myputs("the buffer addres higher than 1M limit\n\r");
+    
     regs->gs = SEG(cs->data);
     regs->esi.w[0]= OFFS(cs->data);
-}
+}    
index 89892a0..666863d 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _CACHE_H
 #define _CACHE_H
 
-#include "types.h"
+#include <stdint.h>
 #include <com32.h>
 
 
@@ -11,7 +11,7 @@
 
 /* The cache structure */
 struct cache_struct {
-        __u32 block;
+        uint32_t block;
         struct cache_struct *prev;
         struct cache_struct *next;
         void  *data;
index 2273ae1..bdf1cde 100644 (file)
@@ -153,7 +153,7 @@ Files               resb MAX_OPEN*open_file_t_size
 ;
 ; Initialize the metadata cache
 ;
-               mov eax, [ClustSize]
+               mov eax, 9            ; for now, the cache is based on sector but not block
                pm_call cache_init
 
 ;
index eb0069f..1909de4 100644 (file)
@@ -1,16 +1,32 @@
 #include <stddef.h>
 #include <com32.h>
+#include <stdio.h>
+#include <string.h>
+
+void itoa(char *str, int num)
+{
+    char buf[10];
+    int i = 0;
+    
+    do {
+        buf[i++] = num % 10 + 0x30;
+    }while ( num /= 10 );
+
+    str[i] = '\0';
+    for (; i > 0; i -- )
+        *str++ = buf[i-1];
+}
 
 void myputchar(int c)
 {
     static com32sys_t ireg;
-    static uint16_t *vram = 0xb8000;
+    //static uint16_t *vram = 0xb8000;
 
     ireg.eax.b[1] = 0x02;
     ireg.edx.b[0] = c;
     __intcall(0x21, &ireg, NULL);
 
-    *vram++ = c + 0x1f00;
+    //*vram++ = c + 0x0700;
 }
 
 void myputs(const char *str)
index 91bd2d8..620459e 100644 (file)
@@ -4,6 +4,13 @@
 #include <com32.h>
 
 extern char core_xfer_buf[65536];
+extern char core_cache_buf[65536];
+
+extern void getlinsec(void);
+
+extern void myputs(const char*);
+extern void itoa(char *, int);
+
 void __cdecl core_intcall(uint8_t, const com32sys_t *, com32sys_t *);
 void __cdecl core_farcall(uint32_t, const com32sys_t *, com32sys_t *);
 int __cdecl core_cfarcall(uint32_t, const void *, uint32_t);
index fe292b1..4af661a 100644 (file)
@@ -127,7 +127,9 @@ auxseg              resb aux_size
 ; ISOLINUX doesn't have a block cache yet
 real_mode_seg  equ 3000h
 %else
+               global cache_seg, core_cache_buf
 cache_seg      equ 3000h               ; 64K area for metadata cache
+core_cache_buf         equ cache_seg << 4
 real_mode_seg  equ 4000h
 
 pktbuf_seg     equ cache_seg           ; PXELINUX packet buffers
index 4511009..34eec93 100644 (file)
@@ -211,7 +211,7 @@ getfattype:
 ;
 ; Initialize the metadata cache
 ;
-               mov eax, [ClustSize]
+               mov eax, 9
                pm_call cache_init
 
 ;