grub-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] a.out kernel loader


From: Marco Gerards
Subject: Re: [PATCH] a.out kernel loader
Date: Tue, 29 Jan 2008 09:48:21 +0100
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux)

Bean <address@hidden> writes:

> On Jan 28, 2008 5:11 PM, Robert Millan <address@hidden> wrote:
>> On Mon, Jan 28, 2008 at 04:10:42AM +0800, Bean wrote:
>> > > > >
>> > > > > How FreeBSD-specific is this?  Will the same module apply to other 
>> > > > > a.out
>> > > > > binaries ?  (I ask since you gave it a generic name)
>> > > >
>> > > > it's an old format of the unix system:
>> > > >
>> > > > http://en.wikipedia.org/wiki/A.out
>> > >
>> > > I know.. I was referring to your loader.
>> >
>> > it should be generic, but i only test it using the loader from freebsd.
>>
>> In that case, I'd suggest putting it directly in loader/ (without i386/pc/).
>>
>> Moving files on CVS is a PITA :-/
>
> ok, here is the new patch.

It would be nice if a.out support could be shared so it can be used
for multiboot as well.

>        * conf/i386-pc.rmk (pkglib_MODULES): Add aout.mod and _aout.mod.
>        (aout_mod_SOURCES): New variable.
>        (aout_mod_CFLAGS): Likewise.
>        (aout_mod_LDFLAGS): Likewise.
>        (_aout_mod_SOURCES): New variable.
>        (_aout_mod_CFLAGS): Likewise.
>        (_aout_mod_LDFLAGS): Likewise.
>
>        * loader/aout.c: New file.
>
>        * loader/aout_normal.c: New file.
>
>        * loader/i386/pc/aout.c: New file.
>
>        * include/grub/aout_loader.h: New file.
>
>
> diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
> index ff02332..36af7de 100644
> --- a/conf/i386-pc.rmk
> +++ b/conf/i386-pc.rmk
> @@ -151,8 +151,8 @@ grub_mkrescue_SOURCES = util/i386/pc/grub-mkrescue.in
>
>  # Modules.
>  pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \
> -     _multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod      \
> -     vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
> +     _multiboot.mod chain.mod multiboot.mod _aout.mod aout.mod reboot.mod \
> +     halt.mod vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
>       videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod  \
>       ata.mod vga.mod memdisk.mod jpeg.mod
>
> @@ -221,6 +221,16 @@ multiboot_mod_SOURCES = loader/multiboot_loader_normal.c
>  multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
>  multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
>
> +# For _aout.mod.
> +_aout_mod_SOURCES = loader/aout.c loader/i386/pc/aout.c
> +_aout_mod_CFLAGS = $(COMMON_CFLAGS)
> +_aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
> +
> +# For aout.mod.
> +aout_mod_SOURCES = loader/aout_normal.c
> +aout_mod_CFLAGS = $(COMMON_CFLAGS)
> +aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
> +
>  # For vbe.mod.
>  vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \
>                 video/i386/pc/vbefill.c video/i386/pc/vbeutil.c
> diff --git a/include/grub/aout_loader.h b/include/grub/aout_loader.h
> new file mode 100755
> index 0000000..64311eb
> --- /dev/null
> +++ b/include/grub/aout_loader.h
> @@ -0,0 +1,134 @@
> +/* aout_loader.h - a.out loader header file. */
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2008  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 3 of the License, or
> + *  (at your option) any later version.
> + *
> + *  GRUB 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +
> +#ifndef GRUB_AOUT_LOADER_HEADER
> +#define GRUB_AOUT_LOADER_HEADER 1
> +
> +#define __LDPGSZ 0x1000
> +
> +#define N_GETMAGIC(ex) \
> +     ( (ex).a_midmag & 0xffff )
> +#define N_GETMID(ex) \
> +     ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETMID_NET(ex) : \
> +     ((ex).a_midmag >> 16) & 0x03ff )
> +#define N_GETFLAG(ex) \
> +     ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETFLAG_NET(ex) : \
> +     ((ex).a_midmag >> 26) & 0x3f )
> +#define N_SETMAGIC(ex,mag,mid,flag) \
> +     ( (ex).a_midmag = (((flag) & 0x3f) <<26) | (((mid) & 0x03ff) << 16) | \
> +     ((mag) & 0xffff) )
> +
> +#define N_GETMAGIC_NET(ex) \
> +     (grub_be_to_cpu32((ex).a_midmag) & 0xffff)
> +#define N_GETMID_NET(ex) \
> +     ((grub_be_to_cpu32((ex).a_midmag) >> 16) & 0x03ff)
> +#define N_GETFLAG_NET(ex) \
> +     ((grub_be_to_cpu32((ex).a_midmag) >> 26) & 0x3f)
> +#define N_SETMAGIC_NET(ex,mag,mid,flag) \
> +     ( (ex).a_midmag = grub_cpu_to_be32( (((flag)&0x3f)<<26) |
> (((mid)&0x03ff)<<16) | \
> +     (((mag)&0xffff)) ) )
> +
> +#define N_ALIGN(ex,x) \
> +     (N_GETMAGIC(ex) == ZMAGIC || N_GETMAGIC(ex) == QMAGIC || \
> +      N_GETMAGIC_NET(ex) == ZMAGIC || N_GETMAGIC_NET(ex) == QMAGIC ? \
> +      ((x) + __LDPGSZ - 1) & ~(unsigned long)(__LDPGSZ - 1) : (x))
> +
> +/* Valid magic number check. */

Please use two spaces after a `.'.  I know this sounds minor, but I'd
like to keep a consistent coding style.  Same for the other comments.

> +#define      N_BADMAG(ex) \
> +     (N_GETMAGIC(ex) != OMAGIC && N_GETMAGIC(ex) != NMAGIC && \
> +      N_GETMAGIC(ex) != ZMAGIC && N_GETMAGIC(ex) != QMAGIC && \
> +      N_GETMAGIC_NET(ex) != OMAGIC && N_GETMAGIC_NET(ex) != NMAGIC && \
> +      N_GETMAGIC_NET(ex) != ZMAGIC && N_GETMAGIC_NET(ex) != QMAGIC)
> +
> +/* Address of the bottom of the text segment. */
> +#define N_TXTADDR(ex) \
> +     ((N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC || \
> +     N_GETMAGIC(ex) == ZMAGIC) ? 0 : __LDPGSZ)
> +
> +/* Address of the bottom of the data segment. */
> +#define N_DATADDR(ex) \
> +     N_ALIGN(ex, N_TXTADDR(ex) + (ex).a_text)
> +
> +/* Text segment offset. */
> +#define      N_TXTOFF(ex) \
> +     (N_GETMAGIC(ex) == ZMAGIC ? __LDPGSZ : (N_GETMAGIC(ex) == QMAGIC || \
> +     N_GETMAGIC_NET(ex) == ZMAGIC) ? 0 : sizeof(struct aout_header))
> +
> +/* Data segment offset. */
> +#define      N_DATOFF(ex) \
> +     N_ALIGN(ex, N_TXTOFF(ex) + (ex).a_text)
> +
> +/* Relocation table offset. */
> +#define N_RELOFF(ex) \
> +     N_ALIGN(ex, N_DATOFF(ex) + (ex).a_data)
> +
> +/* Symbol table offset. */
> +#define N_SYMOFF(ex) \
> +     (N_RELOFF(ex) + (ex).a_trsize + (ex).a_drsize)
> +
> +/* String table offset. */
> +#define      N_STROFF(ex)    (N_SYMOFF(ex) + (ex).a_syms)
> +
> +/*
> + * Header prepended to each a.out file.
> + * only manipulate the a_midmag field via the
> + * N_SETMAGIC/N_GET{MAGIC,MID,FLAG} macros in a.out.h
> + */

Please do not use comments like this with a asterix on each line.

> +struct aout_header
> +{
> +  grub_uint32_t a_midmag;    /* htonl(flags<<26 | mid<<16 | magic) */
> +  grub_uint32_t a_text;              /* text segment size */
> +  grub_uint32_t a_data;              /* initialized data size */
> +  grub_uint32_t a_bss;               /* uninitialized data size */
> +  grub_uint32_t a_syms;              /* symbol table size */
> +  grub_uint32_t a_entry;     /* entry point */
> +  grub_uint32_t a_trsize;    /* text relocation size */
> +  grub_uint32_t a_drsize;    /* data relocation size */
> +};

Please fix these comments.  Same for those below.

> +/* a_magic */
> +#define      OMAGIC          0x107   /* 0407 old impure format */
> +#define      NMAGIC          0x108   /* 0410 read-only text */
> +#define      ZMAGIC          0x10b   /* 0413 demand load format */
> +#define QMAGIC          0xcc /* 0314 "compact" demand load format */
> +
> +/* a_mid */
> +#define      MID_ZERO        0       /* unknown - implementation dependent */
> +#define      MID_SUN010      1       /* sun 68010/68020 binary */
> +#define      MID_SUN020      2       /* sun 68020-only binary */
> +#define MID_I386     134     /* i386 BSD binary */
> +#define MID_SPARC    138     /* sparc */
> +#define      MID_HP200       200     /* hp200 (68010) BSD binary */
> +#define      MID_HP300       300     /* hp300 (68020+68881) BSD binary */
> +#define      MID_HPUX        0x20C   /* hp200/300 HP-UX binary */
> +#define      MID_HPUX800     0x20B   /* hp800 HP-UX binary */

Like Robert asked, did you type this yourself?

> +/*
> + * a_flags
> + */
> +#define EX_PIC               0x10    /* contains position independant code */
> +#define EX_DYNAMIC   0x20    /* contains run-time link-edit info */
> +#define EX_DPMASK    0x30    /* mask for the above */
> +
> +void grub_aout_arch_boot (grub_addr_t entry);
> +void grub_rescue_cmd_aout (int argc, char *argv[]);
> +
> +#endif /* ! GRUB_AOUT_LOADER_HEADER */
> diff --git a/loader/aout.c b/loader/aout.c
> new file mode 100644
> index 0000000..584f93a
> --- /dev/null
> +++ b/loader/aout.c
> @@ -0,0 +1,149 @@
> +/* aout.c - boot a.out loader (*BSD)  */
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2008  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 3 of the License, or
> + *  (at your option) any later version.
> + *
> + *  GRUB 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <grub/loader.h>
> +#include <grub/file.h>
> +#include <grub/err.h>
> +#include <grub/rescue.h>
> +#include <grub/dl.h>
> +#include <grub/aout_loader.h>
> +
> +static grub_dl_t my_mod;
> +
> +static grub_addr_t entry;
> +
> +static grub_err_t
> +grub_aout_boot (void)
> +{
> +  grub_aout_arch_boot (entry);
> +
> +  /* Not reached.  */
> +  return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_aout_unload (void)
> +{
> +  grub_dl_unref (my_mod);
> +  return GRUB_ERR_NONE;
> +}
> +
> +void
> +grub_rescue_cmd_aout (int argc, char *argv[])
> +{
> +  grub_file_t file = 0;
> +  struct aout_header ah;
> +  grub_addr_t cur_addr;
> +  int align_4k;
> +
> +  grub_dl_ref (my_mod);
> +
> +  if (argc == 0)
> +    {
> +      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
> +      goto fail;
> +    }
> +
> +  file = grub_file_open (argv[0]);
> +  if (!file)
> +    goto fail;
> +
> +  if (grub_file_read (file, (char *) &ah, sizeof (ah)) != sizeof (ah))
> +    {
> +      grub_error (GRUB_ERR_READ_ERROR, "cannot read the a.out header");
> +      goto fail;
> +    }
> +
> +  if (N_BADMAG (ah))
> +    {
> +      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
> +      goto fail;
> +    }
> +
> +  entry = ah.a_entry & 0xFFFFFF;
> +
> +  if (*((char *) &ah) == 0xb && (*((char *) &ah + 1) == 1))
> +    {
> +      cur_addr = entry;
> +      align_4k = 0;
> +    }
> +  else
> +    {
> +      cur_addr = entry & 0xF00000;
> +      align_4k = 1;
> +    }
> +
> +  grub_file_seek (file, N_TXTOFF (ah));
> +
> +  if (grub_errno)
> +    goto fail;
> +
> +  if (cur_addr < 0x100000)
> +    {
> +      grub_error (GRUB_ERR_BAD_OS, "load address below 1M");
> +      goto fail;
> +    }
> +
> +  if (grub_file_read (file, (char *) cur_addr, ah.a_text) != (int) ah.a_text)
> +    {
> +      grub_error (GRUB_ERR_READ_ERROR, "read text fails");
> +      goto fail;
> +    }
> +
> +  cur_addr += ah.a_text;
> +
> +  if (align_4k)
> +    cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
> +
> +  if (grub_file_read (file, (char *) cur_addr, ah.a_data) != (int) ah.a_data)
> +    {
> +      grub_error (GRUB_ERR_READ_ERROR, "read data fails");
> +      goto fail;
> +    }
> +
> +  cur_addr += ah.a_data;
> +
> +  if (align_4k)
> +    cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
> +
> +  if (ah.a_bss)
> +    grub_memset ((char *) cur_addr, 0, ah.a_bss);
> +
> +  if (grub_errno == GRUB_ERR_NONE)
> +    grub_loader_set (grub_aout_boot, grub_aout_unload, 1);
> +
> +fail:
> +
> +  if (file)
> +    grub_file_close (file);
> +
> +  if (grub_errno != GRUB_ERR_NONE)
> +    grub_dl_unref (my_mod);
> +}
> +
> +GRUB_MOD_INIT (aout)
> +{
> +  grub_rescue_register_command ("aout", grub_rescue_cmd_aout, "load a.out");
> +  my_mod = mod;
> +}
> +
> +GRUB_MOD_FINI (aout)
> +{
> +  grub_rescue_unregister_command ("aout");
> +}
> diff --git a/loader/aout_normal.c b/loader/aout_normal.c
> new file mode 100644
> index 0000000..6dc0b3e
> --- /dev/null
> +++ b/loader/aout_normal.c
> @@ -0,0 +1,45 @@
> +/* aout_normal.c - boot a.out loader (*BSD)  */
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2008  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 3 of the License, or
> + *  (at your option) any later version.
> + *
> + *  GRUB 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <grub/loader.h>
> +#include <grub/err.h>
> +#include <grub/normal.h>
> +#include <grub/dl.h>
> +#include <grub/aout_loader.h>
> +
> +static grub_err_t
> +grub_normal_aout_command (struct grub_arg_list *state
> +                       __attribute__ ((unused)), int argc, char **args)
> +{
> +  grub_rescue_cmd_aout (argc, args);
> +  return grub_errno;
> +}
> +
> +GRUB_MOD_INIT (aout_normal)
> +{
> +  (void) mod;                        /* To stop warning.  */
> +  grub_register_command ("aout", grub_normal_aout_command,
> +                      GRUB_COMMAND_FLAG_BOTH,
> +                      "aout FILE [ARGS...]", "Load an a.out kernel.", 0);
> +}
> +
> +GRUB_MOD_FINI (aout_normal)
> +{
> +  grub_unregister_command ("aout");
> +}
> diff --git a/loader/i386/pc/aout.c b/loader/i386/pc/aout.c
> new file mode 100755
> index 0000000..179d70f
> --- /dev/null
> +++ b/loader/i386/pc/aout.c
> @@ -0,0 +1,28 @@
> +/* aout.c - boot an aout OS image. */
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2008  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 3 of the License, or
> + *  (at your option) any later version.
> + *
> + *  GRUB 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <grub/loader.h>
> +#include <grub/machine/loader.h>
> +#include <grub/aout_loader.h>
> +
> +void
> +grub_aout_arch_boot (grub_addr_t entry)
> +{
> +  grub_multiboot2_real_boot (entry, 0);
> +}
>
>
> -- 
> Bean
>
>
> _______________________________________________
> Grub-devel mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/grub-devel





reply via email to

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