grub-devel
[Top][All Lists]
Advanced

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

Re: Linux/ADFS partition table support


From: Timothy Baldwin
Subject: Re: Linux/ADFS partition table support
Date: Tue, 8 Nov 2005 19:20:13 +0000
User-agent: KMail/1.8.2

On Thursday 20 Oct 2005 15:47, Timothy Baldwin wrote:
> 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.

Revised for current CVS + 64-bit disk address support. Changelog as before.

diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x '*.rej' -x CVS grub2-submitted/conf/i386-pc.rmk 
grub2-work/conf/i386-pc.rmk
--- grub2-submitted/conf/i386-pc.rmk    2005-11-08 18:39:53.000000000 +0000
+++ grub2-work/conf/i386-pc.rmk 2005-11-08 19:01:17.000000000 +0000
@@ -102,6 +102,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 normal/script.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
@@ -125,7 +126,8 @@ 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 test.mod
+       terminfo.mod serial.mod xfs.mod affs.mod sfs.mod test.mod       \
+       acorn.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -307,6 +309,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 '*.rej' -x CVS grub2-submitted/conf/powerpc-ieee1275.rmk 
grub2-work/conf/powerpc-ieee1275.rmk
--- grub2-submitted/conf/powerpc-ieee1275.rmk   2005-11-08 18:39:53.000000000 
+0000
+++ grub2-work/conf/powerpc-ieee1275.rmk        2005-11-08 19:01:39.000000000 
+0000
@@ -57,6 +57,7 @@ grub_emu_SOURCES = commands/boot.c comma
        normal/function.c normal/lexer.c normal/main.c normal/menu.c    \
        normal/menu_entry.c normal/misc.c normal/script.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 grub_script.tab.c
@@ -91,7 +92,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 test.mod
+       affs.mod sfs.mod test.mod acorn.mod
 
 # For fshelp.mod.
 fshelp_mod_SOURCES = fs/fshelp.c
@@ -198,6 +199,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 '*.rej' -x CVS grub2-submitted/conf/sparc64-ieee1275.rmk 
grub2-work/conf/sparc64-ieee1275.rmk
--- grub2-submitted/conf/sparc64-ieee1275.rmk   2005-11-08 18:39:53.000000000 
+0000
+++ grub2-work/conf/sparc64-ieee1275.rmk        2005-11-08 19:01:57.000000000 
+0000
@@ -58,6 +58,7 @@ grub_mkimage_SOURCES = util/sparc64/ieee
 #      normal/function.c normal/lexer.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
@@ -86,7 +87,7 @@ pkgdata_MODULES = fat.mod ufs.mod ext2.m
        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
@@ -219,6 +220,10 @@ 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)
+
 # 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 '*.rej' -x CVS grub2-submitted/DISTLIST grub2-work/DISTLIST
--- grub2-submitted/DISTLIST    2005-10-15 19:10:37.000000000 +0100
+++ grub2-work/DISTLIST 2005-11-08 18:57:40.000000000 +0000
@@ -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
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x '*.rej' -x CVS grub2-submitted/include/grub/acorn_filecore.h 
grub2-work/include/grub/acorn_filecore.h
--- grub2-submitted/include/grub/acorn_filecore.h       1970-01-01 
01:00:00.000000000 +0100
+++ grub2-work/include/grub/acorn_filecore.h    2005-11-08 18:57:40.000000000 
+0000
@@ -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 '*.rej' -x CVS grub2-submitted/include/grub/partition.h 
grub2-work/include/grub/partition.h
--- grub2-submitted/include/grub/partition.h    2005-11-08 19:05:19.000000000 
+0000
+++ grub2-work/include/grub/partition.h 2005-11-08 19:05:05.000000000 +0000
@@ -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 grub_disk_addr_t
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x '*.rej' -x CVS grub2-submitted/partmap/acorn.c 
grub2-work/partmap/acorn.c
--- grub2-submitted/partmap/acorn.c     1970-01-01 01:00:00.000000000 +0100
+++ grub2-work/partmap/acorn.c  2005-11-08 18:57:40.000000000 +0000
@@ -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 = (grub_disk_addr_t)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 = (grub_disk_addr_t)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 '*.rej' -x CVS grub2-submitted/util/grub-emu.c 
grub2-work/util/grub-emu.c
--- grub2-submitted/util/grub-emu.c     2005-11-08 18:40:16.000000000 +0000
+++ grub2-work/util/grub-emu.c  2005-11-08 18:57:40.000000000 +0000
@@ -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 ();
@@ -257,6 +258,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 ();
   


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

Attachment: pgpBnTqmR6fjj.pgp
Description: PGP signature


reply via email to

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