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: Sun, 13 Nov 2005 18:51:16 +0000
User-agent: KMail/1.8.2

On Sunday 13 Nov 2005 16:03, Marco Gerards wrote:
> Timothy Baldwin <address@hidden> writes:

>       * include/grub/acorn_filecore.h: Likewise.
>
> I would prefer to move this to partmap/acorn.c.  Or do you have to use
> this struct elsewhere?

Yes it's also used in disk/arm/RISC_OS/filecore.c, as a parameter to some
system calls for reading disks. 

That will be a few patches down the line, but see
http://www.majoroak.f2s.com/tim/grub/RISC_OS/patches/grub2-patch3c.diff.gz
for a preview.

> >  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
>
> [...]
>
> > +#include <stddef.h>
>
> Why do you include stddef?  I really want to avoid this.

That was historic. Removed.  BTW, stddef.h is part of gcc.

> > +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));
>
> What is aligned?  Insn't it the opposite of packed?

Not quite, it aligns the whole struct without affecting the placement of
members within the struct. This avoids bloating the code with unneeded
unaligned loads (at least 7 times larger than an aligned load on ARM) that
would appear with packed alone.

I've made the changes you asked for, and synced to current CVS.
I've added grub_disk_addr_t as unsigned long pending inclusion of my
64-bit disk address support patch.


2005-13-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.

        * include/types.h (grub_disk_addr_t): New typedef.


diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x '*.rej' -x CVS grub2/conf/i386-pc.rmk 
grub2-acornpart/conf/i386-pc.rmk
--- grub2/conf/i386-pc.rmk      2005-11-13 17:42:24.000000000 +0000
+++ grub2-acornpart/conf/i386-pc.rmk    2005-11-13 17:53:43.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 grub_emu_init.c
@@ -134,7 +135,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
@@ -316,6 +318,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/conf/powerpc-ieee1275.rmk 
grub2-acornpart/conf/powerpc-ieee1275.rmk
--- grub2/conf/powerpc-ieee1275.rmk     2005-11-13 17:42:24.000000000 +0000
+++ grub2-acornpart/conf/powerpc-ieee1275.rmk   2005-11-13 17:53:43.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 grub_emu_init.c
@@ -100,7 +101,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
@@ -207,6 +208,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/conf/sparc64-ieee1275.rmk 
grub2-acornpart/conf/sparc64-ieee1275.rmk
--- grub2/conf/sparc64-ieee1275.rmk     2005-11-08 18:39:53.000000000 +0000
+++ grub2-acornpart/conf/sparc64-ieee1275.rmk   2005-11-13 17:53:43.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/DISTLIST grub2-acornpart/DISTLIST
--- grub2/DISTLIST      2005-10-15 19:10:37.000000000 +0100
+++ grub2-acornpart/DISTLIST    2005-11-13 17:53:43.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/include/grub/acorn_filecore.h 
grub2-acornpart/include/grub/acorn_filecore.h
--- grub2/include/grub/acorn_filecore.h 1970-01-01 01:00:00.000000000 +0100
+++ grub2-acornpart/include/grub/acorn_filecore.h       2005-11-13 
17:53:43.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/include/grub/types.h 
grub2-acornpart/include/grub/types.h
--- grub2/include/grub/types.h  2005-10-01 20:49:55.000000000 +0100
+++ grub2-acornpart/include/grub/types.h        2005-11-13 18:09:17.000000000 
+0000
@@ -93,6 +93,9 @@ typedef grub_uint32_t grub_size_t;
 typedef grub_int32_t   grub_ssize_t;
 #endif
 
+/* FIXME: Will be grub_uint64_t */
+typedef unsigned long  grub_disk_addr_t;
+
 /* Byte-orders.  */
 #define grub_swap_bytes16(x)   \
 ({ \
diff -purN -x '*.mk' -x '*~' -x autom4te.cache -x configure -x '.#*' -x 
'*.orig' -x '*.rej' -x CVS grub2/partmap/acorn.c grub2-acornpart/partmap/acorn.c
--- grub2/partmap/acorn.c       1970-01-01 01:00:00.000000000 +0100
+++ grub2-acornpart/partmap/acorn.c     2005-11-13 18:23:52.000000000 +0000
@@ -0,0 +1,197 @@
+/* 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>
+
+#define LINUX_NATIVE_MAGIC grub_cpu_to_le32 (0xdeafa1de)
+#define LINUX_SWAP_MAGIC   grub_cpu_to_le32 (0xdeafab1e)
+#define LINUX_MAP_ENTRIES  (512 / 12)
+
+#define NONADFS_PARTITON_TYPE_LINUX 9
+#define NONADFS_PARTITON_TYPE_MASK 15
+
+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;
+
+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 & NONADFS_PARTITON_TYPE_MASK) != NONADFS_PARTITON_TYPE_LINUX)
+    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/ADFS partition map",
+  .iterate = acorn_partition_map_iterate,
+  .probe = acorn_partition_map_probe,
+  .get_name = acorn_partition_map_get_name
+};
+
+
+GRUB_MOD_INIT(acorn_partition_map)
+{
+  grub_partition_map_register (&grub_acorn_partition_map);
+}
+
+GRUB_MOD_FINI(acorn_partition_map)
+{
+  grub_partition_map_unregister (&grub_acorn_partition_map);
+}


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

Attachment: pgpKIv18fgb9H.pgp
Description: PGP signature


reply via email to

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