Showing posts with label grub. Show all posts
Showing posts with label grub. Show all posts

Friday, October 2, 2009

To Compile GRUB with GFXBOOT and SLIC patch

I use GRUB 0.97 to boot multiple operating systems on my computer. While I was searching Yahoo! China, I found a patch called loadslic.patch. I wanted to use MinGW to compile GRUB with GFXBOOT and SLIC patch. But I received an error saying “GRUB requires a working absolute objcopy; upgrade your binutils.” So I switched to Linux and compiled GRUB. Below I show how I did it.




  1. I prepared my compiler environment by installing GCC 3.4. Then I downloaded the following files:





  2. Unpack the GRUB 0.97 source.


    tar xzvf grub-0.97.tar.gz
    cd grub-0.97


  3. Apply various patches.


    patch -p1 -l < ../040_all_grub-0.96-nxstack.patch
    patch -p1 -l < ../05-grub-0.97-initrdaddr.diff
    patch -p1 -l < ../i2o.patch
    patch -p1 -l < ../intelmac.patch
    patch -p1 -l < ../more-raid.patch
    patch -p1 -l < ../special-devices.patch
    patch -p1 -l < ../grub-0.97-pure64-1.patch


  4. Apply the GFXBOOT patch.


    cd ..
    tar xjvf gfxboot-4.1.19.tar.bz2
    cd ../grub-0.97
    patch -p0 -l < ../gfxboot-4.1.19/patches/grub-0.97.diff



  5. Apply the following patch which adds a feature to load an OEM SLIC table for Windows activation. I found this patch through Yahoo! China. Save it as loadslic.patch.


    --- grub-0.97/stage2/builtins.c 2005-02-16 05:58:23.000000000 +0800
    +++ grub-0.97.new/stage2/builtins.c 2009-08-11 22:37:26.000000000 +0800
    @@ -48,6 +48,7 @@
    #ifdef USE_MD5_PASSWORDS
    # include <md5.h>
    #endif
    +#include <defs.h>

    /* The type of kernel loaded. */
    kernel_t kernel_type;
    @@ -397,6 +398,180 @@
    "Print the contents of the file FILE."
    };

    +
    +/*
    + * Add by yangrz, 2009-08-11
    + */
    +#define SLIC_LENGTH 0x176
    +
    +typedef struct acpi_rsdp {
    + char signature[8]; /* RSDP signature "RSD PTR" */
    + u_char checksum; /* checksum of the first 20 bytes */
    + char oem_id[6]; /* OEM ID, "LXBIOS" */
    + u_char revision; /* 0 for APCI 1.0, 2 for ACPI 2.0 */
    + u_int rsdt_address; /* physical address of RSDT */
    + u_int length; /* total length of RSDP (including extended part) */
    + unsigned long long xsdt_address; /* physical address of XSDT */
    + u_char ext_checksum; /* chechsum of whole table */
    + u_char reserved[3];
    +} __attribute__((packed)) acpi_rsdp_t;
    +
    +typedef struct acpi_table_header /* ACPI common table header */
    +{
    + char signature [4]; /* ACPI signature (4 ASCII characters) */\
    + u_int length; /* Length of table, in bytes, including header */\
    + u_char revision; /* ACPI Specification minor version # */\
    + u_char checksum; /* To make sum of entire table == 0 */\
    + char oem_id [6]; /* OEM identification */\
    + char oem_table_id [8]; /* OEM table identification */\
    + u_int oem_revision; /* OEM revision number */\
    + char asl_compiler_id [4]; /* ASL compiler vendor ID */\
    + u_int asl_compiler_revision; /* ASL compiler revision number */
    +} __attribute__ ((packed)) acpi_header_t;
    +
    +/* RSDT */
    +typedef struct acpi_rsdt {
    + struct acpi_table_header header;
    + /* MCONFIG, HPET, FADT, SRAT, SLIT, MADT(APIC), SSDT, SSDTX, and SSDT for CPU pstate*/
    + u_int entry[1];
    +} __attribute__ ((packed)) acpi_rsdt_t;
    +
    +static u_char
    +acpi_checksum(u_char *table, u_int length)
    +{
    + u_char ret=0;
    + while (length--)
    + {
    + ret += *table;
    + table++;
    + }
    + return -ret;
    +}
    +
    +static acpi_rsdp_t *
    +acpi_find_rsdp(void)
    +{
    + acpi_rsdp_t *rsdp;
    +
    + //TODO: also search EBDA
    + for ( rsdp = (acpi_rsdp_t *)(RAW_ADDR(0xe0000));
    + rsdp < (acpi_rsdp_t *)(RAW_ADDR(0xfffff - 0x16));
    + rsdp = (acpi_rsdp_t *)((unsigned char *)rsdp + 16) )
    + {
    + if ( memcmp(rsdp->signature, "RSD PTR ", 8) == 0
    + && acpi_checksum((u_char *)rsdp, rsdp->length) == 0 )
    + {
    + return rsdp;
    + }
    + }
    +
    + return NULL;
    +}
    +
    +static acpi_header_t *
    +acpi_find_slic(acpi_rsdp_t *rsdp)
    +{
    + int i;
    + acpi_rsdt_t *rsdt;
    + acpi_header_t *slic;
    +
    + rsdt = (acpi_rsdt_t *)(rsdp->rsdt_address);
    + for ( i = 0;
    + i < (rsdt->header.length - sizeof(acpi_header_t))/4;
    + i++)
    + {
    + slic = (acpi_header_t *)(RAW_ADDR(rsdt->entry[i]));
    + if ( slic != NULL && memcmp(slic->signature, "SLIC", 4) == 0 )
    + {
    + return slic;
    + }
    + }
    +
    + return NULL;
    +}
    +
    +/*
    + * return value : success 0
    + * fail 1
    + */
    +static int
    +acpi_copy_memory(char *target, char *source, int len)
    +{
    + int i;
    +
    + for ( i = 0; i < len; i++ )
    + {
    + target[i] = source[i];
    + }
    + /* check data */
    + if ( memcmp(target, source, len) != 0 )
    + {
    + printf("modify memory fail: maybe address 0x%x write protect\n",
    + target);
    + return 1;
    + }
    + return 0;
    +}
    +
    +static int
    +acpi_add_slic(char *arg, int flags)
    +{
    + char *file = arg;
    + acpi_rsdp_t *rsdp;
    + acpi_header_t *slic;
    + char buf[SLIC_LENGTH];
    +
    + rsdp = acpi_find_rsdp();
    + if ( rsdp == NULL )
    + {
    + grub_printf("can not find rsdp\n");
    + return 1;
    + }
    + slic = acpi_find_slic(rsdp);
    + if ( slic == NULL )
    + {
    + grub_printf("can not find slic\n");
    + return 1;
    + }
    +
    + if ( slic->length != SLIC_LENGTH )
    + {
    + return 1;
    + }
    +
    + if ( !grub_open(file) )
    + {
    + printf("grub open %s fail\n", file);
    + return 1;
    + }
    + if ( grub_read (buf, SLIC_LENGTH) != SLIC_LENGTH )
    + {
    + printf("grub read fail\n");
    + grub_close();
    + return 1;
    + }
    + grub_close();
    +
    + if ( acpi_copy_memory((char *)slic, buf, SLIC_LENGTH) )
    + {
    + errnum = ERR_WONT_FIT;
    + return 1;
    + }
    +
    + errnum = ERR_NONE;
    + return 0;
    +}
    +
    +static struct builtin builtin_load_slic =
    +{
    + "loadslic",
    + acpi_add_slic,
    + BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
    + "loadslic FILE",
    + "load acpi slic form file"
    +};
    +/* end yangrz add */
    +

    /* chainloader */
    static int
    @@ -4835,6 +5010,8 @@
    &builtin_install,
    &builtin_ioprobe,
    &builtin_kernel,
    + /* Add by yangrz, 2009-08-08 */
    + &builtin_load_slic,
    &builtin_lock,
    &builtin_makeactive,
    &builtin_map,

    Apply this patch as follows:


    patch -p1 -l < ../loadslic.patch


  6. Compile GRUB.


    ./configure --prefix=/usr
    make
    make install

    The following files are installed:


    /usr/bin/mbchk
    /usr/info/multiboot.info
    /usr/lib/grub/i386-pc
    /usr/man/man1/mbchk.1
    /usr/man/man8/grub.8
    /usr/man/man8/grub-install.8
    /usr/man/man8/grub-md5-crypt.8
    /usr/man/man8/grub-terminfo.8
    /usr/sbin/grub
    /usr/sbin/grub-install
    /usr/sbin/grub-md5-crypt
    /usr/sbin/grub-set-default
    /usr/sbin/grub-terminfo

    To get my GRUB binaries, read this post.





Using GRUB to load SLIC


Note that the SLIC patch for GRUB only works on computers with BIOS that actually contain a SLIC table. To load SLIC with the patched GRUB, use the loadslic command at the GRUB prompt or in the menu.lst configuration file. For example, a menu.lst may contain a section like the following:


# GRUB Boot Menu
hiddenmenu

# By default, boot Windows Vista
default 0
timeout 0

# Boot Windows Vista Home Premium
title Windows Vista Home Premium
unhide (hd0,0)
hide (hd0,1)
loadslic (hd0,5)/boot/grub/slic.bin
chainloader (hd0,0)+1


For old computers with non-SLP BIOS, read this post.

Tuesday, September 29, 2009

GRUB: Booting and Activating Windows Vista/7

This post describes a way to activate Windows Vista/7 with Grub and SLIC loader. In order to successfully activate Windows Vista/7, you essentially need the following 3 things.



  • OEM SLIC code

    Every SLIC code is 374 bytes. It can be extracted from the BIOS by using the SLIC Dump ToolKit on a PC running legitimate Windows.
  • OEM Certificate (*.xrm-ms) that matches with the corresponding SLIC code
  • Valid 25-digit Windows key


Once these 3 things are obtained, you need a program to insert the SLIC code into memory to emulate OEM BIOS. I found an executable file called wow.exe whose job is to insert a SLIC code into BIOS. Also, GRUB.EXE is needed to find Windows partition and to boot Windows.



Because wow.exe and grub.exe are DOS executables, DOS should be booted first and run wow.exe and grub.exe in turn. grub.exe will chain-load Windows bootmgr, and then Windows will start. FreeDOS is preferred to MS-DOS because it works better with GRUB. Download a floppy image containing FreeDOS kernel and FreeCOM command processor below.




Inserting SLIC data into wow.exe with XVI32


wow.exe has a SLIC table embedded in itself beginning at $A58. Start XVI32 and open wow.exe. Start another XVI32 and open a SLIC table which should be 374 bytes.

With the XVI32 window showing a SLIC.table, open the Edit menu, click the beginning of file, select Block mark from the Edit menu, go to the end of file and select Block mark again. Open the Edit menu, open the Clipboard submenu and select Copy.

With the XVI32 window showing wow.exe, go to $A58, open the Edit window, select Block <n> chars..., enter 374 and click OK. Select Block delete from the Edit menu. Then, open the Edit menu, open the Clipboard submenu, and choose Paste. Go to $A38 and select Overwrite string... and enter the new 14-character OEM identifier which should match the string starting at $A62. Save the file wow.exe.


Open the FreeDOS floppy image with WinImage. Insert wow.exe into the floppy image. Create a batch file called AUTOEXEC.BAT with a text editor and put the following contents in it.


@ECHO OFF
WOW
GRUB

Save the file AUTOEXEC.BAT and insert in into FreeDOS floppy image.


Assuming that Windows 7 is installed, open a Command Prompt as administrator. Create an arbitrary file in C:\Boot, for example, with the filename win7. This file will be used to find the Windows partition (useful in mutiple-Windows environment).


copy nul C:\Boot\win7

Then, create a new text file MENU.LST with the following contents:


timeout 0
default 0
fallback 0
hiddenmenu

title Windows 7
find --set-root /boot/win7
chainloader /bootmgr

Save the file as MENU.LST and insert it into the floppy image with WinImage. Save the floppy image and quit WinImage.


With GRUB installed into MBR, type the following GRUB commands at boot time to boot Windows with BIOS-inserted SLIC code. Assume memdisk and freedos.flp is in the (hd0,3) partition.


kernel (hd0,3)/boot/grub/memdisk
initrd (hd0,3)/boot/grub/freedos.flp


Activating Windows


Once Windows has started, find the OEM certificate (*.xrm-ms) and 25-character Windows key that match the SLIC table just loaded into BIOS. Open a command prompt as administrator and type the following commands to activate Windows:


slmgr -ilc oemcert.xrm-ms
slmgr -ipk XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

Hopefully, Windows will be activated.

Thursday, September 17, 2009

Using GRUB To Boot Windows XP with a Floppy Image

I had trouble booting Windows XP installed in a logical partition. I guess the boot sector of the logical partition was damaged. I had to boot this installation of Windows XP by chainloading from another Windows XP on a primary partition. But without another Windows XP partition, I can boot Windows XP from a floppy diskette although floppy diskettes are not in much use nowadays.



I created a Windows XP boot floppy by following instruciton on this article on the Microsoft site. Then, I booted Linux and made an image file of the boot floppy.


dd if=/dev/fd0 of=ntboot.bin bs=512

Save the image file somewhere in your hard drive. Then, when you start the computer, use the following GRUB commands to boot Windows XP.


kernel (hd0,6)/boot/grub/memdisk bigraw
initrd (hd0,6)/boot/grub/ntboot.bin

memdisk is a part of the syslinux package.


Here's my XP boot image to be used with GRUB or syslinux: ntboot.bin. Before actually using it, make sure to edit BOOT.INI in it.

About This Blog

KBlog logo This blog seeks to provide a collection of interesting pictures found on the Web. Thanks for visiting the blog and posting your comments.

© Contents by KBlog

© Blogger template by Emporium Digital 2008

Followers

Total Pageviews

Powered By Blogger