grub-devel
[Top][All Lists]
Advanced

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

Linux/ADFS partition table support


From: Timothy Baldwin
Subject: Linux/ADFS partition table support
Date: Thu, 20 Oct 2005 15:47:50 +0100
User-agent: KMail/1.8.2

Here is support for Linux/ADFS partition tables, which is used for Linux 
partitions on discs connected to the motherboard interface of systems which 
run RISC OS.  Since it shares a structure with the RISC OS disc API, that has 
been separated into a header file.

In writing this I've discovered that RISC OS has no API to read the size of a 
disc, so filecore.mod now returns the largest value an unsigned long can 
store. The API which is documented to return the size of the disc actually 
returns the size of the Filecore filesystem on the disc.

I have also fixed a couple more bugs in the RISC OS port.

RISC OS specific changes are at:
http://www.majoroak.f2s.com/tim/grub/patches/grub2-patch13.diff.gz

General changes are below and at:
http://www.majoroak.f2s.com/tim/grub/patches/grub2-patch12b.diff.gz


2005-10-20  Timothy Baldwin  <address@hidden>

        Add support for Linux/ADFS partition tables.

        * partmap/acorn.c: New file.

        * include/grub/acorn_filecore.h: Likewise.

        * DISTLIST: Added `partmap/acorn.c' and `include/grub/acorn_filecore.h'.

        * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `partmap/acorn.c'.
        (pkgdata_MODULES): Add `acorn.mod'.
        (acorn_mod_SOURCES): New variable.
        (acorn_mod_CFLAGS): Likewise.

        * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add `partmap/acorn.c'.
        (pkgdata_MODULES): Add `acorn.mod'.
        (acorn_mod_SOURCES): New variable.
        (acorn_mod_CFLAGS): Likewise.

        * conf/i386-pc.rmk (grub_emu_SOURCES): Add `partmap/acorn.c'.
        (pkgdata_MODULES): Add `acorn.mod'.
        (acorn_mod_SOURCES): New variable.
        (acorn_mod_CFLAGS): Likewise.
        (acorn_mod_LDFLAGS): Likewise.

        * util/grub-emu.c (main): Call `grub_acorn_partition_map_init' and
        `grub_acorn_partition_map_fini'.

        * include/grub/partition.h (grub_acorn_partition_map_init): New 
prototype.
        (grub_acorn_partition_map_fini): Likewise.


diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x CVS grub2-submitted/conf/i386-pc.rmk grub2-arm/conf/i386-pc.rmk
--- grub2-submitted/conf/i386-pc.rmk    2005-10-15 08:44:41.000000000 +0100
+++ grub2-arm/conf/i386-pc.rmk  2005-10-18 20:45:28.000000000 +0100
@@ -94,6 +94,7 @@ grub_emu_SOURCES = commands/boot.c comma
        normal/completion.c normal/context.c normal/main.c              \
        normal/menu.c normal/menu_entry.c normal/misc.c                 \
        partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c      \
+       partmap/acorn.c                                                 \
        util/console.c util/grub-emu.c util/misc.c                      \
        util/i386/pc/biosdisk.c util/i386/pc/getroot.c                  \
        util/i386/pc/misc.c
@@ -117,7 +118,7 @@ pkgdata_MODULES = _chain.mod _linux.mod 
        apple.mod pc.mod sun.mod loopback.mod reboot.mod halt.mod       \
        help.mod default.mod timeout.mod configfile.mod vbe.mod         \
        vesafb.mod vbetest.mod vbeinfo.mod search.mod gzio.mod          \
-       terminfo.mod serial.mod xfs.mod affs.mod sfs.mod
+       terminfo.mod serial.mod xfs.mod affs.mod sfs.mod acorn.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -298,6 +299,11 @@ sun_mod_SOURCES = partmap/sun.c
 sun_mod_CFLAGS = $(COMMON_CFLAGS)
 sun_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For acorn.mod
+acorn_mod_SOURCES = partmap/acorn.c
+acorn_mod_CFLAGS = $(COMMON_CFLAGS)
+acorn_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For loopback.mod
 loopback_mod_SOURCES = disk/loopback.c
 loopback_mod_CFLAGS = $(COMMON_CFLAGS)
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x CVS grub2-submitted/conf/powerpc-ieee1275.rmk 
grub2-arm/conf/powerpc-ieee1275.rmk
--- grub2-submitted/conf/powerpc-ieee1275.rmk   2005-10-15 08:44:42.000000000 
+0100
+++ grub2-arm/conf/powerpc-ieee1275.rmk 2005-10-18 20:45:41.000000000 +0100
@@ -49,6 +49,7 @@ grub_emu_SOURCES = commands/boot.c comma
        normal/completion.c normal/context.c    \
        normal/main.c normal/menu.c normal/menu_entry.c normal/misc.c   \
        partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c      \
+       partmap/acorn.c                                                 \
        util/console.c util/grub-emu.c util/misc.c                      \
        util/i386/pc/biosdisk.c util/i386/pc/getroot.c                  \
        util/powerpc/ieee1275/misc.c
@@ -77,7 +78,7 @@ pkgdata_MODULES = _linux.mod linux.mod f
        boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \
        pc.mod suspend.mod loopback.mod help.mod reboot.mod halt.mod sun.mod \
        default.mod timeout.mod configfile.mod search.mod gzio.mod xfs.mod \
-       affs.mod sfs.mod
+       affs.mod sfs.mod acorn.mod
 
 # For fshelp.mod.
 fshelp_mod_SOURCES = fs/fshelp.c
@@ -183,6 +184,10 @@ pc_mod_CFLAGS = $(COMMON_CFLAGS)
 sun_mod_SOURCES = partmap/sun.c
 sun_mod_CFLAGS = $(COMMON_CFLAGS)
 
+# For acorn.mod
+acorn_mod_SOURCES = partmap/acorn.c
+acorn_mod_CFLAGS = $(COMMON_CFLAGS)
+
 # For loopback.mod
 loopback_mod_SOURCES = disk/loopback.c
 loopback_mod_CFLAGS = $(COMMON_CFLAGS)
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x CVS grub2-submitted/conf/sparc64-ieee1275.rmk 
grub2-arm/conf/sparc64-ieee1275.rmk
--- grub2-submitted/conf/sparc64-ieee1275.rmk   2005-08-21 20:33:14.000000000 
+0100
+++ grub2-arm/conf/sparc64-ieee1275.rmk 2005-10-18 20:46:47.000000000 +0100
@@ -47,6 +47,7 @@ grub_mkimage_SOURCES = util/sparc64/ieee
 #      normal/completion.c normal/context.c    \
 #      normal/main.c normal/menu.c normal/menu_entry.c normal/misc.c   \
 #      partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c      \
+#      partmap/acorn.c                                                 \
 #      util/console.c util/grub-emu.c util/misc.c                      \
 #      util/i386/pc/biosdisk.c util/i386/pc/getroot.c                  \
 #      util/sparc64/ieee1275/misc.c
@@ -73,7 +73,7 @@ genmoddep_SOURCES = util/genmoddep.c
 #      hfs.mod jfs.mod normal.mod hello.mod font.mod ls.mod \
 #      boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \
 #      pc.mod suspend.mod loopback.mod help.mod reboot.mod halt.mod sun.mod \
-#      default.mod timeout.mod configfile.mod search.mod
+#      default.mod timeout.mod configfile.mod search.mod acorn.mod
 
 # For fshelp.mod.
 fshelp_mod_SOURCES = fs/fshelp.c
@@ -167,6 +167,10 @@ pc_mod_CFLAGS = $(COMMON_CFLAGS)
 sun_mod_SOURCES = partmap/sun.c
 sun_mod_CFLAGS = $(COMMON_CFLAGS)
 
+# For acorn.mod
+acorn_mod_SOURCES = partmap/acorn.c
+acorn_mod_CFLAGS = $(COMMON_CFLAGS)
+
 # For loopback.mod
 loopback_mod_SOURCES = disk/loopback.c
 loopback_mod_CFLAGS = $(COMMON_CFLAGS)
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x CVS grub2-submitted/include/grub/acorn_filecore.h 
grub2-arm/include/grub/acorn_filecore.h
--- grub2-submitted/include/grub/acorn_filecore.h       1970-01-01 
01:00:00.000000000 +0100
+++ grub2-arm/include/grub/acorn_filecore.h     2005-10-16 20:43:03.000000000 
+0100
@@ -0,0 +1,51 @@
+ 
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_ACORN_FILECORE_HEADER
+#define GRUB_ACORN_FILECORE_HEADER     1
+
+#include <grub/types.h>
+
+struct grub_filecore_disc_record
+{
+  grub_uint8_t log2secsize;
+  grub_uint8_t secspertrack;
+  grub_uint8_t heads;
+  grub_uint8_t density;
+  grub_uint8_t idlen;
+  grub_uint8_t log2bpmb;
+  grub_uint8_t skew;
+  grub_uint8_t bootoption;
+  grub_uint8_t lowsector;      // In bits 0-5, flags in bits 6 and 7.
+  grub_uint8_t nzones;
+  grub_uint16_t zone_spare;
+  grub_uint32_t root_address;
+  grub_uint32_t disc_size;     // Disc size in bytes.
+  grub_uint16_t cycle_id;
+  char disc_name[10];
+  grub_uint32_t disctype;      // Yes, it is 32 bits!
+  grub_uint32_t disc_size2;    // Most significant part of the disc size.
+  grub_uint8_t share_size;
+  grub_uint8_t big_flag;
+  grub_uint8_t reserved[18];
+};
+
+
+#endif /* ! GRUB_ACORN_FILECORE_HEADER */
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x CVS grub2-submitted/include/grub/partition.h 
grub2-arm/include/grub/partition.h
--- grub2-submitted/include/grub/partition.h    2005-08-20 07:46:36.000000000 
+0100
+++ grub2-arm/include/grub/partition.h  2005-10-18 20:52:23.000000000 +0100
@@ -92,6 +92,8 @@ void grub_apple_partition_map_init (void
 void grub_apple_partition_map_fini (void);
 void grub_sun_partition_map_init (void);
 void grub_sun_partition_map_fini (void);
+void grub_acorn_partition_map_init (void);
+void grub_acorn_partition_map_fini (void);
 #endif
 
 static inline unsigned long
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x CVS grub2-submitted/partmap/acorn.c grub2-arm/partmap/acorn.c
--- grub2-submitted/partmap/acorn.c     1970-01-01 01:00:00.000000000 +0100
+++ grub2-arm/partmap/acorn.c   2005-10-18 20:51:23.000000000 +0100
@@ -0,0 +1,214 @@
+/* acorn.c - Read Linux/ADFS partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/acorn_filecore.h>
+#include <stddef.h>
+
+#define LINUX_NATIVE_MAGIC grub_cpu_to_le32 (0xdeafa1de)
+#define LINUX_SWAP_MAGIC   grub_cpu_to_le32 (0xdeafab1e)
+#define LINUX_MAP_ENTRIES  (512 / 12)
+
+struct grub_acorn_boot_block
+{
+  grub_uint8_t misc[0x1C0];
+  struct grub_filecore_disc_record disc_record;
+  grub_uint8_t flags;
+  grub_uint16_t start_cylinder;
+  grub_uint8_t checksum;
+} __attribute__ ((packed, aligned));
+
+struct linux_part
+{
+  grub_uint32_t magic;
+  grub_uint32_t start;
+  grub_uint32_t size;
+};
+
+static struct grub_partition_map grub_acorn_partition_map;
+
+#ifndef GRUB_UTIL
+static grub_dl_t my_mod;
+#endif
+
+
+static grub_err_t
+find (grub_disk_t disk, struct linux_part *m, unsigned *sector)
+{
+  int i;
+  struct grub_acorn_boot_block boot;
+  grub_err_t err = grub_disk_read (disk, 0xC00 / GRUB_DISK_SECTOR_SIZE, 0,
+                                  sizeof (struct grub_acorn_boot_block),
+                                  &boot);
+  if (err)
+    return err;
+
+  if ((boot.flags & 15) != 9)
+    goto fail;
+
+  unsigned checksum = 0;
+  for (i = 0; i != 0x1ff; ++i)
+    checksum = (checksum & 0xff) + (checksum >> 8) + boot.misc[i];
+
+  if ((grub_uint8_t) checksum != boot.checksum)
+    goto fail;
+
+  unsigned heads = boot.disc_record.heads + ((boot.disc_record.lowsector >> 6) 
& 1);
+  unsigned sectors_per_cylinder = boot.disc_record.secspertrack * heads;
+  *sector = grub_le_to_cpu16 (boot.start_cylinder) * sectors_per_cylinder;
+
+  return grub_disk_read (disk, *sector, 0, sizeof (struct linux_part) * 
LINUX_MAP_ENTRIES, m);
+
+fail:
+  return grub_error (GRUB_ERR_BAD_PART_TABLE,
+                    "Linux/ADFS partition map not found.");
+
+}
+
+
+static grub_err_t
+acorn_partition_map_iterate (grub_disk_t disk,
+                            int (*hook) (grub_disk_t disk,
+                                         const grub_partition_t partition))
+{
+  int i;
+  unsigned sector;
+  struct grub_partition part;
+  struct grub_disk raw;
+  struct linux_part map[LINUX_MAP_ENTRIES];
+
+  /* Enforce raw disk access.  */
+  raw = *disk;
+  raw.partition = 0;
+
+  grub_err_t err = find (&raw, map, &sector);
+  if (err)
+    return err;
+
+  part.partmap = &grub_acorn_partition_map;
+
+  for (i = 0; i != LINUX_MAP_ENTRIES; ++i)
+    {
+      if (map[i].magic != LINUX_NATIVE_MAGIC
+         && map[i].magic != LINUX_SWAP_MAGIC)
+       return GRUB_ERR_NONE;
+
+      part.start = sector + map[i].start;
+      part.len = map[i].size;
+      part.offset = 6;
+      part.index = i;
+
+      if (hook (disk, &part))
+       return grub_errno;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_partition_t
+acorn_partition_map_probe (grub_disk_t disk, const char *str)
+{
+  unsigned sector;
+  struct linux_part map[LINUX_MAP_ENTRIES];
+
+  /* Enforce raw disk access.  */
+  struct grub_disk raw = *disk;
+  raw.partition = 0;
+
+  /* Get the partition number.  */
+  unsigned long partnum = grub_strtoul (str, 0, 10);
+  if (partnum > LINUX_MAP_ENTRIES)
+    goto fail;
+
+  grub_err_t err = find (&raw, map, &sector);
+  if (err)
+    return 0;
+
+  if (map[partnum].magic != LINUX_NATIVE_MAGIC
+      && map[partnum].magic != LINUX_SWAP_MAGIC)
+    goto fail;
+
+  grub_partition_t p = grub_malloc (sizeof (struct grub_partition));
+  if (!p)
+    return 0;
+
+  p->start = sector + map[partnum].start;
+  p->len = map[partnum].size;
+  p->offset = 6;
+  p->index = partnum;
+  return p;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
+  return 0;
+}
+
+
+static char *
+acorn_partition_map_get_name (const grub_partition_t p)
+{
+  char *name;
+
+  name = grub_malloc (13);
+  if (!name)
+    return 0;
+
+  grub_sprintf (name, "%d", p->index);
+  return name;
+}
+
+
+/* Partition map type.  */
+static struct grub_partition_map grub_acorn_partition_map = {
+  .name = "Linux/Filecore partition map",
+  .iterate = acorn_partition_map_iterate,
+  .probe = acorn_partition_map_probe,
+  .get_name = acorn_partition_map_get_name
+};
+
+
+#ifdef GRUB_UTIL
+void
+grub_acorn_partition_map_init (void)
+{
+  grub_partition_map_register (&grub_acorn_partition_map);
+}
+
+void
+grub_acorn_partition_map_fini (void)
+{
+  grub_partition_map_unregister (&grub_acorn_partition_map);
+}
+#else
+GRUB_MOD_INIT
+{
+  grub_partition_map_register (&grub_acorn_partition_map);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI
+{
+  grub_partition_map_unregister (&grub_acorn_partition_map);
+}
+#endif
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x CVS grub2-submitted/util/grub-emu.c grub2-arm/util/grub-emu.c
--- grub2-submitted/util/grub-emu.c     2005-10-15 08:44:51.000000000 +0100
+++ grub2-arm/util/grub-emu.c   2005-10-18 20:48:57.000000000 +0100
@@ -193,6 +193,7 @@ main (int argc, char *argv[])
   grub_amiga_partition_map_init ();
   grub_apple_partition_map_init ();
   grub_sun_partition_map_init ();
+  grub_acorn_partition_map_init ();
 
   /* Initialize the default modules.  */
   grub_iso9660_init ();
@@ -255,6 +256,7 @@ main (int argc, char *argv[])
   grub_pc_partition_map_fini ();
   grub_apple_partition_map_fini ();
   grub_sun_partition_map_fini ();
+  grub_acorn_partition_map_fini ();
 
   grub_machine_fini ();
   
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x CVS grub2-submitted/DISTLIST grub2-arm/DISTLIST
--- grub2-submitted/DISTLIST    2005-10-15 18:52:29.000000000 +0100
+++ grub2-arm/DISTLIST  2005-10-20 12:57:08.000000000 +0100
@@ -67,6 +67,7 @@ fs/ufs.c
 fs/sfs.c
 fs/xfs.c
 hello/hello.c
+include/grub/acorn_filecore.h
 include/grub/arg.h
 include/grub/boot.h
 include/grub/cache.h
@@ -184,6 +185,7 @@ normal/menu_entry.c
 normal/misc.c
 normal/i386/setjmp.S
 normal/powerpc/setjmp.S
+partmap/acorn.c
 partmap/amiga.c
 partmap/apple.c
 partmap/pc.c


-- 
Member AFFS, WYLUG, SWP (UK), UAF, RESPECT, StWC
No to software patents!    Victory to the iraqi resistance!

Attachment: pgpRKWDoHv5uc.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]