From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1Hztnf-0004xw-Q6 for mharc-grub-devel@gnu.org; Sun, 17 Jun 2007 08:24:11 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Hztnc-0004xr-Pr for grub-devel@gnu.org; Sun, 17 Jun 2007 08:24:08 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Hztnb-0004xf-BC for grub-devel@gnu.org; Sun, 17 Jun 2007 08:24:07 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Hztnb-0004xc-6E for grub-devel@gnu.org; Sun, 17 Jun 2007 08:24:07 -0400 Received: from ug-out-1314.google.com ([66.249.92.173]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Hztna-00077t-Nn for grub-devel@gnu.org; Sun, 17 Jun 2007 08:24:07 -0400 Received: by ug-out-1314.google.com with SMTP id 34so459622ugf for ; Sun, 17 Jun 2007 05:24:05 -0700 (PDT) DKIM-Signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:user-agent:mime-version:to:subject:content-type; b=hSj/S3Noi8lyk5a0m6Jive49Neifk1pxr+T7ROFz9DvY/ckDY+j1/Y7g0P/9yxoRMJzAdhFg7oIN0qHWiYfbXFx/uMKwGnuKODNUp3yW+wsD1NksoDBl6bKM/wvF29QEiKC21HbGhpuLoBKFvbdp8kP13/HOCHn+bZ3Wmi/D7SM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:user-agent:mime-version:to:subject:content-type; b=n7e60njz326XsbYAQf7aXIie4/fpnk4ag/PnWUFmAqOzdtOKjoVZs1buJgYCWXXXnUH96BGGQoK58kF8t7A8V6riRccP7jCn9UAaLLwJob2zC5AAKCnFdkZRjzO0vMHGoiPFSx0it0CZ9Xw/Mm9TrRCs8zPQmz4GI1cJBBoQGnc= Received: by 10.67.20.3 with SMTP id x3mr4231033ugi.1182083045437; Sun, 17 Jun 2007 05:24:05 -0700 (PDT) Received: from ?87.103.180.35? ( [87.103.180.35]) by mx.google.com with ESMTP id p56sm4128953ugp.2007.06.17.05.24.03 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 17 Jun 2007 05:24:04 -0700 (PDT) Message-ID: <467527E0.1020008@gmail.com> Date: Sun, 17 Jun 2007 19:24:00 +0700 From: Mikhail Vorozhtsov User-Agent: Mozilla-Thunderbird 2.0.0.0 (X11/20070601) MIME-Version: 1.0 To: The development of GRUB2 Content-Type: multipart/mixed; boundary="------------010002070503080802070805" X-detected-kernel: Linux 2.4-2.6 (Google crawlbot) Subject: Self multiboot patch X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Jun 2007 12:24:09 -0000 This is a multi-part message in MIME format. --------------010002070503080802070805 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Hi. Here is a patch for booting GRUB via itself with multiboot module. Tested on [http://grub.enbug.org/TestingOnX86]-alike floppy image and QEMU. BTW. When I'm trying to add some code/data before/in multiboot_entry in startup.S, GRUB hangs with "Loading kernel" message (even if it booted not via multiboot). How can I avoid it? It would be nice to print some message about invalid magic value, for example. But I just cannot add the code. --------------010002070503080802070805 Content-Type: text/x-diff; name="mb.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mb.patch" diff -ru grub2.orig/include/grub/i386/pc/loader.h grub2.multiboot/include/grub/i386/pc/loader.h --- grub2.orig/include/grub/i386/pc/loader.h 2004-09-12 19:20:52.000000000 +0700 +++ grub2.multiboot/include/grub/i386/pc/loader.h 2007-06-17 18:31:53.000000000 +0700 @@ -28,11 +28,17 @@ extern char *EXPORT_VAR(grub_linux_tmp_addr); extern char *EXPORT_VAR(grub_linux_real_addr); +/* Multiboot loader needs to know boot device. */ +extern grub_uint32_t EXPORT_VAR(grub_boot_drive); +extern grub_int32_t EXPORT_VAR(grub_install_dos_part); +extern grub_int32_t EXPORT_VAR(grub_install_bsd_part); + void EXPORT_FUNC(grub_linux_boot_zimage) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_linux_boot_bzimage) (void) __attribute__ ((noreturn)); /* This is an asm part of the chainloader. */ -void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) + __attribute__ ((noreturn)); /* The asm part of the multiboot loader. */ void EXPORT_FUNC(grub_multiboot_real_boot) (grub_addr_t entry, diff -ru grub2.orig/loader/i386/pc/multiboot.c grub2.multiboot/loader/i386/pc/multiboot.c --- grub2.orig/loader/i386/pc/multiboot.c 2006-06-04 22:56:54.000000000 +0700 +++ grub2.multiboot/loader/i386/pc/multiboot.c 2007-06-17 19:02:10.000000000 +0700 @@ -22,8 +22,6 @@ * FIXME: The following features from the Multiboot specification still * need to be implemented: * - VBE support - * - a.out support - * - boot device * - symbol table * - memory map * - drives table @@ -236,6 +234,75 @@ return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class"); } +/* Load with a.out kludge. */ +static grub_err_t +grub_multiboot_load_raw (grub_file_t file, grub_off_t header_offset, + const struct grub_multiboot_header *header) +{ + grub_off_t file_size = grub_file_size (file); + grub_off_t load_offset = header_offset + - (header->header_addr - header->load_addr); + grub_uint32_t load_end_addr = header->load_end_addr; + grub_uint32_t bss_end_addr = header->bss_end_addr; + grub_uint32_t load_size, total_size; + + if (header->header_addr < header->load_addr) + return grub_error (GRUB_ERR_BAD_OS, "Header precedes code"); + + if (header_offset < (header->header_addr - header->load_addr) + || load_offset > file_size) + return grub_error (GRUB_ERR_BAD_OS, "Code and data go out of file"); + + if (load_end_addr == 0) + { + if (file_size - load_offset > 0xFFFFFFFF) + return grub_error (GRUB_ERR_BAD_OS, "Code and data size is too big"); + load_size = file_size - load_offset; + load_end_addr = header->load_addr + load_size; + } + else + load_size = load_end_addr - header->load_addr; + + if (load_end_addr < header->load_addr) + return grub_error (GRUB_ERR_BAD_OS, "Code and data size is negative"); + + if (-(grub_uint64_t) load_size <= load_offset + || load_offset + load_size > file_size) + return grub_error (GRUB_ERR_BAD_OS, "Code and data go out of file"); + + if (header->entry_addr < header->load_addr + || header->entry_addr >= load_end_addr) + return grub_error (GRUB_ERR_BAD_OS, + "Entry point is outside of code and data area"); + + if (bss_end_addr == 0) + bss_end_addr = load_end_addr; + + if (bss_end_addr < load_end_addr) + return grub_error (GRUB_ERR_BAD_OS, "BSS size is negative"); + + total_size = load_size + (bss_end_addr - load_end_addr); + + if (-load_size <= (bss_end_addr - load_end_addr) + || header->load_addr < grub_os_area_addr + || -total_size <= header->load_addr + || (header->load_addr + total_size) + > (grub_os_area_addr + grub_os_area_size)) + return grub_error (GRUB_ERR_BAD_OS, + "Kernel doesn't fit in memory reserved for the OS"); + + if (grub_file_seek (file, load_offset) == (grub_off_t) -1 + || grub_file_read (file, (char *) header->load_addr, load_size) + != (grub_ssize_t) load_size) + return grub_error (GRUB_ERR_READ_ERROR, "Cannot read code and data"); + + grub_memset ((void *) load_end_addr, 0, total_size - load_size); + + entry = header->entry_addr; + + return GRUB_ERR_NONE; +} + void grub_rescue_cmd_multiboot (int argc, char *argv[]) { @@ -293,7 +360,13 @@ goto fail; } - if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) + if (header->flags & GRUB_MB_AOUT_KLUDGE) + { + if (grub_multiboot_load_raw (file, (char *) header - buffer, header) + != GRUB_ERR_NONE) + goto fail; + } + else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) goto fail; mbi = grub_malloc (sizeof (struct grub_multiboot_info)); @@ -325,6 +398,15 @@ mbi->flags |= GRUB_MB_INFO_CMDLINE; mbi->cmdline = (grub_uint32_t) cmdline; + mbi->flags |= GRUB_MB_INFO_BOOTDEV; + mbi->boot_device = (grub_boot_drive << 24); + if (grub_install_dos_part >= 0) + mbi->boot_device |= 0x00FFFF | (grub_install_dos_part << 16); + else if (grub_install_bsd_part >= 0) + mbi->boot_device |= 0xFF00FF | (grub_install_bsd_part << 8); + else + mbi->boot_device |= 0xFFFFFF; + mbi->flags |= GRUB_MB_INFO_BOOT_LOADER_NAME; mbi->boot_loader_name = (grub_uint32_t) grub_strdup (PACKAGE_STRING); --------------010002070503080802070805--