Port-sandpoint archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Synology PPCBoot SK98 network bug fix



Hi,

> Too bad. We must be missing something, as the kernel driver obviously
> can do it.

I looked again at our kernel driver and also the ppcboot sources, and saw
that we don't do the XMAC set up in altboot.  However, adding that didn't
make any difference, so I'm still using 8 receive buffers.

I also looked at creating an environment on the flash.  Looking at the
ppcboot code, I think this should be:

  4 byte CRC for the whole ot the data
  0x20000 bytes of environment data

  environment strings are followed by \0 with an extra \0 at the end
  environment starts ar 0xFFF50000

So, I wrote a program to generate CRC + 0x20000 bytes from arguments:

  http://www.coris.org.uk/misc/crc32env/

copied it via bootp and wrote it to flash at 0xFFF5000.  I still get:

  *** Warning - bad CRC, using default environment

though.  I checked that the CRC was correct by using:

  crc32 fff50004 20000 0

so I must have the address wrong.

So, I decided to give up with this and actually install NetBSD ;-)  I
partitioned the disk using an MBR with the NetBSD partition at offset 64.
I added RAIDframe to the GENERIC kernel and configured the two disks as
RAID 0.  I also added booting from RAID 0 support to altboot (patches
attached).  My disk layout is:

fdisk:
  0: NetBSD (sysid 169)
    start 64, size 625142384 (305245 MB, Cyls 0/1/2-38913/80/63)

disklabel:
  e: 625142384        64       RAID                     # (Cyl.      0*- 620180)

and the boot output:

  wd0: <ST3320620AS> DMA LBA LBA48 305245 MB
  wd0e: raid
  raid.a: ffs   (128)
  raid.b: swap  (4194432)
  raid.d: ffs   (5245056)
  raid.e: ffs   (9439360)
  raid.f: ffs   (17827968)
  raid.g: ffs   (26216576)
  raid.h: ffs   (30410880)
  wd1: <ST3320620AS> DMA LBA LBA48 305245 MB
  wd1e: raid
  raid.a: ffs   (128)
  raid.b: swap  (4194432)
  raid.d: ffs   (5245056)
  raid.e: ffs   (9439360)
  raid.f: ffs   (17827968)
  raid.g: ffs   (26216576)
  raid.h: ffs   (30410880)
  MAC address 00:11:32:01:95:49

One thing that I noticed was that the dsk.c:dsk_strategy() doesn't seem to
read from the correct offset.  It has:

        if ((dlp = d->dlabel) != NULL)
                bno += dlp->d_partitions[d->part].p_offset;

but the partition offsets are relative to the start of the disklabel, and
not relative to the start of the disk.  So, I added the offsets to all the
partitions in decode_dlabel() (for all cases, not only RAID).  I'm not sure
how it worked before if the boot partition wasn't at the start of the disk?
Note, that the patch will not work if there is a boot partition followed by
RAID paritions on the disk.  Perhaps I should check if partition 'a' is FFS
and only check for a RAID partition if it is not?

I also noticed that:

  go 1000000 wd0:netbsd ask

didn't cause the kernel to ask for the root partition, so I have to remove
automatic root from the RAID set if I boot from the network, and that the
disk lights stay as blinking orange.  I will try and look at these soon.

Thanks,

J

-- 
  My other computer also runs NetBSD    /        Sailing at Newbiggin
        http://www.netbsd.org/        /   http://www.newbigginsailingclub.org/
Index: src/sys/arch/sandpoint/stand/altboot/dsk.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sandpoint/stand/altboot/dsk.c,v
retrieving revision 1.5
diff -u -r1.5 dsk.c
--- src/sys/arch/sandpoint/stand/altboot/dsk.c  6 Mar 2011 13:55:12 -0000       
1.5
+++ src/sys/arch/sandpoint/stand/altboot/dsk.c  14 Jun 2011 06:18:23 -0000
@@ -43,6 +43,7 @@
 
 #include <sys/disklabel.h>
 #include <sys/bootblock.h>
+#include <dev/raidframe/raidframevar.h>
 
 #include <machine/bootinfo.h>
 #include <machine/stdarg.h>
@@ -297,6 +298,7 @@
        struct partition *pp;
        char *dp;
        int i, first;
+       daddr_t rf_offset = 0;
 
        bsdp = NULL;
        (*d->lba_read)(d, 0, 1, iobuf);
@@ -316,6 +318,22 @@
        for (i = 0; i < 512 - sizeof(struct disklabel); i++, dp += 4) {
                dlp = (struct disklabel *)dp;
                if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC) {
+                       for (i = 0; i < dlp->d_npartitions; i += 1) {
+                               if (dlp->d_partitions[i].p_fstype == FS_RAID) {
+                                       printf("%s%c: raid\n", d->xname,
+                                           i + 'a');
+                                       snprintf(d->xname, sizeof(d->xname),
+                                           "raid.");
+                                       rf_offset = RF_PROTECTED_SECTORS;
+                                       (*d->lba_read)(d,
+                                           first + LABELSECTOR +
+                                           RF_PROTECTED_SECTORS,
+                                           1, iobuf);
+                                       break;
+                               }
+                       }
+               }
+               if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC) {
                        goto found;
                }
        }
@@ -323,11 +341,10 @@
        printf("%s: no disklabel\n", d->xname);
        return;
   found:
-       d->dlabel = allocaligned(sizeof(struct disklabel), 4);
-       memcpy(d->dlabel, dlp, sizeof(struct disklabel));
        for (i = 0; i < dlp->d_npartitions; i += 1) {
                const char *type;
                pp = &dlp->d_partitions[i];
+               pp->p_offset += first + rf_offset;
                type = NULL;
                switch (pp->p_fstype) {
                case FS_SWAP: /* swap */
@@ -341,8 +358,11 @@
                        break;
                }
                if (type != NULL)
-                       printf("%s%c: %s\n", d->xname, i + 'a', type);
+                       printf("%s%c: %s (%u)\n", d->xname, i + 'a', type,
+                           pp->p_offset);
        }
+       d->dlabel = allocaligned(sizeof(struct disklabel), 4);
+       memcpy(d->dlabel, dlp, sizeof(struct disklabel));
 }
 
 static void


Home | Main Index | Thread Index | Old Index