Module Name: src
Committed By: jakllsch
Date: Thu Jan 6 01:08:49 UTC 2011
Modified Files:
src/distrib/sets/lists/base: md.amd64 md.i386
src/sbin/gpt: Makefile gpt.c gpt.h
src/sys/arch/i386/stand/bootxx: boot1.c bootxx.S pbr.S
src/sys/arch/i386/stand/mbr: Makefile
src/sys/sys: bootblock.h
Added Files:
src/sbin/gpt: biosboot.c
src/sys/arch/i386/stand/mbr: gpt.S
src/sys/arch/i386/stand/mbr/mbr_gpt: Makefile
src/sys/arch/i386/stand/mbr/mbr_gpt_com0: Makefile
Log Message:
Support booting from GPT-partioned disks on PC-BIOS-compatible systems.
Much of the work in this commit was done by Mike Volokhov during GSoC 2009.
To generate a diff of this commit:
cvs rdiff -u -r1.106 -r1.107 src/distrib/sets/lists/base/md.amd64
cvs rdiff -u -r1.137 -r1.138 src/distrib/sets/lists/base/md.i386
cvs rdiff -u -r1.3 -r1.4 src/sbin/gpt/Makefile
cvs rdiff -u -r0 -r1.1 src/sbin/gpt/biosboot.c
cvs rdiff -u -r1.12 -r1.13 src/sbin/gpt/gpt.c
cvs rdiff -u -r1.4 -r1.5 src/sbin/gpt/gpt.h
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/i386/stand/bootxx/boot1.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/i386/stand/bootxx/bootxx.S
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/i386/stand/bootxx/pbr.S
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/i386/stand/mbr/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/arch/i386/stand/mbr/gpt.S
cvs rdiff -u -r0 -r1.1 src/sys/arch/i386/stand/mbr/mbr_gpt/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/arch/i386/stand/mbr/mbr_gpt_com0/Makefile
cvs rdiff -u -r1.51 -r1.52 src/sys/sys/bootblock.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/base/md.amd64
diff -u src/distrib/sets/lists/base/md.amd64:1.106 src/distrib/sets/lists/base/md.amd64:1.107
--- src/distrib/sets/lists/base/md.amd64:1.106 Thu Dec 16 18:42:49 2010
+++ src/distrib/sets/lists/base/md.amd64 Thu Jan 6 01:08:48 2011
@@ -1,4 +1,4 @@
-# $NetBSD: md.amd64,v 1.106 2010/12/16 18:42:49 christos Exp $
+# $NetBSD: md.amd64,v 1.107 2011/01/06 01:08:48 jakllsch Exp $
./dev/lms0 base-obsolete obsolete
./dev/mms0 base-obsolete obsolete
./libexec/ld.elf_so-i386 base-sys-shlib compat,pic
@@ -298,6 +298,8 @@
./usr/mdec/mbr_com0 base-sysutil-bin
./usr/mdec/mbr_com0_9600 base-sysutil-bin
./usr/mdec/mbr_ext base-sysutil-bin
+./usr/mdec/mbr_gpt base-sysutil-bin
+./usr/mdec/mbr_gpt_com0 base-sysutil-bin
./usr/mdec/netboot_3c509.rom base-sysutil-bin
./usr/mdec/netboot_3c590.rom base-sysutil-bin
./usr/mdec/netboot_3c90xb.rom base-sysutil-bin
Index: src/distrib/sets/lists/base/md.i386
diff -u src/distrib/sets/lists/base/md.i386:1.137 src/distrib/sets/lists/base/md.i386:1.138
--- src/distrib/sets/lists/base/md.i386:1.137 Sat Sep 11 13:06:36 2010
+++ src/distrib/sets/lists/base/md.i386 Thu Jan 6 01:08:48 2011
@@ -1,4 +1,4 @@
-# $NetBSD: md.i386,v 1.137 2010/09/11 13:06:36 tsutsui Exp $
+# $NetBSD: md.i386,v 1.138 2011/01/06 01:08:48 jakllsch Exp $
./dev/lms0 base-obsolete obsolete
./dev/mms0 base-obsolete obsolete
./dev/pms0 base-obsolete obsolete
@@ -79,6 +79,8 @@
./usr/mdec/mbr_com0 base-sysutil-bin
./usr/mdec/mbr_com0_9600 base-sysutil-bin
./usr/mdec/mbr_ext base-sysutil-bin
+./usr/mdec/mbr_gpt base-sysutil-bin
+./usr/mdec/mbr_gpt_com0 base-sysutil-bin
./usr/mdec/netboot_3c509.rom base-sysutil-bin
./usr/mdec/netboot_3c590.rom base-sysutil-bin
./usr/mdec/netboot_3c90xb.rom base-sysutil-bin
Index: src/sbin/gpt/Makefile
diff -u src/sbin/gpt/Makefile:1.3 src/sbin/gpt/Makefile:1.4
--- src/sbin/gpt/Makefile:1.3 Sat Apr 11 07:58:12 2009
+++ src/sbin/gpt/Makefile Thu Jan 6 01:08:48 2011
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.3 2009/04/11 07:58:12 lukem Exp $
+# $NetBSD: Makefile,v 1.4 2011/01/06 01:08:48 jakllsch Exp $
# $FreeBSD: src/sbin/gpt/Makefile,v 1.7 2005/09/01 02:49:20 marcel Exp $
PROG= gpt
-SRCS= add.c create.c destroy.c gpt.c label.c map.c migrate.c recover.c \
- remove.c show.c
+SRCS= add.c biosboot.c create.c destroy.c gpt.c label.c map.c migrate.c \
+ recover.c remove.c show.c
MAN= gpt.8
LDADD+= -lprop -lutil
Index: src/sbin/gpt/gpt.c
diff -u src/sbin/gpt/gpt.c:1.12 src/sbin/gpt/gpt.c:1.13
--- src/sbin/gpt/gpt.c:1.12 Fri Apr 2 19:33:09 2010
+++ src/sbin/gpt/gpt.c Thu Jan 6 01:08:48 2011
@@ -31,7 +31,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/gpt.c,v 1.16 2006/07/07 02:44:23 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: gpt.c,v 1.12 2010/04/02 19:33:09 christos Exp $");
+__RCSID("$NetBSD: gpt.c,v 1.13 2011/01/06 01:08:48 jakllsch Exp $");
#endif
#include <sys/param.h>
@@ -756,6 +756,7 @@
const char *name;
} cmdsw[] = {
{ cmd_add, "add" },
+ { cmd_biosboot, "biosboot" },
{ cmd_create, "create" },
{ cmd_destroy, "destroy" },
{ NULL, "help" },
@@ -772,7 +773,7 @@
static void
usage(void)
{
- extern const char addmsg[], createmsg[], destroymsg[];
+ extern const char addmsg[], biosbootmsg[], createmsg[], destroymsg[];
extern const char labelmsg1[], labelmsg2[], labelmsg3[];
extern const char migratemsg[], recovermsg[], removemsg1[];
extern const char removemsg2[], showmsg[];
@@ -783,6 +784,7 @@
" %s %s\n"
" %s %s\n"
" %s %s\n"
+ " %s %s\n"
" %*s %s\n"
" %s %s\n"
" %s %s\n"
@@ -790,6 +792,7 @@
" %s %s\n"
" %s %s\n",
getprogname(), addmsg,
+ getprogname(), biosbootmsg,
getprogname(), createmsg,
getprogname(), destroymsg,
getprogname(), labelmsg1,
Index: src/sbin/gpt/gpt.h
diff -u src/sbin/gpt/gpt.h:1.4 src/sbin/gpt/gpt.h:1.5
--- src/sbin/gpt/gpt.h:1.4 Sat Feb 7 18:12:22 2009
+++ src/sbin/gpt/gpt.h Thu Jan 6 01:08:48 2011
@@ -67,7 +67,7 @@
};
struct mbr {
- uint16_t mbr_code[223];
+ uint8_t mbr_code[446];
struct mbr_part mbr_part[4];
uint16_t mbr_sig;
#define MBR_SIG 0xAA55
@@ -90,6 +90,7 @@
void utf8_to_utf16(const uint8_t *, uint16_t *, size_t);
int cmd_add(int, char *[]);
+int cmd_biosboot(int, char *[]);
int cmd_create(int, char *[]);
int cmd_destroy(int, char *[]);
int cmd_label(int, char *[]);
Index: src/sys/arch/i386/stand/bootxx/boot1.c
diff -u src/sys/arch/i386/stand/bootxx/boot1.c:1.19 src/sys/arch/i386/stand/bootxx/boot1.c:1.20
--- src/sys/arch/i386/stand/bootxx/boot1.c:1.19 Fri Jan 1 03:18:27 2010
+++ src/sys/arch/i386/stand/bootxx/boot1.c Thu Jan 6 01:08:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: boot1.c,v 1.19 2010/01/01 03:18:27 christos Exp $ */
+/* $NetBSD: boot1.c,v 1.20 2011/01/06 01:08:48 jakllsch Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: boot1.c,v 1.19 2010/01/01 03:18:27 christos Exp $");
+__RCSID("$NetBSD: boot1.c,v 1.20 2011/01/06 01:08:48 jakllsch Exp $");
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
@@ -44,11 +44,11 @@
#define XSTR(x) #x
#define STR(x) XSTR(x)
-static uint32_t bios_sector;
+static daddr_t bios_sector;
static struct biosdisk_ll d;
-const char *boot1(uint32_t, uint32_t *);
+const char *boot1(uint32_t, uint64_t *);
extern void putstr(const char *);
extern struct disklabel ptn_disklabel;
@@ -60,7 +60,7 @@
}
const char *
-boot1(uint32_t biosdev, uint32_t *sector)
+boot1(uint32_t biosdev, uint64_t *sector)
{
struct stat sb;
int fd;
Index: src/sys/arch/i386/stand/bootxx/bootxx.S
diff -u src/sys/arch/i386/stand/bootxx/bootxx.S:1.9 src/sys/arch/i386/stand/bootxx/bootxx.S:1.10
--- src/sys/arch/i386/stand/bootxx/bootxx.S:1.9 Mon Apr 28 20:23:25 2008
+++ src/sys/arch/i386/stand/bootxx/bootxx.S Thu Jan 6 01:08:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: bootxx.S,v 1.9 2008/04/28 20:23:25 martin Exp $ */
+/* $NetBSD: bootxx.S,v 1.10 2011/01/06 01:08:48 jakllsch Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
*
* On entry:
* %dl BIOS drive number
- * %esi Sector number of netbsd partition
+ * %edi:%esi Sector number of NetBSD partition
* %cs, %ds, %es, %ss All zero
* %sp near 0xfffc
*/
@@ -60,6 +60,7 @@
calll real_to_prot
.code32
+ push %edi
movl $_end, %ecx /* zero bss */
movl $__bss_start, %edi
subl %edi, %ecx
@@ -67,9 +68,11 @@
xor %eax, %eax
rep
stosl
+ pop %edi
- and $0xff, %edx
- push %esi /* save args for secondary bootstrap */
+ movzbl %dl, %edx
+ push %edi /* save args for secondary bootstrap */
+ push %esi
movl %esp, %esi /* address of sector number */
push %edx
push %esi /* args for boot1 */
@@ -84,7 +87,9 @@
pop %edx /* bios disk number */
pop %ebx /* expected partition start sector */
+ pop %ecx
movl $boot_params, %esi
+ orb $X86_BP_FLAGS_LBA64VALID, 4(%esi)
lcall $SECONDARY_LOAD_ADDRESS/16, $0
boot_fail:
Index: src/sys/arch/i386/stand/bootxx/pbr.S
diff -u src/sys/arch/i386/stand/bootxx/pbr.S:1.18 src/sys/arch/i386/stand/bootxx/pbr.S:1.19
--- src/sys/arch/i386/stand/bootxx/pbr.S:1.18 Sun Jan 2 02:01:58 2011
+++ src/sys/arch/i386/stand/bootxx/pbr.S Thu Jan 6 01:08:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pbr.S,v 1.18 2011/01/02 02:01:58 jakllsch Exp $ */
+/* $NetBSD: pbr.S,v 1.19 2011/01/06 01:08:48 jakllsch Exp $ */
/*-
* Copyright (c) 2003,2004 The NetBSD Foundation, Inc.
@@ -97,6 +97,8 @@
* sector we were loaded from (if we were loaded by NetBSD mbr code).
* In any case we have to re-read sector zero of the disk and hunt
* through the BIOS partition table for the NetBSD partition.
+ * However, if there's a magic number in %eax, then %ecx:%ebx
+ * contains the sector we were loaded from.
*/
.text
@@ -119,12 +121,20 @@
. = start + MBR_AFTERBPB /* skip BPB */
start0:
+#ifndef BOOT_FROM_FAT
+ movl %eax, %edi /* move %eax magic out of the way */
+#endif
xor %ax, %ax /* don't trust values of ds, es or ss */
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
mov $0xfffc, %sp
+#ifndef BOOT_FROM_FAT
+ cmpl $X86_MBR_GPT_MAGIC, %edi /* did mbr_gpt leave us a LBA? */
+ je boot_gpt
+#endif
+
/* A 'reset disk system' request is traditional here... */
push %dx /* some BIOS zap %dl here :-( */
int $0x13 /* ah == 0 from code above */
@@ -332,6 +342,7 @@
jnz error
movl %ebp, %esi /* %esi ptn base, %dl disk id */
+ movl lba_sector + 4, %edi /* %edi ptn base high */
jmp $0, $bootxx /* our %cs may not be zero */
/* Read disk using int13-extension parameter block */
@@ -355,17 +366,26 @@
movw $0x200 + BOOTXX_SECTORS, %ax /* command 2, xx sectors */
jmp do_read
+#ifndef BOOT_FROM_FAT
+boot_gpt:
+ /* 64-bit LBA in %ecx:%ebx */
+ movl %ebx, lba_sector
+ movl %ecx, lba_sector + 4
+ movl %ebx, %ebp
+ jmp boot_lba
+#endif
+
_errtxt: .ascii "Error " /* runs into newline... */
_errcod: .byte 0 /* ... if errcod set */
_newline:
.asciz "\r\n"
#ifndef TERSE_ERROR
-ERR_READ: .asciz "Disk read"
-ERR_NO_BOOTXX: .asciz "Not a bootxx image"
-ERR_PTN: .asciz "No NetBSD partition"
+ERR_READ: .asciz "read"
+ERR_NO_BOOTXX: .asciz "no magic"
+ERR_PTN: .asciz "no slice"
#ifndef NO_LBA_CHECK
-ERR_NO_LBA: .asciz "Invalid CHS read"
+ERR_NO_LBA: .asciz "need LBA"
#endif
#endif
@@ -387,8 +407,7 @@
.word BOOTADDR /* offset in segment */
.word 0 /* segment */
_lba_sector:
- .long 0x0000 /* sector # goes here... */
- .long 0x0000
+ .quad 0 /* sector # goes here... */
/* Drive Serial Number */
. = _C_LABEL(start) + MBR_DSN_OFFSET
Index: src/sys/arch/i386/stand/mbr/Makefile
diff -u src/sys/arch/i386/stand/mbr/Makefile:1.2 src/sys/arch/i386/stand/mbr/Makefile:1.3
--- src/sys/arch/i386/stand/mbr/Makefile:1.2 Sat Jan 19 21:01:34 2008
+++ src/sys/arch/i386/stand/mbr/Makefile Thu Jan 6 01:08:49 2011
@@ -1,5 +1,6 @@
-# $NetBSD: Makefile,v 1.2 2008/01/19 21:01:34 dsl Exp $
+# $NetBSD: Makefile,v 1.3 2011/01/06 01:08:49 jakllsch Exp $
SUBDIR= mbr mbr_bootsel mbr_ext mbr_com0 mbr_com0_9600
+SUBDIR+= mbr_gpt mbr_gpt_com0
.include <bsd.subdir.mk>
Index: src/sys/sys/bootblock.h
diff -u src/sys/sys/bootblock.h:1.51 src/sys/sys/bootblock.h:1.52
--- src/sys/sys/bootblock.h:1.51 Wed Jan 5 23:13:01 2011
+++ src/sys/sys/bootblock.h Thu Jan 6 01:08:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: bootblock.h,v 1.51 2011/01/05 23:13:01 jakllsch Exp $ */
+/* $NetBSD: bootblock.h,v 1.52 2011/01/06 01:08:48 jakllsch Exp $ */
/*-
* Copyright (c) 2002-2004 The NetBSD Foundation, Inc.
@@ -168,6 +168,8 @@
*
* 400 - 439 MP NetBSD: mbr_bootsel
*
+ * 424 - 439 M NetBSD: bootptn_guid (in GPT PMBR only)
+ *
* 440 - 443 M WinNT/2K/XP Drive Serial Number (NT DSN)
* http://www.geocities.com/thestarman3/asm/mbr/Win2kmbr.htm
*
@@ -194,6 +196,9 @@
#define MBR_BOOTCODE_OFFSET 90 /* offsetof(mbr_sector, mbr_bootcode) */
#define MBR_BS_OFFSET 400 /* offsetof(mbr_sector, mbr_bootsel) */
#define MBR_BS_OLD_OFFSET 404 /* where mbr_bootsel used to be */
+#define MBR_GPT_GUID_OFFSET 424 /* location of partition GUID to boot */
+#define MBR_GPT_GUID_DEFAULT /* default uninitialized GUID */ \
+ {0xeee69d04,0x02f4,0x11e0,0x8f,0x5d,{0x00,0xe0,0x81,0x52,0x9a,0x6b}}
#define MBR_DSN_OFFSET 440 /* offsetof(mbr_sector, mbr_dsn) */
#define MBR_BS_MAGIC_OFFSET 444 /* offsetof(mbr_sector, mbr_bootsel_magic) */
#define MBR_PART_OFFSET 446 /* offsetof(mbr_sector, mbr_part[0]) */
@@ -1064,6 +1069,7 @@
#define X86_BOOT_MAGIC_2 X86_BOOT_MAGIC(2) /* bootxx.S */
#define X86_BOOT_MAGIC_PXE X86_BOOT_MAGIC(3) /* start_pxe.S */
#define X86_BOOT_MAGIC_FAT X86_BOOT_MAGIC(4) /* fatboot.S */
+#define X86_MBR_GPT_MAGIC 0xedb88320 /* gpt.S */
/* values for bp_flags */
#define X86_BP_FLAGS_RESET_VIDEO 1
Added files:
Index: src/sbin/gpt/biosboot.c
diff -u /dev/null src/sbin/gpt/biosboot.c:1.1
--- /dev/null Thu Jan 6 01:08:49 2011
+++ src/sbin/gpt/biosboot.c Thu Jan 6 01:08:48 2011
@@ -0,0 +1,326 @@
+/* $NetBSD: biosboot.c,v 1.1 2011/01/06 01:08:48 jakllsch Exp $ */
+
+/*
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to the NetBSD Foundation
+ * by Mike M. Volokhov. Development of this software was supported by the
+ * Google Summer of Code program.
+ * The GSoC project was mentored by Allen Briggs and Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifdef __RCSID
+__RCSID("$NetBSD: biosboot.c,v 1.1 2011/01/06 01:08:48 jakllsch Exp $");
+#endif
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/disk.h>
+#include <sys/param.h>
+#include <sys/bootblock.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <paths.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+
+#include "map.h"
+#include "gpt.h"
+
+#define DEFAULT_BOOTDIR "/usr/mdec"
+#define DEFAULT_BOOTCODE "mbr_gpt"
+
+static daddr_t start;
+static uint64_t size;
+
+static char *bootpath;
+static unsigned int entry;
+
+const uuid_t uuid_mbr_guid_default = MBR_GPT_GUID_DEFAULT;
+
+const char biosbootmsg[] = "biosboot [-c bootcode] [-i index] device ...";
+
+static void
+usage_biosboot(void)
+{
+ fprintf(stderr, "usage: %s %s\n", getprogname(), biosbootmsg);
+ exit(1);
+}
+
+static struct mbr*
+read_boot(void)
+{
+ int bfd, ret = 0;
+ struct mbr *buf;
+ struct stat st;
+ uuid_t uuid_patch_magic;
+
+ /* XXX how to do the following better? */
+ if (bootpath == NULL) {
+ bootpath = strdup(DEFAULT_BOOTDIR "/" DEFAULT_BOOTCODE);
+ } else {
+ if (strchr(bootpath, '/') == 0) {
+ char *p;
+ if ((p = strdup(bootpath)) == NULL)
+ err(1, "Malloc failed");
+ free(bootpath);
+ (void)asprintf(&bootpath, "%s/%s", DEFAULT_BOOTDIR, p);
+ free(p);
+ }
+ }
+ if (bootpath == NULL)
+ err(1, "Malloc failed");
+
+ if ((buf = malloc((size_t)secsz)) == NULL)
+ err(1, "Malloc failed");
+
+ if ((bfd = open(bootpath, O_RDONLY)) < 0 || fstat(bfd, &st) == -1) {
+ warn("%s", bootpath);
+ goto fail;
+ }
+
+ if (st.st_size != secsz) {
+ warnx("%s: the bootcode does not match '%s' sector size",
+ bootpath, device_name);
+ goto fail;
+ }
+
+ if (read(bfd, buf, secsz) != st.st_size) {
+ warn("%s", bootpath);
+ goto fail;
+ }
+
+ if (le32toh(buf->mbr_sig) != MBR_SIG) {
+ warnx("%s: invalid MBR magic", bootpath);
+ goto fail;
+ }
+
+ uuid_dec_le(&buf->mbr_code[MBR_GPT_GUID_OFFSET], &uuid_patch_magic);
+
+ /*
+ * The loader have to contain some magic in patchable area,
+ * such we can be sure that we won't trash something important
+ */
+ if (!uuid_equal(&uuid_patch_magic, &uuid_mbr_guid_default, NULL)) {
+ warnx("%s: the bootcode does not support required options",
+ bootpath);
+ goto fail;
+ }
+
+ ret++;
+
+ fail:
+ if (bfd >= 0)
+ close(bfd);
+ if (ret == 0) {
+ free(buf);
+ buf = NULL;
+ }
+ return buf;
+}
+
+static void
+biosboot(int fd)
+{
+ map_t *gpt, *tpg;
+ map_t *tbl, *lbt;
+ map_t *mbrmap, *m;
+ struct mbr *mbr, *bootcode;
+ struct gpt_ent *pp;
+ uuid_t buuid;
+
+ /*
+ * Parse and validate partition maps
+ */
+ gpt = map_find(MAP_TYPE_PRI_GPT_HDR);
+ if (gpt == NULL) {
+ warnx("%s: error: no primary GPT header; run create or recover",
+ device_name);
+ return;
+ }
+
+ tpg = map_find(MAP_TYPE_SEC_GPT_HDR);
+ if (tpg == NULL) {
+ warnx("%s: error: no secondary GPT header; run recover",
+ device_name);
+ return;
+ }
+
+ tbl = map_find(MAP_TYPE_PRI_GPT_TBL);
+ lbt = map_find(MAP_TYPE_SEC_GPT_TBL);
+ if (tbl == NULL || lbt == NULL) {
+ warnx("%s: error: run recover -- trust me", device_name);
+ return;
+ }
+
+ mbrmap = map_find(MAP_TYPE_PMBR);
+ if (mbrmap == NULL || mbrmap->map_start != 0) {
+ warnx("%s: error: no valid Protective MBR found", device_name);
+ return;
+ }
+
+ mbr = mbrmap->map_data;
+
+ /*
+ * Update the boot code
+ */
+ if ((bootcode = read_boot()) == NULL) {
+ warnx("error reading bootcode");
+ return;
+ }
+ (void)memcpy(&mbr->mbr_code, &bootcode->mbr_code,
+ sizeof(mbr->mbr_code));
+ free(bootcode);
+
+ /*
+ * Walk through the GPT and see where we can boot from
+ */
+ for (m = map_first(); m != NULL; m = m->map_next) {
+ if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
+ continue;
+
+ pp = m->map_data;
+
+ /* first, prefer user selection */
+ if (entry > 0 && m->map_index == entry)
+ break;
+
+ /* next, partition as could be specified by wedge */
+ if (entry < 1 && size > 0 &&
+ m->map_start == start && m->map_size == (off_t)size)
+ break;
+ }
+
+ if (m == NULL) {
+ warnx("error: no bootable partition");
+ return;
+ } else
+ uuid_dec_le(pp->ent_guid, &buuid);
+
+#if 1
+ {
+ char *p;
+
+ uuid_to_string(&buuid, &p, NULL);
+ printf("Boot device: %s\n", device_name);
+ printf("Partition GUID: %s\n", p);
+ printf("Boot code: %s\n", bootpath);
+
+ free(p);
+ }
+#endif
+
+ uuid_enc_le(&mbr->mbr_code[MBR_GPT_GUID_OFFSET], &buuid);
+ if (gpt_write(fd, mbrmap) == -1) {
+ warnx("error: cannot update Protective MBR");
+ return;
+ }
+}
+
+int
+cmd_biosboot(int argc, char *argv[])
+{
+ struct dkwedge_info dkw;
+ struct stat sb;
+ char devpath[MAXPATHLEN];
+ char *dev, *p;
+ int ch, fd;
+
+ while ((ch = getopt(argc, argv, "c:i:")) != -1) {
+ switch(ch) {
+ case 'c':
+ if (bootpath != NULL)
+ usage_biosboot();
+ if ((bootpath = strdup(optarg)) == NULL)
+ err(1, "Malloc failed");
+ break;
+ case 'i':
+ if (entry > 0)
+ usage_biosboot();
+ entry = strtoul(optarg, &p, 10);
+ if (*p != 0 || entry < 1)
+ usage_biosboot();
+ break;
+ default:
+ usage_biosboot();
+ }
+ }
+
+ if (argc == optind)
+ usage_biosboot();
+
+ while (optind < argc) {
+ dev = argv[optind++];
+ start = 0;
+ size = 0;
+
+#ifdef __NetBSD__
+ /*
+ * If a dk wedge was specified, loader should be
+ * installed onto parent device
+ */
+ if ((fd = opendisk(dev, O_RDONLY, devpath, sizeof(devpath), 0))
+ == -1)
+ goto next;
+ if (fstat(fd, &sb) == -1)
+ goto close;
+
+#ifdef DIOCGWEDGEINFO
+ if ((sb.st_mode & S_IFMT) != S_IFREG &&
+ ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) {
+ if (entry > 0)
+ /* wedges and indexes are mutually exclusive */
+ usage_biosboot();
+ dev = dkw.dkw_parent;
+ start = dkw.dkw_offset;
+ size = dkw.dkw_size;
+ }
+#endif
+ close:
+ close(fd);
+#endif /* __NetBSD__*/
+
+ fd = gpt_open(dev);
+ next:
+ if (fd == -1) {
+ warn("unable to open device '%s'", device_name);
+ continue;
+ }
+
+ biosboot(fd);
+
+ gpt_close(fd);
+ }
+
+ return (0);
+}
Index: src/sys/arch/i386/stand/mbr/gpt.S
diff -u /dev/null src/sys/arch/i386/stand/mbr/gpt.S:1.1
--- /dev/null Thu Jan 6 01:08:49 2011
+++ src/sys/arch/i386/stand/mbr/gpt.S Thu Jan 6 01:08:49 2011
@@ -0,0 +1,552 @@
+/* $NetBSD: gpt.S,v 1.1 2011/01/06 01:08:49 jakllsch Exp $ */
+
+/*
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to the NetBSD Foundation
+ * by Mike M. Volokhov, based on the mbr.S code by Wolfgang Solfrank,
+ * Frank van der Linden, and David Laight.
+ * Development of this software was supported by the
+ * Google Summer of Code program.
+ * The GSoC project was mentored by Allen Briggs and Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * x86 PC BIOS master boot code - GUID partition table format
+ */
+
+/* Compile options:
+ * COM_PORT - do serial io to specified port number
+ * 0..3 => bios port, otherwise actual io_addr
+ * COM_BAUD - initialise serial port baud rate
+ *
+ * NO_LBA_CHECK - no check if bios supports LBA reads
+ * NO_CRC_CHECK - disable crc checks for GPT
+ * NO_BANNER - do not output title line 'banner'
+ */
+
+#ifdef COM_PORT
+#if COM_PORT < 4
+/* The first 4 items in the 40:xx segment are the serial port base addresses */
+#define COM_PORT_VAL (0x400 + (COM_PORT * 2))
+#else
+#define COM_PORT_VAL $COM_PORT
+#endif
+
+#if !defined(COM_FREQ)
+#define COM_FREQ 1843200
+#endif
+#endif
+
+#include <machine/asm.h>
+#include <sys/bootblock.h>
+
+#define BOOTADDR 0x7c00
+#define GPTBUFADDR 0xa000 /* GPT buffer (both header & array) */
+
+/*
+ * GPT header structure, offsets
+ */
+#define GPTHDR_SIG_O 0 /* header signature, 8 b */
+#define GPTHDR_REV_O 8 /* GPT revision, 4 b */
+#define GPTHDR_SIZE_O 12 /* header size, 4 b */
+#define GPTHDR_CRC_O 16 /* header CRC32, 4 b */
+#define GPTHDR_RSVD_O 20 /* reserved, 4 b */
+#define GPTHDR_MYLBA_O 24 /* this header LBA, 8 b */
+#define GPTHDR_ALTLBA_O 32 /* alternate header LBA, 8 b */
+#define GPTHDR_SLBA_O 40 /* first usable LBA, 8 b */
+#define GPTHDR_ELBA_O 48 /* last usable LBA, 8 b */
+#define GPTHDR_GUID_O 56 /* disk GUID, 16 b */
+#define GPTHDR_PTNLBA_O 72 /* ptn. entry LBA, 8 b */
+#define GPTHDR_PTNN_O 80 /* number of ptns, 4 b */
+#define GPTHDR_PTNSZ_O 84 /* partition size, 4 b */
+#define GPTHDR_PTNCRC_O 88 /* ptn. array CRC32, 4 b */
+
+/*
+ * GPT partition entry structure, offsets
+ */
+#define GPTPTN_TYPE_O 0 /* ptn. type GUID, 16 b */
+#define GPTPTN_GUID_O 16 /* ptn. unique GUID, 16 b */
+#define GPTPTN_SLBA_O 32 /* ptn. starting LBA, 8 b */
+#define GPTPTN_ELBA_O 40 /* ptn. ending LBA, 8 b */
+#define GPTPTN_ATTR_O 48 /* ptn. attributes, 8 b */
+#define GPTPTN_NAME_O 56 /* ptn. name, UTF-16, 72 b */
+
+/*
+ * Default values of generic disk partitioning
+ */
+#ifndef SECTOR_SIZE
+#define SECTOR_SIZE 512 /* 8192 bytes max */
+#endif
+#define GPTHDR_BLKNO 1
+#define GPTHDR_SIZE 92 /* size of GPT header */
+#define GPTHDR_LBASZ 1 /* default LBAs for header */
+#define GPTHDR_PTNSZ 128 /* size of a partition entry */
+#define GPTHDR_PTNN_MIN 128 /* minimum number of ptns */
+#define GPTPTN_SIZE (GPTHDR_PTNSZ * GPTHDR_PTNN_MIN)
+#if GPTPTN_SIZE % SECTOR_SIZE == 0
+#define GPTPTN_LBASZ (GPTPTN_SIZE / SECTOR_SIZE)
+#else
+#define GPTPTN_LBASZ (GPTPTN_SIZE / SECTOR_SIZE + 1)
+#endif
+#define GPT_LBASZ (GPTHDR_LBASZ + GPTPTN_LBASZ)
+
+/*
+ * Minimum and maximum drive number that is considered to be valid.
+ */
+#define MINDRV 0x80
+#define MAXDRV 0x8f
+
+/*
+ * Error codes. Done this way to save space.
+ */
+#define ERR_INVPART 'P' /* Invalid partition table */
+#define ERR_READ 'R' /* Read error */
+#define ERR_NOOS 'S' /* Magic no. check failed for part. */
+#define ERR_NO_LBA 'L' /* Sector above chs limit */
+
+#define set_err(err) movb $err, %al
+
+ .text
+ .code16
+/*
+ * Move ourselves out of the way first.
+ * (to the address we are linked at)
+ * and zero our bss
+ */
+ENTRY(start)
+ xor %ax, %ax
+ mov %ax, %ss
+ movw $BOOTADDR, %sp
+ mov %ax, %es
+ mov %ax, %ds
+ movw $mbr, %di
+ mov $BOOTADDR + (mbr - start), %si
+ push %ax /* zero for %cs of lret */
+ push %di
+ movw $(bss_start - mbr), %cx
+ rep
+ movsb /* relocate code (zero %cx on exit) */
+ mov $(bss_end - bss_start + 511)/512, %ch
+ rep
+ stosw /* zero bss */
+ lret /* Ensures %cs == 0 */
+
+/*
+ * Sanity check the drive number passed by the BIOS. Some BIOSs may not
+ * do this and pass garbage.
+ */
+mbr:
+ cmpb $MAXDRV, %dl /* relies on MINDRV being 0x80 */
+ jle 1f
+ movb $MINDRV, %dl /* garbage in, boot disk 0 */
+1:
+ push %dx /* save drive number */
+ push %dx /* twice - for err_msg loop */
+
+#if defined(COM_PORT) && defined(COM_BAUD)
+ mov $com_args, %si
+ mov $num_com_args, %cl /* %ch is zero from above */
+ mov COM_PORT_VAL, %dx
+1: lodsw
+ add %ah, %dl
+ outb %dx
+ loop 1b
+#endif
+
+#ifndef NO_BANNER
+ mov $banner, %si
+ call message
+#endif
+
+/*
+ * Read and validate GUID partition tables
+ *
+ * Register use:
+ * %ax temp
+ * %bx temp
+ * %cx counters (%ch was preset to zero via %cx before)
+ * %dx disk pointer (inherited from BIOS or the check above)
+ * %bp GPT header pointer
+ */
+#ifndef NO_LBA_CHECK
+/*
+ * Determine whether we have int13-extensions, by calling int 13, function 41.
+ * Check for the magic number returned, and the disk packet capability.
+ * On entry %dx should contain BIOS disk number.
+ */
+lba_check:
+ movw $0x55aa, %bx
+ movb $0x41, %ah
+ int $0x13
+ set_err(ERR_NO_LBA)
+ jc 1f /* no int13 extensions */
+ cmpw $0xaa55, %bx
+ jnz 1f
+ testb $1, %cl
+ jnz gpt
+1: jmp err_msg
+#endif
+
+gpt:
+ /*
+ * Read GPT header
+ */
+ movw $GPTBUFADDR, %bp /* start from primary GPT layout */
+read_gpt:
+ call do_lba_read /* read GPT header */
+ jc try_gpt2
+
+ /*
+ * Verify GPT header
+ */
+ movw $efihdr_sign, %si /* verify GPT signature... */
+ movw %bp, %di /* ptn signature is at offset 0 */
+ movb $sizeof_efihdr_sign, %cl /* signature length */
+ repe
+ cmpsb /* compare */
+ jne try_gpt2 /* if not equal - try GPT2 */
+
+#ifndef NO_CRC_CHECK
+ mov %bp, %si /* verify CRC32 of the header... */
+ mov $GPTHDR_SIZE, %di /* header boundary */
+ add %bp, %di
+ xor %eax, %eax
+ xchgl %eax, GPTHDR_CRC_O(%bp) /* save and reset header CRC */
+ call crc32
+ cmp %eax, %ebx /* is CRC correct? */
+ jne try_gpt2
+#endif
+
+#if 0 /* XXX: weak check - safely disabled due to space constraints */
+ movw $lba_sector, %si /* verify GPT location... */
+ mov $GPTHDR_MYLBA_O, %di
+ add %bp, %di
+ movb $8, %cl /* LBA size */
+ repe
+ cmpsb /* compare */
+ jne try_gpt2 /* if not equal - try GPT2 */
+#endif
+
+ /*
+ * All header checks passed - now verify GPT partitions array
+ */
+#ifndef NO_CRC_CHECK
+ movl GPTHDR_PTNCRC_O(%bp), %eax /* original array checksum */
+ push %bp /* save header pointer for try_gpt2 */
+#endif
+
+ /*
+ * point %bp to GPT partitions array location
+ */
+ cmp $GPTBUFADDR, %bp
+ je 1f
+ mov $GPTBUFADDR, %bp
+ jmp 2f
+1: mov $GPTBUFADDR + GPTPTN_LBASZ * SECTOR_SIZE, %bp
+2:
+
+#ifndef NO_CRC_CHECK
+ mov %bp, %si /* array location for CRC32 check */
+ mov $GPTPTN_SIZE, %di /* array boundary */
+ add %bp, %di
+ call crc32
+ cmp %eax, %ebx /* is CRC correct? */
+ jne 1f /* if no - try GPT2 */
+ pop %ax /* restore stack consistency */
+#endif
+ jmp gpt_parse
+
+#ifndef NO_CRC_CHECK
+1: pop %bp /* restore after unsucc. array check */
+#endif
+try_gpt2:
+ cmp $GPTBUFADDR, %bp /* is this GPT1? */
+ set_err(ERR_INVPART)
+ jne err_msg /* if no - we just tried GPT2. Stop. */
+
+ mov %bp, %si /* use [%bp] as tmp buffer */
+ movb $0x1a, (%si) /* init buffer size (per v.1.0) */
+ movb $0x48, %ah /* request extended LBA status */
+ int $0x13 /* ... to get GPT2 location */
+ set_err(ERR_NO_LBA)
+ jc err_msg /* on error - stop */
+#define LBA_DKINFO_OFFSET 16 /* interested offset in out buffer */
+ addw $LBA_DKINFO_OFFSET, %si /* ... contains number of disk LBAs */
+#undef LBA_DKINFO_OFFSET
+ movw $lba_sector, %di
+ movb $8, %cl /* LBA size */
+ rep
+ movsb /* do get */
+ subl $GPT_LBASZ, lba_sector /* calculate location of GPT2 */
+ sbbl $0, lba_sector + 4 /* 64-bit LBA correction */
+
+ movw $GPTBUFADDR + GPTPTN_LBASZ * SECTOR_SIZE, %bp
+ /* the GPT2 header location */
+ jmp read_gpt /* try once again */
+
+/*
+ * GPT header validation done.
+ * Now parse GPT partitions and try to boot from appropriate.
+ * Register use:
+ * %bx partition counter
+ * %bp partition entry pointer (already initialized on entry)
+ * %di partition entry moving pointer
+ * %si variables pointer
+ * %cx counter
+ */
+
+gpt_parse:
+ movw $BOOTADDR, lba_rbuff /* from now we will read boot code */
+ movb $1, lba_count /* read PBR only */
+ mov $GPTHDR_PTNN_MIN, %bx /* number of GUID partitions to parse */
+do_gpt_parse:
+ movw $bootptn_guid, %si /* lookup the boot partition GUID */
+ movb $0x10, %cl /* sizeof GUID */
+ movw %bp, %di /* set pointer to partition entry */
+ add %cx, %di /* partition GUID at offset 16 */
+ repe
+ cmpsb /* do compare */
+ jne try_nextptn /* doesn't seem appropriate ptn */
+
+ /*
+ * Read partition boot record
+ */
+ mov $GPTPTN_SLBA_O, %si /* point %si to partition LBA */
+ add %bp, %si
+ movw $lba_sector, %di
+ movb $8, %cl /* LBA size */
+ rep
+ movsb /* set read pointer to LBA of PBR */
+ call do_lba_read /* read PBR */
+ jz try_nextptn
+
+ /*
+ * Check signature for valid bootcode and try to boot
+ */
+ movb BOOTADDR, %al /* first byte non-zero */
+ testb %al, %al
+ jz 1f
+ movw BOOTADDR + MBR_MAGIC_OFFSET, %ax
+1: cmp $MBR_MAGIC, %ax
+ jne try_nextptn
+do_boot:
+ pop %dx /* ... %dx - drive # */
+ movw $lba_sector, %sp /* ... %ecx:%ebx - boot partition LBA */
+ pop %ebx
+ pop %ecx
+ movl crc32_poly, %eax /* X86_MBR_GPT_MAGIC */
+ jmp BOOTADDR
+ /* THE END */
+
+try_nextptn:
+ addw $GPTHDR_PTNSZ, %bp /* move to next partition */
+ dec %bx /* ptncounter-- */
+ jnz do_gpt_parse
+ set_err(ERR_NOOS) /* no bootable partitions were found */
+ /* jmp err_msg */ /* stop */
+
+/* Something went wrong...
+ * Output error code,
+ * reset disk subsystem - needed after read failure,
+ * and wait for user key
+ */
+err_msg:
+ movb %al, errcod
+ movw $errtxt, %si
+ call message
+ pop %dx /* drive we errored on */
+ xor %ax,%ax /* only need %ah = 0 */
+ int $0x13 /* reset disk subsystem */
+ int $0x18 /* BIOS might ask for a key */
+ /* press and retry boot seq. */
+1: sti
+ hlt
+ jmp 1b
+
+/*
+ * I hate #including source files, but the stuff below has to be at
+ * the correct absolute address.
+ * Clearly this could be done with a linker script.
+ */
+
+#if defined(COM_PORT) && defined(COM_BAUD)
+message:
+ pusha
+message_1:
+ lodsb
+ test %al, %al
+ jz 3f
+ mov COM_PORT_VAL, %dx
+ outb %al, %dx
+ add $5, %dl
+2: inb %dx
+ test $0x40, %al
+ jz 2b
+ jmp message_1
+3: popa
+ ret
+#else
+#include <message.S>
+#endif
+
+#if 0
+#include <dump_eax.S>
+#endif
+
+#ifndef NO_CRC_CHECK
+/*
+ * The CRC32 calculation
+ *
+ * %si address of block to hash
+ * %di stop address
+ * %ax scratch (but restored after exit)
+ * %dx scratch (but restored after exit)
+ * %cx counter
+ * %ebx crc (returned)
+ */
+crc32:
+ push %dx /* preserve drive number */
+ push %ax /* preserve original CRC */
+
+ xorl %ebx, %ebx
+ decl %ebx /* init value */
+1:
+ lodsb /* load next message byte to %al */
+ movb $8, %cl /* set bit counter */
+2:
+ movb %al, %dl
+ xorb %bl, %dl /* xoring with previous result */
+ shrl $1, %ebx
+ shrb $1, %al
+ testb $1, %dl
+ jz 3f
+crc32_poly = . + 3 /* gross, but saves a few bytes */
+ xorl $0xedb88320, %ebx /* EFI CRC32 Polynomial */
+3:
+ loop 2b /* loop over bits */
+ cmp %di, %si /* do we reached end of message? */
+ jne 1b
+ notl %ebx /* result correction */
+
+ pop %ax
+ pop %dx
+ ret
+#endif
+
+do_lba_read:
+ movw $lba_dap, %si
+ movb $0x42, %ah
+ int $0x13 /* read */
+ ret
+
+/*
+ * Data definition block
+ */
+
+errtxt: .ascii "Error " /* runs into crlf if errcod set */
+errcod: .byte 0
+crlf: .asciz "\r\n"
+
+#ifndef NO_BANNER
+banner: .asciz "NetBSD GPT\r\n"
+#endif
+
+#if defined(COM_PORT) && defined(COM_BAUD)
+#define COM_DIVISOR (((COM_FREQ / COM_BAUD) + 8) / 16)
+com_args:
+ .byte 0x80 /* divisor latch enable */
+ .byte +3 /* io_port + 3 */
+ .byte COM_DIVISOR & 0xff
+ .byte -3 /* io_port */
+ .byte COM_DIVISOR >> 8 /* high baud */
+ .byte +1 /* io_port + 1 */
+ .byte 0x03 /* 8 bit no parity */
+ .byte +2 /* io_port + 3 */
+num_com_args = (. - com_args)/2
+#endif
+
+/*
+ * Control block for int-13 LBA read - Disk Address Packet
+ */
+lba_dap:
+ .byte 0x10 /* control block length */
+ .byte 0 /* reserved */
+lba_count:
+ .word GPT_LBASZ /* sector count */
+lba_rbuff:
+ .word GPTBUFADDR /* offset in segment */
+ .word 0 /* segment */
+lba_sector:
+ .quad GPTHDR_BLKNO /* sector # goes here... */
+
+efihdr_sign:
+ .ascii "EFI PART" /* GPT header signature */
+ .long 0x00010000 /* GPT header revision */
+sizeof_efihdr_sign = . - efihdr_sign
+
+/*
+ * Stuff from here on is overwritten by gpt/fdisk - the offset must not change
+ *
+ * Get amount of space to makefile can report it.
+ * (Unfortunately I can't seem to get the value reported when it is -ve)
+ */
+mbr_space = bootptn_guid - .
+
+/*
+ * GUID of the bootable partition. Patchable area.
+ * Default GUID used by installer for safety checks.
+ */
+ . = start + MBR_GPT_GUID_OFFSET
+bootptn_guid:
+ /* MBR_GPT_GUID_DEFAULT */
+ .long 0xeee69d04
+ .word 0x02f4
+ .word 0x11e0
+ .byte 0x8f,0x5d
+ .byte 0x00,0xe0,0x81,0x52,0x9a,0x6b
+
+/* space for mbr_dsn */
+ . = start + MBR_DSN_OFFSET
+ .long 0
+
+/* mbr_bootsel_magic */
+ . = start + MBR_BS_MAGIC_OFFSET
+ .word 0
+
+/* mbr partition table */
+ . = start + MBR_PART_OFFSET
+parttab:
+ .fill 0x40, 0x01, 0x00
+
+ . = start + MBR_MAGIC_OFFSET
+ .word MBR_MAGIC
+
+/* zeroed data space */
+bss_off = 0
+bss_start = .
+#define BSS(name, size) name = bss_start + bss_off; bss_off = bss_off + size
+ BSS(dump_eax_buff, 16)
+ BSS(bss_end, 0)
Index: src/sys/arch/i386/stand/mbr/mbr_gpt/Makefile
diff -u /dev/null src/sys/arch/i386/stand/mbr/mbr_gpt/Makefile:1.1
--- /dev/null Thu Jan 6 01:08:49 2011
+++ src/sys/arch/i386/stand/mbr/mbr_gpt/Makefile Thu Jan 6 01:08:49 2011
@@ -0,0 +1,6 @@
+# $NetBSD: Makefile,v 1.1 2011/01/06 01:08:49 jakllsch Exp $
+
+PROG= mbr_gpt
+SRCS= gpt.S
+
+.include <../Makefile.mbr>
Index: src/sys/arch/i386/stand/mbr/mbr_gpt_com0/Makefile
diff -u /dev/null src/sys/arch/i386/stand/mbr/mbr_gpt_com0/Makefile:1.1
--- /dev/null Thu Jan 6 01:08:49 2011
+++ src/sys/arch/i386/stand/mbr/mbr_gpt_com0/Makefile Thu Jan 6 01:08:49 2011
@@ -0,0 +1,7 @@
+# $NetBSD: Makefile,v 1.1 2011/01/06 01:08:49 jakllsch Exp $
+
+PROG= mbr_gpt_com0
+SRCS= gpt.S
+AFLAGS+= -DCOM_PORT=0
+
+.include <../Makefile.mbr>