I finally had time to finish this up along with some cleanup.  I failed
to fix openbios (I can't make sense of it), so I instead did some ugly
hack to work around the bad implementation in openbios by keeping the
struct address the same, and wrapping the code and data of first.b around
that struct, rather than being all before the struct.  It works
wonderfully with qemu 0.10.4 from sid.

So what has been changed:

Build warnings and errors.

Makefile dependancies have been cleaned up so make works without
unnecesary runs of make clean.

Support for initrd+vmlinux bigger than 11MB except on powerpc 601 where
only 16MB is mapped.  64MB is now mapped on 604 and higher.  No idea
how the mapping works on a 601 so I don't know how to fix it.

Support for a larger second.b file.  256KB is currently supported up
from 64KB.  Since e2fslibs has gotten larger, second.b is currently 85KB,
which caused problems building a working quik before.  This is done
through the use of a second.map file.  first.b now only stores the
location of second.map, loads that and then uses the 1024 bytes in that
as the table of blocks for second.b

Switching to a newer e2fslibs means symlinks are now fully supported.
Using ext3 might work, but some unclean shutdowns might make for
an unreadable filesystem and cause boot failures.  I would recommend
sticking with ext2 for /boot.

Version number changed to 3.0 since I think this is a HUGE change in
functionality and behaviour.  You can decide if you like that change
or not.

So here is the patch:

diff -ruN quik-2.1/first/first.S quik-2.1.fixed/first/first.S
--- quik-2.1/first/first.S      2009-05-20 14:46:01.000000000 -0400
+++ quik-2.1.fixed/first/first.S        2009-05-20 15:55:18.000000000 -0400
@@ -38,6 +38,26 @@
 .LC7:  .string "exit"
 .LC8:  .string "enter"
 
+/* We need 64bytes for our FIRST_INFO struct reserved so we make some */
+/* data and tell the linker where we want it.                         */
+       .section        ".filler"
+.FILL0:        .long   0xdeadbeef
+.FILL1:        .long   0xdeadbeef
+.FILL2:        .long   0xdeadbeef
+.FILL3:        .long   0xdeadbeef
+.FILL4:        .long   0xdeadbeef
+.FILL5:        .long   0xdeadbeef
+.FILL6:        .long   0xdeadbeef
+.FILL7:        .long   0xdeadbeef
+.FILL8:        .long   0xdeadbeef
+.FILL9:        .long   0xdeadbeef
+.FILLA:        .long   0xdeadbeef
+.FILLB:        .long   0xdeadbeef
+.FILLC:        .long   0xdeadbeef
+.FILLD:        .long   0xdeadbeef
+.FILLE:        .long   0xdeadbeef
+.FILLF:        .long   0xdeadbeef
+
        .section        ".text"
        .align  2
        .globl  main
@@ -56,7 +76,8 @@
        sync
        isync
 
-/* Use the BAT2 & 3 registers to map the 1st 16MB of RAM to 0. */
+/* Use the BAT2 & 3 registers to map the 1st 16MB of RAM to 0 on 601. */
+/* Use the BAT3 register to map the 1st 64MB of RAM to 0 on 604 and later. */
        mfpvr   9
        rlwinm  9,9,16,16,31            /* r9 = 1 for 601, 4 for 604 */
                                        /* the 604 case now works on G3, and 
should */
@@ -66,7 +87,7 @@
        li      7,4                     /* set up BAT registers for 601 */
        li      8,0x7f
        b       5f
-4:     li      7,0x1ff                 /* set up BAT registers for 604 et al */
+4:     li      7,0x7ff                 /* set up BAT registers for 604 et al */
        li      8,2
        mtdbatl 3,8
        mtdbatu 3,7
@@ -134,11 +155,33 @@
        cmplwi  0,0,1
        ble     out             /*      goto out; */
 
+/* Load second.map.x */
        addi    26,14,first_i...@l      /* fp = FIRST_INFO; */
+       li      29,second_map_s...@l    /* map size should fit in one block */
+       addi    20,26,0x3C-4    /* bp = &fp->blknos[-1]; */
+       lwz     28,20(26)       /* addr = fp->second_map_base; */
+       addi    3,14,....@l     /*      call_prom("seek", 3, bdev, */
+       li      4,3             /*                0, *++bp * 512); */
+       mr      5,27
+       lwzu    31,4(20)
+       srwi    6,31,23
+       slwi    7,31,9
+       bl      call_prom
+       mr      16,3
+       addi    3,14,....@l     /*      if (call_prom("read", 3, bdev, */
+       li      4,3             /*                    addr, bs) != bs) */
+       mr      5,27
+       mr      6,28
+       mr      7,29
+       bl      call_prom
+       mr      30,3
+       cmpw    0,3,29          /*              goto out; */
+       bne     out
+
+/* Load second.b */
+       addi    20,28,-4        /* bp = &fp->mapbase[-1]; */
        lwz     28,16(26)       /* addr = fp->second_base; */
        mr      25,28           /* start = (void *) addr; */
-       lwz     29,12(26)       /* bs = fp->blocksize; */
-       addi    20,26,0x38-4    /* bp = &fp->blknos[-1]; */
        lwz     21,8(26)        /* i = fp->nblocks; do { */
 3:     addi    3,14,....@l     /*      call_prom("seek", 3, bdev, */
        li      4,3             /*                0, *++bp * 512); */
@@ -229,4 +272,18 @@
 .Lfe2:
        .size    call_prom,.Lfe2-call_prom
 
-
+       /* This is filler to ensure that the code ends at 0x2c8 where */
+       /* FIRST_INFO starts to line up with the filler data above    */
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
diff -ruN quik-2.1/first/ld.script quik-2.1.fixed/first/ld.script
--- quik-2.1/first/ld.script    2000-03-10 15:59:28.000000000 -0500
+++ quik-2.1.fixed/first/ld.script      2009-05-20 15:48:14.000000000 -0400
@@ -31,6 +31,7 @@
   .text      :
   {
     *(.text)
+    *(.filler)
     *(.rodata)
     *(.rodata1)
     *(.got1)
diff -ruN quik-2.1/include/layout.h quik-2.1.fixed/include/layout.h
--- quik-2.1/include/layout.h   2009-05-20 15:13:20.000000000 -0400
+++ quik-2.1.fixed/include/layout.h     2009-05-20 15:21:33.000000000 -0400
@@ -10,20 +10,25 @@
  * (at your option) any later version.
  */
 
-#define VERSION                "2.1"
+#define VERSION                "3.0"
 
 #define FIRST_BASE     0x3f4000 /* dec: 4145152 */
 #define FIRST_SIZE     0x400 /* dec: 1024 */
 
-#define SECOND_BASE    0x3e0000 /* dec: 4063232 */
-#define SECOND_SIZE    0x10000 /* dec: 65536 */
+#define SECOND_BASE    0x3b0000 /* dec: 3866624 */
+#define SECOND_SIZE    0x40000 /* dec: 262144 max size of second.b */
+
+#define SECOND_MAP_BASE 0x3efc00 /* Last 1K of SECOND's memory range,
+                                       which we can overwrite on last
+                                       transfer if needed */
+#define SECOND_MAP_SIZE        0x400 /* dec: 1024 */
 
 #define STACK_TOP      0x400000 /* dec: 4194304 */
 
 /* 0x400000 - 0x500000 is one of OF's favourite places to be. */
 
 /* We malloc in low memory now and load kernel at 0x500000 instead, we
- * also map 16Mb with BATs. This is all done to help loading larger
+ * also map 64MB with BATs. This is all done to help loading larger
  * kernels. --BenH.
  */
 #define MALLOC_BASE    0x300000 /* dec: 3145728 */
@@ -31,12 +36,13 @@
 #ifndef __ASSEMBLY__
 struct first_info {
     char       quik_vers[8];
-    int                nblocks;
+    int                nblocks; /* blocks in second.b */
     int                blocksize;
     unsigned   second_base;
+    unsigned   second_map_base; /* load address of second.map */
     int                conf_part;
     char       conf_file[32];
-    unsigned   blknos[64];
+    unsigned   blknos[1]; /* block used for second.map */
 };
 #endif /* __ASSEMBLY__ */
 
@@ -44,5 +50,10 @@
  * If you change FIRST_SIZE or sizeof(struct first_info),
  * be sure to change the definition of FIRST_INFO_OFF.
  */
-#define FIRST_INFO_OFF 0x2c8   /* == FIRST_SIZE - sizeof(struct first_info) */
+#define FIRST_INFO_OFF 0x2c8   /* was FIRST_SIZE - sizeof(struct first_info) */
+                                /* now it is stuck because openbios           
*/
+                                /* for qemu hardcoded it rather than just     
*/
+                                /* booting the bootable partition and I       
*/
+                                /* don't know how the openbios forth code     
*/
+                                /* works well enough to fix it.               
*/
 #define FIRST_INFO     (FIRST_BASE + FIRST_INFO_OFF)
diff -ruN quik-2.1/include/quik_md.h quik-2.1.fixed/include/quik_md.h
--- quik-2.1/include/quik_md.h  2009-05-20 14:46:01.000000000 -0400
+++ quik-2.1.fixed/include/quik_md.h    2009-01-21 17:06:51.000000000 -0500
@@ -93,7 +93,7 @@
   int rlevel;
 } mdev_info_t;
 
-#define BOOTDEV(dev,i) (((dev)->devs[(i)]) ? (dev)->devs[(i)]->bootdev : NULL)
+#define BOOTDEV(dev,i) (((dev)->devs[(i)]) ? (dev)->devs[(i)]->bootdev : "")
 #define SPART(dev,i) (((dev)->devs[(i)]) ? (dev)->devs[(i)]->spart : NULL)
 
 dev_info_t * new_dev_info (void);
@@ -101,6 +101,7 @@
 int md_get_version (int);
 mdev_info_t * md_get_info (const char *);
 mdev_info_t * new_mdev_info (unsigned char);
+void free_mdev_info(mdev_info_t *);
 
 
 #endif
diff -ruN quik-2.1/quik/Makefile quik-2.1.fixed/quik/Makefile
--- quik-2.1/quik/Makefile      2009-05-20 14:46:01.000000000 -0400
+++ quik-2.1.fixed/quik/Makefile        2009-01-21 17:08:00.000000000 -0500
@@ -5,6 +5,9 @@
 
 all: quik
 
+quik.o: quik.c ../include/layout.h ../include/quik_md.h
+quik_md.o: quik.c ../include/layout.h ../include/quik_md.h
+
 quik: $(objects)
        $(CC) $(CFLAGS) -o quik $(objects)
 
diff -ruN quik-2.1/quik/quik.c quik-2.1.fixed/quik/quik.c
--- quik-2.1/quik/quik.c        2009-05-20 14:46:01.000000000 -0400
+++ quik-2.1.fixed/quik/quik.c  2009-02-09 10:59:27.000000000 -0500
@@ -227,11 +227,13 @@
   }
 }
 
-int get_partition_blocks(char *filename, mdev_info_t * devs)
+int get_partition_blocks(char *filename, mdev_info_t * devs, char 
*mapfilenamebase)
 {
     int fd;
+    int mapfd;
     int block, i, j;
     struct stat st;
+    char mapfilename[64];
 
     if ((fd = open(filename, O_RDONLY)) == -1)
        fatal("Cannot find %s", filename);
@@ -240,18 +242,31 @@
     devs->nsect = devs->bs >> 9;
     for (j=0; j<devs->ndevs; j++) {
       if (SPART(devs,j)) {
+        snprintf(mapfilename,64,"%s.%d",mapfilenamebase,j);
+        if ((mapfd = open(mapfilename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) 
== -1)
+          fatal("Cannot open %s for write", mapfilename);
        devs->devs[j]->finfo.blocksize = devs->bs;
        
        for (i = 0;; i++) {
          block = i;
          if (i * devs->bs >= st.st_size || ioctl(fd, FIBMAP, &block) < 0 || 
!block)
            break;
-         devs->devs[j]->finfo.blknos[i] = block * devs->nsect + 
devs->devs[j]->doff;
+         devs->devs[j]->finfo.blknos[0] = block * devs->nsect + 
devs->devs[j]->doff;
+          write(mapfd,&(devs->devs[j]->finfo.blknos[0]),4);
        }
        devs->devs[j]->finfo.nblocks = i;
+        close(mapfd);
+        if ((mapfd = open(mapfilename, O_RDONLY)) == -1)
+          fatal("Cannot find %s", mapfilename);
+        block = 0;
+        if (ioctl(mapfd, FIBMAP, &block) < 0 || !block)
+          fatal("Failed to map block of %s",mapfilename);
+        devs->devs[j]->finfo.blknos[0] = block * devs->nsect + 
devs->devs[j]->doff;
+        close(mapfd);
       }
     }
     close(fd);
+
     return 0;
 }
 
@@ -284,6 +299,7 @@
                "QUIK" VERSION, 
                sizeof(devs->devs[i]->finfo.quik_vers));
        devs->devs[i]->finfo.second_base = SECOND_BASE;
+       devs->devs[i]->finfo.second_map_base = SECOND_MAP_BASE;
        devs->devs[i]->finfo.conf_part = devs->devs[i]->cpart;
        strncpy(devs->devs[i]->finfo.conf_file, 
                config_file, 
@@ -737,7 +753,7 @@
       install_first_stage(devs->fs_dev, install);
       make_bootable(devs);
     }
-    get_partition_blocks(secondary, devs);
+    get_partition_blocks(secondary, devs, "/boot/second.map");
     write_block_table(devs, config_file);
     
     free_mdev_info(devs);
diff -ruN quik-2.1/README.big.second quik-2.1.fixed/README.big.second
--- quik-2.1/README.big.second  1969-12-31 19:00:00.000000000 -0500
+++ quik-2.1.fixed/README.big.second    2009-05-20 16:47:10.000000000 -0400
@@ -0,0 +1,37 @@
+This version of QUIK has been enhanced to support a map file for loading
+second.b since e2fslibs has gotten to big to fit in the 64KB QUIK was
+originally written for.  This is similar to how lilo has done things
+pretty much forever since lilo only had 480 or so bytes to work in,
+while QUIK has 1024.  Eventually 1024 bytes isn't enough for the block
+map either though.
+
+Adding this support increased the size of first.S's assembly code, which
+causes the location of FIRST_INFO struct to move, although removing the
+second.b block map from the struct reduces the struct size a lot.
+
+Unfortunately, openbios for ppc qemu has hardcoded the location of the
+struct used by QUIK 2.1, rather than implementing generic loading of
+whatever partition is flagged as bootable.  I wish I knew how to fix
+that but I can't understand the forth code they use at all, and have no
+idea how to fix it.  So to stay compatible with openbios's current design,
+I have kept the struct location fixed at 0x2c8 from the start of the
+code and filled it with filler data (currently 64bytes of 0xdeadbeef).
+The code is padded with nop to 0x2c8 and the linker script places the
+filler section right after the code.  This leaves space between the code
+and rodata for the 64byte scruct and leaves the address of the struct
+fixed so that openbios can still find it.  It's ugly, but it works.
+
+The maximum size of second.b is now 256KB rather than 64KB, and could
+be made larger without much effort.  Current size is 85KB.
+
+Moving to a new e2fslibs has made symlinks work, so that's a bonus.
+It may even work with ext3 filesystems, although if you have an unclean
+shutdown, the journal needing a replay could prevent you from booting,
+which is similar to issues grub can have with ext3 filesystems and
+unclean shutdowns.  Maybe it works, maybe it doesn't.  ext2 for /boot
+is still recommended.  Certainly you must have quik load from a filesystem
+where the block numbers fit in 32bit (so no more than 2TB including any
+offsets from the start of the disk).  Probably not an issue for anyone.
+
+-- 
+Len Sorensen
diff -ruN quik-2.1/second/Makefile quik-2.1.fixed/second/Makefile
--- quik-2.1/second/Makefile    2009-05-20 14:46:01.000000000 -0400
+++ quik-2.1.fixed/second/Makefile      2009-02-09 10:58:53.000000000 -0500
@@ -4,7 +4,7 @@
 
 CFLAGS = -I../include -O2 -D__NO_STRING_INLINES -Wall -ffreestanding
 
-LDFLAGS=-N -Ttext 0x3e0000
+LDFLAGS=-N -Ttext 0x3b0000
 
 OBJS = crt0.o printf.o malloc.o main.o cmdline.o disk.o file.o \
        cfg.o strtol.o prom.o cache.o string.o setjmp.o ctype.o \
@@ -16,8 +16,8 @@
        $(LD) $(LDFLAGS) -Bstatic -o second $(OBJS) -lext2fs
 
 crt0.o:        crt0.S
-main.o:        main.c quik.h
-malloc.o:      malloc.c quik.h
+main.o:        main.c quik.h ../include/layout.h
+malloc.o:      malloc.c quik.h ../include/layout.h
 printf.o:      printf.c quik.h
 cmdline.o:     cmdline.c quik.h
 disk.o:               disk.c quik.h
diff -ruN quik-2.1/second/misc.c quik-2.1.fixed/second/misc.c
--- quik-2.1/second/misc.c      2009-05-20 14:46:01.000000000 -0400
+++ quik-2.1.fixed/second/misc.c        2009-05-20 16:08:24.000000000 -0400
@@ -11,8 +11,6 @@
  */
 #include <linux/kernel.h>
 
-#include <asm/page.h>
-
 #include <sys/types.h>
 #include "setjmp.h"
 #include "gzip.h"
diff -ruN quik-2.1/second/prom.c quik-2.1.fixed/second/prom.c
--- quik-2.1/second/prom.c      2009-05-20 14:46:01.000000000 -0400
+++ quik-2.1.fixed/second/prom.c        2009-02-05 16:31:25.000000000 -0500
@@ -145,29 +145,32 @@
 prom_init(void (*pp)(void *))
 {
     prom_entry = pp;
+    int tmp;
     /* First get a handle for the stdout device */
     prom_chosen = call_prom("finddevice", 1, 1, "/chosen");
     if (prom_chosen == (void *)-1)
        prom_exit();
-    getpromprop(prom_chosen, "stdout", &prom_stdout, sizeof(prom_stdout));
-    getpromprop(prom_chosen, "stdin", &prom_stdin, sizeof(prom_stdin));
-    getpromprop(prom_chosen, "mmu", &prom_mmu, sizeof(prom_mmu));
+    tmp = getpromprop(prom_chosen, "stdout", &prom_stdout, 
sizeof(prom_stdout));
+    tmp = getpromprop(prom_chosen, "stdin", &prom_stdin, sizeof(prom_stdin));
+    tmp = getpromprop(prom_chosen, "mmu", &prom_mmu, sizeof(prom_mmu));
     prom_options = call_prom("finddevice", 1, 1, "/options");
 }
 
 void
 prom_get_chosen(char *name, char *buf, int buflen)
 {
+    int tmp;
     buf[0] = 0;
-    getpromprop(prom_chosen, name, buf, buflen);
+    tmp = getpromprop(prom_chosen, name, buf, buflen);
 }
 
 void
 prom_get_options(char *name, char *buf, int buflen)
 {
+    int tmp;
     buf[0] = 0;
     if (prom_options != (void *) -1)
-       getpromprop(prom_options, name, buf, buflen);
+       tmp = getpromprop(prom_options, name, buf, buflen);
 }
 
 int
diff -ruN quik-2.1/second/quik.h quik-2.1.fixed/second/quik.h
--- quik-2.1/second/quik.h      2009-05-20 14:46:01.000000000 -0400
+++ quik-2.1.fixed/second/quik.h        2009-02-05 16:22:29.000000000 -0500
@@ -6,7 +6,7 @@
 #include <stddef.h>
 
 #define IMAGE_BUF       ((unsigned char *) 0x500000)
-#define IMAGE_END       ((unsigned char *) 0x1000000)
+#define IMAGE_END       ((unsigned char *) 0x4000000)
 
 extern char cbuff[];
 extern char bootdevice[];
@@ -58,3 +58,4 @@
 void cmdinit();
 void cmdedit(void (*tabfunc)(void), int c);
 
+int uncompress_kernel(int);



-- 
To UNSUBSCRIBE, email to debian-bugs-rc-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to