Convert the cache code to C and implement the core printf function
authorLiu Aleaxander <Aleaxander@gmail.com>
Tue, 2 Jun 2009 00:32:36 +0000 (08:32 +0800)
committerLiu Aleaxander <Aleaxander@gmail.com>
Tue, 2 Jun 2009 00:32:36 +0000 (08:32 +0800)
for the cahce part, I do get the error message says that undefined reference
to `getlinsec'. I'm abort to implement a C version one.

for the printf function, it works somehow, but doesn't work well. With the test,
it seems it can handle the format output correctly. And I haven't debugged it,
so I have no idea for now.

core/cache.c [new file with mode: 0644]
core/cache.h [new file with mode: 0644]
core/diskstart.inc
core/extern.inc
core/extlinux.asm
core/ldlinux.asm
core/printf.c [new file with mode: 0644]
core/types.h [new file with mode: 0644]

diff --git a/core/cache.c b/core/cache.c
new file mode 100644 (file)
index 0000000..aaa9000
--- /dev/null
@@ -0,0 +1,145 @@
+#include "core.h"
+
+#include "cache.h"
+#include <stdio.h>
+
+
+/*
+ * Each CachePtr contains:
+ * - Block pointer
+ * - LRU previous pointer
+ * - LRU next pointer
+ * - Block data buffer address
+ * 
+ * The cache buffer are pointed to by a cache_head structure.
+ */
+
+
+static struct cache_struct cache_head, cache[MAX_CACHE_ENTRIES];
+static __u8 cache_data[65536];
+static int cache_block_size;
+static int cache_entries;
+
+/**
+ * cache_init:
+ *
+ * Initialize the cache data structres.
+ * regs->eax.l stores the block size
+ *
+ */
+void cache_init(com32sys_t * regs)
+{
+        struct cache_struct *prev, *cur;
+        __u8 *data = cache_data;
+        int block_size = regs->eax.l;
+        int i;
+
+        cache_block_size = block_size;
+        cache_entries = sizeof cache_data / block_size;
+        if (cache_entries > MAX_CACHE_ENTRIES)
+                cache_entries = MAX_CACHE_ENTRIES;
+        
+        cache_head.prev = &cache[cache_entries-1];
+        cache_head.prev->next = &cache_head;
+        prev = &cache_head;
+        
+        for (i = 0; i < cache_entries; i++) {
+                cur = &cache[i];
+                cur->block = 0;
+                cur->prev  = prev;
+                prev->next = cur;
+                cur->data  = data;
+                data += block_size;
+                prev = cur++;
+        }
+}
+
+
+extern void getlinsec(void);
+
+void getoneblk(char *buf, __u32 block, int block_size)
+{
+        int sec_per_block = block_size / 512; /* 512==sector size */
+        com32sys_t regs;
+        
+        
+
+        regs.eax.l = block * sec_per_block;
+        regs.ebp.l = sec_per_block;
+        regs.es = SEG(buf);
+        regs.ebx.w[0] = OFFS(buf);
+
+        call16(getlinsec, &regs, NULL);
+}
+
+
+
+/**
+ * get_cache_block:
+ *
+ * Check for a particular BLOCK in the block cache, 
+ * and if it is already there, just do nothing and return;
+ * otherwise load it and updata the relative cache
+ * structre with data pointer.
+ *
+ * it's a test version for my start of merging extlinux into core.
+ * and after I have figured out how to handle the relations between
+ * rm and pm, c and asm, we call call it from C file, so no need 
+ * com32sys_t *regs any more.
+ *
+ * @return: the data stores at gs:si
+ *
+ */
+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;
+    int i;
+    
+    if ( !block ) {
+        extern void myputs(const char *);
+        myputs("ERROR: we got a ZERO block number that's not we want!\n");
+        return;
+    }
+    
+    /* it's aleardy the freshest, so nothing we need do , just return it */
+    if ( cs->block == block ) 
+        goto out;
+    
+    for ( i = 0; i < cache_entries; i ++ ) {
+        if ( cs->block == block )
+            break;
+        else
+            cs = cs->prev;
+    }
+    
+    if ( i == cache_entries ) {
+        /* missed, so we need to load it */
+        
+        /* store it at the head of real cache */
+        cs = cache_head.next;
+        
+        cs->block = block;
+        getoneblk(cs->data, block, cache_block_size);
+    }
+    
+    /* remove cs from current position in list */
+    cs->prev->next = cs->next;
+    cs->next->prev = cs->prev;
+    
+    
+    /* add to just before head node */
+    last = cache_head.prev;
+    head = &cache_head;
+    
+    last->next = cs;
+    cs->prev = last;
+    head->prev = cs;
+    cs->next = head;
+    
+ out:
+    regs->gs = SEG(cs->data);
+    regs->esi.w[0]= OFFS(cs->data);
+}
diff --git a/core/cache.h b/core/cache.h
new file mode 100644 (file)
index 0000000..89892a0
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _CACHE_H
+#define _CACHE_H
+
+#include "types.h"
+#include <com32.h>
+
+
+#define MAX_CACHE_ENTRIES  0x064 /* I'm not sure it's the max */
+
+
+
+/* The cache structure */
+struct cache_struct {
+        __u32 block;
+        struct cache_struct *prev;
+        struct cache_struct *next;
+        void  *data;
+};
+
+
+
+/* functions defined in cache.c */
+void cache_init(com32sys_t *regs);
+
+void get_cache_block(com32sys_t *regs);
+
+#endif /* cache.h */
index b804726..4b570bc 100644 (file)
@@ -252,6 +252,7 @@ getonesec:
 ; that is dead from that point; this saves space.  However, please keep
 ; the order to dst,src to keep things sane.
 ;
+               global getlinsec
 getlinsec:
                add eax,[bsHidden]              ; Add partition offset
                xor edx,edx                     ; Zero-extend LBA (eventually allow 64 bits)
index f765cff..e6321d1 100644 (file)
@@ -12,4 +12,7 @@
        ; hello.c
        extern hello
 
+       ; cache.c
+       extern cache_init, get_cache_block
+
 %endif ; EXTERN_INC
index 3a054b2..2273ae1 100644 (file)
@@ -153,7 +153,8 @@ Files               resb MAX_OPEN*open_file_t_size
 ;
 ; Initialize the metadata cache
 ;
-               call initcache
+               mov eax, [ClustSize]
+               pm_call cache_init
 
 ;
 ; Now, everything is "up and running"... patch kaboom for more
@@ -308,7 +309,7 @@ open_inode:
                add eax,edx
                pop edx
                and dx,SECTOR_SIZE-1
-               call getcachesector             ; Get the group descriptor
+               pm_call get_cache_block         ; Get the group descriptor
                add si,dx
                mov esi,[gs:si+bg_inode_table]  ; Get inode table block #
                pop eax                         ; Get inode within group
@@ -327,7 +328,7 @@ open_inode:
                and dx,SECTOR_SIZE-1
                mov [bx+file_in_off],dx
 
-               call getcachesector
+               pm_call get_cache_block
                add si,dx
                mov cx,EXT2_GOOD_OLD_INODE_SIZE >> 2
                mov di,ThisInode
@@ -693,7 +694,7 @@ linsector:
                push eax
                mov eax,[si+file_in_sec]
                mov bx,si
-               call getcachesector     ; Get inode
+               pm_call get_cache_block ; Get inode
                add si,[bx+file_in_off] ; Get *our* inode
                pop eax
                lea ebx,[i_block+4*eax]
@@ -724,7 +725,7 @@ linsector:
                mov ebp,[gs:si+bx]
                shl ebp,cl
                add eax,ebp
-               call getcachesector
+               pm_call get_cache_block
                pop bx
                and bx,(SECTOR_SIZE >> 2)-1
                shl bx,2
@@ -742,7 +743,7 @@ linsector:
                mov ebp,[gs:si+bx]
                shl ebp,cl
                add eax,ebp
-               call getcachesector
+               pm_call get_cache_block
                pop bx
                and bx,(SECTOR_SIZE >> 2)-1
                shl bx,2
@@ -757,7 +758,7 @@ linsector:
                mov ebp,[gs:si+bx]
                shl ebp,cl
                add eax,ebp
-               call getcachesector
+               pm_call get_cache_block
                pop bx
                and bx,(SECTOR_SIZE >> 2)-1
                shl bx,2
@@ -874,7 +875,6 @@ build_curdir_str:
 %include "writestr.inc"                ; String output
 %include "writehex.inc"                ; Hexadecimal output
 %include "strecpy.inc"          ; strcpy with end pointer check
-%include "cache.inc"           ; Metadata disk cache
 %include "localboot.inc"       ; Disk-based local boot
 
 ; -----------------------------------------------------------------------------
index c08799f..4511009 100644 (file)
@@ -211,7 +211,8 @@ getfattype:
 ;
 ; Initialize the metadata cache
 ;
-               call initcache
+               mov eax, [ClustSize]
+               pm_call cache_init
 
 ;
 ; Now, everything is "up and running"... patch kaboom for more
@@ -392,7 +393,7 @@ search_dos_dir:
 
 .scansector:
                ; EAX <- directory sector to scan
-               call getcachesector
+               pm_call get_cache_block
                ; GS:SI now points to this sector
 
                mov cx,SECTOR_SIZE/32           ; 32 == directory entry size
@@ -745,7 +746,7 @@ readdir:
                cmp eax,0
                jz .fail
 .fetch_cache:
-               call getcachesector
+               pm_call get_cache_block
 .move_current:
                add si,bx       ; Resume last position in sector
                mov ecx,SECTOR_SIZE     ; 0 out high part
@@ -1358,7 +1359,7 @@ nextsector:
 ;
 getfatsector:
                add eax,[FAT]           ; FAT starting address
-               jmp getcachesector
+               pm_call get_cache_block
 
 ; -----------------------------------------------------------------------------
 ;  Common modules
@@ -1368,7 +1369,6 @@ getfatsector:
 %include "plaincon.inc"                ; writechr
 %include "writestr.inc"                ; String output
 %include "writehex.inc"                ; Hexadecimal output
-%include "cache.inc"           ; Metadata disk cache
 %include "localboot.inc"       ; Disk-based local boot
 
 ; -----------------------------------------------------------------------------
diff --git a/core/printf.c b/core/printf.c
new file mode 100644 (file)
index 0000000..3872e92
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <unistd.h>
+
+
+
+
+#define BUF_SIZE 1024
+
+char buf[BUF_SIZE];
+
+
+extern void myputs(const char *);
+
+int printf(const char *format, ...)
+{
+    va_list ap;
+    int rv;
+    
+    va_start(ap, format);
+    rv = sprintf(buf, format, ap);
+    va_end(ap);
+    
+    myputs(buf);
+
+    return rv;
+
+}
diff --git a/core/types.h b/core/types.h
new file mode 100644 (file)
index 0000000..4cd3902
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _TYPES_H
+#define _TYPES_H
+
+typedef unsigned long long __u64;
+typedef unsigned int   __u32;
+typedef unsigned short __u16;
+typedef unsigned char  __u8;
+
+
+typedef int   __s32;
+typedef short __s16;
+typedef char  __s8;
+
+
+
+
+#endif /* types.h */