From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1MXkPp-0000LD-OD for mharc-grub-devel@gnu.org; Sun, 02 Aug 2009 19:24:33 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MXkPn-0000L8-Ba for grub-devel@gnu.org; Sun, 02 Aug 2009 19:24:31 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MXkPi-0000Jr-GX for grub-devel@gnu.org; Sun, 02 Aug 2009 19:24:30 -0400 Received: from [199.232.76.173] (port=35817 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MXkPi-0000Jg-Dx for grub-devel@gnu.org; Sun, 02 Aug 2009 19:24:26 -0400 Received: from xvm-190-8.ghst.net ([217.70.190.8]:56020 helo=aybabtu.com) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MXkPh-00050l-Tj for grub-devel@gnu.org; Sun, 02 Aug 2009 19:24:26 -0400 Received: from [192.168.10.10] (helo=thorin) by aybabtu.com with esmtp (Exim 4.69) (envelope-from ) id 1MXkPf-0003ln-F6 for grub-devel@gnu.org; Mon, 03 Aug 2009 01:24:23 +0200 Received: from rmh by thorin with local (Exim 4.69) (envelope-from ) id 1MXkPe-00064X-Ic for grub-devel@gnu.org; Mon, 03 Aug 2009 01:24:22 +0200 Date: Mon, 3 Aug 2009 01:24:22 +0200 From: Robert Millan To: grub-devel@gnu.org Message-ID: <20090802232422.GA23320@thorin> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="3MwIy2ne0vdjdPXF" Content-Disposition: inline Organization: free as in freedom X-Message-Flag: Worried about Outlook viruses? Switch to Thunderbird! www.mozilla.com/thunderbird X-Debbugs-No-Ack: true User-Agent: Mutt/1.5.18 (2008-05-17) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Subject: [PATCH] ntldr support 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, 02 Aug 2009 23:24:32 -0000 --3MwIy2ne0vdjdPXF Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, This patch implements a loader for NTLDR boot semantics (which are the same in BootMGR, hence both are supported). It still needs some cleanup in chainloader.c before it can be merged [1], but I submit it so that others can test it and report if it works for them. [1] ideally, we should be able to share most code with the chainloader -- Robert Millan The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and how) you may access your data; but nobody's threatening your freedom: we still allow you to remove your data and not access it at all." --3MwIy2ne0vdjdPXF Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="ntldr.diff" Index: kern/i386/pc/startup.S =================================================================== --- kern/i386/pc/startup.S (revision 2465) +++ kern/i386/pc/startup.S (working copy) @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 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 @@ -576,6 +576,35 @@ ljmp $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR .code32 +/* + * void grub_ntldr_real_boot (grub_uint8_t *boot_file, int drive, grub_uint32_t boot_file_size) + * + * This starts NTLDR. + * + * Register allocations for parameters: + * %eax *boot_file + * %edx drive + * %ecx boot_file_size + */ + +ntldr_tmp_stack: + .long 0 +FUNCTION(grub_ntldr_real_boot) + /* Copy NTLDR from heap to its link address. */ + movl %eax, %esi + movl $GRUB_MEMORY_MACHINE_NTLDR_ADDR, %edi + cld + rep + movsb + + /* Relocation may have taken over our stack, so use this one to + hold our return address. */ + movl $(ntldr_tmp_stack + 4), %esp + call prot_to_real + .code16 + ljmp $(GRUB_MEMORY_MACHINE_NTLDR_ADDR >> 4), $0x0 + .code32 + #include "../loader.S" /* Index: include/grub/i386/pc/console.h =================================================================== --- include/grub/i386/pc/console.h (revision 2465) +++ include/grub/i386/pc/console.h (working copy) @@ -51,7 +51,7 @@ void grub_console_init (void); /* Finish the console system. */ -void grub_console_fini (void); +void EXPORT_FUNC(grub_console_fini) (void); #endif Index: include/grub/i386/pc/loader.h =================================================================== --- include/grub/i386/pc/loader.h (revision 2465) +++ include/grub/i386/pc/loader.h (working copy) @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004,2007 Free Software Foundation, Inc. + * Copyright (C) 2002,2003,2004,2007,2009 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 @@ -25,4 +25,7 @@ /* 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_ntldr_real_boot) (grub_uint8_t *boot_file, int drive, + grub_uint32_t boot_file_size) __attribute__ ((noreturn)); + #endif /* ! GRUB_LOADER_MACHINE_HEADER */ Index: include/grub/i386/pc/memory.h =================================================================== --- include/grub/i386/pc/memory.h (revision 2465) +++ include/grub/i386/pc/memory.h (working copy) @@ -1,7 +1,7 @@ /* memory.h - describe the memory map */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 2002,2007,2008,2009 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 @@ -63,6 +63,9 @@ /* The address where another boot loader is loaded. */ #define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR 0x7c00 +/* The address where NTLDR is loaded. */ +#define GRUB_MEMORY_MACHINE_NTLDR_ADDR 0x20000 + /* The flag for protected mode. */ #define GRUB_MEMORY_MACHINE_CR0_PE_ON 0x1 Index: loader/i386/pc/chainloader.c =================================================================== --- loader/i386/pc/chainloader.c (revision 2465) +++ loader/i386/pc/chainloader.c (working copy) @@ -1,7 +1,7 @@ /* chainloader.c - boot another boot loader */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2004,2007 Free Software Foundation, Inc. + * Copyright (C) 2002,2004,2007,2009 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 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -36,12 +37,17 @@ static grub_dl_t my_mod; static int boot_drive; static void *boot_part_addr; +static grub_uint8_t *boot_file; +static grub_off_t boot_file_size; static grub_err_t grub_chainloader_boot (void) { - grub_chainloader_real_boot (boot_drive, boot_part_addr); + /* NTLDR expects console in text mode. */ + grub_console_fini (); + grub_ntldr_real_boot (boot_file, boot_drive, (grub_uint32_t) boot_file_size); + /* Never reach here. */ return GRUB_ERR_NONE; } @@ -68,24 +74,11 @@ if (! file) goto fail; - /* Read the first block. */ - if (grub_file_read (file, (void *) 0x7C00, GRUB_DISK_SECTOR_SIZE) - != GRUB_DISK_SECTOR_SIZE) - { - if (grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_BAD_OS, "too small"); + boot_file_size = file->size; - goto fail; - } + boot_file = grub_malloc (boot_file_size); - /* Check the signature. */ - signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2)); - if (signature != grub_le_to_cpu16 (0xaa55) - && ! (flags & GRUB_CHAINLOADER_FORCE)) - { - grub_error (GRUB_ERR_BAD_OS, "invalid signature"); - goto fail; - } + grub_file_read (file, boot_file, boot_file_size); grub_file_close (file); @@ -95,11 +88,26 @@ if (dev && dev->disk && dev->disk->partition) { grub_disk_read (dev->disk, dev->disk->partition->offset, 446, 64, - (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR); + GRUB_MEMORY_MACHINE_PART_TABLE_ADDR); part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR + (dev->disk->partition->index << 4)); } + if (! dev) + grub_fatal ("boo"); + + /* Read the first block. */ + grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, (void *) 0x7C00); + + /* Check the signature. */ + signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2)); + if (signature != grub_le_to_cpu16 (0xaa55) + && ! (flags & GRUB_CHAINLOADER_FORCE)) + { + grub_error (GRUB_ERR_BAD_OS, "invalid signature"); + goto fail; + } + if (dev) grub_device_close (dev); @@ -109,7 +117,7 @@ boot_drive = drive; boot_part_addr = part_addr; - grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1); + grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); return; fail: @@ -145,8 +153,8 @@ GRUB_MOD_INIT(chainloader) { - cmd = grub_register_command ("chainloader", grub_cmd_chainloader, - 0, "load another boot loader"); + cmd = grub_register_command ("ntldr", grub_cmd_chainloader, + 0, "load NTLDR"); my_mod = mod; } --3MwIy2ne0vdjdPXF--