grub-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] ntldr support


From: Robert Millan
Subject: Re: [PATCH] ntldr support
Date: Tue, 4 Aug 2009 21:27:15 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

After thinking a bit about this, I don't think we want this command in
its current form.

The problem is it is misleading.  It leads the user to think it can load
ntldr as a standalone file, but in fact it is reading the PBR behind the
scenes.

If we want this feature at all, I think it should be an option in the
chainloader rather than a standalone command.  It's almost the same as
the chainloader really, the only difference is that ntldr is load after
PBR by GRUB instead of by PBR itself.

But I'm not even sure it makes sense to support this at all.  Perhaps if
people who are interested in it explain the use case and how did they got
there, I would change my mind about it.

On Mon, Aug 03, 2009 at 01:24:22AM +0200, Robert Millan wrote:
> 
> 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."

> 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 <grub/loader.h>
>  #include <grub/machine/loader.h>
>  #include <grub/machine/chainloader.h>
> +#include <grub/machine/console.h>
>  #include <grub/file.h>
>  #include <grub/err.h>
>  #include <grub/device.h>
> @@ -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;
>  }
>  


-- 
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."




reply via email to

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