[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] a.out kernel loader
From: |
Bean |
Subject: |
[PATCH] a.out kernel loader |
Date: |
Mon, 28 Jan 2008 02:53:14 +0800 |
Hi,
This patch add support for a.out kernel, which includes the 4th loader
of BSD system. For example, to start FreeBSD:
set root=(hd0,0,a)
aout /boot/loader
* 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/i386/pc/aout.c: New file.
* loader/i386/pc/aout_normal.c: New file.
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index 52dc06b..2d30a81 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -150,8 +150,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
@@ -180,6 +180,16 @@ linux_mod_SOURCES = loader/i386/pc/linux_normal.c
linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For _aout.mod.
+_aout_mod_SOURCES = loader/i386/pc/aout.c
+_aout_mod_CFLAGS = $(COMMON_CFLAGS)
+_aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For aout.mod.
+aout_mod_SOURCES = loader/i386/pc/aout_normal.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
# For normal.mod.
normal_mod_DEPENDENCIES = grub_script.tab.c grub_script.tab.h
normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \
diff --git a/loader/i386/pc/aout.c b/loader/i386/pc/aout.c
new file mode 100755
index 0000000..61133dd
--- /dev/null
+++ b/loader/i386/pc/aout.c
@@ -0,0 +1,267 @@
+/* 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/machine/loader.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/rescue.h>
+#include <grub/dl.h>
+
+static grub_dl_t my_mod;
+
+#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. */
+#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
+ */
+
+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 */
+};
+
+/* 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 */
+
+/*
+ * 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 */
+
+static grub_addr_t entry;
+
+static grub_err_t
+grub_aout_boot (void)
+{
+ grub_multiboot_real_boot (entry, 0);
+
+ /* 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_size_t) grub_file_size (file) > grub_os_area_size)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x > 0x%x)",
+ (grub_size_t) grub_file_size (file), grub_os_area_size);
+ 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/i386/pc/aout_normal.c b/loader/i386/pc/aout_normal.c
new file mode 100755
index 0000000..b90e3af
--- /dev/null
+++ b/loader/i386/pc/aout_normal.c
@@ -0,0 +1,44 @@
+/* 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/machine/loader.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.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");
+}
--
Bean
- [PATCH] a.out kernel loader,
Bean <=
- Re: [PATCH] a.out kernel loader, Robert Millan, 2008/01/27
- Re: [PATCH] a.out kernel loader, Bean, 2008/01/27
- Re: [PATCH] a.out kernel loader, Robert Millan, 2008/01/27
- Re: [PATCH] a.out kernel loader, Bean, 2008/01/27
- Re: [PATCH] a.out kernel loader, Robert Millan, 2008/01/28
- Re: [PATCH] a.out kernel loader, Bean, 2008/01/28
- Re: [PATCH] a.out kernel loader, walt, 2008/01/28
- Re: [PATCH] a.out kernel loader, Bean, 2008/01/28
- Re: [PATCH] a.out kernel loader, walt, 2008/01/28
- Re: [PATCH] a.out kernel loader, Bean, 2008/01/29