aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-05-28 09:23:57 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-05-28 09:23:57 -0700
commit80001b1d2acc06b33bb6de05474ce54682dacfb6 (patch)
treea320dc9767a953d435ef9d3c951ebd2d97acf4dd
parent6699cb66d4456f2d61b3ac3f8d14ce81df2437eb (diff)
parent1bd7c31844a7b946c5d2d85a21e913fa81460930 (diff)
downloadsyslinux.git-80001b1d2acc06b33bb6de05474ce54682dacfb6.tar.gz
syslinux.git-80001b1d2acc06b33bb6de05474ce54682dacfb6.tar.xz
syslinux.git-80001b1d2acc06b33bb6de05474ce54682dacfb6.zip
Merge commit 'origin/master' into gpxe-added
Conflicts: NEWS version
-rw-r--r--NEWS8
-rw-r--r--com32/lib/MCONFIG4
-rw-r--r--com32/libutil/Makefile2
-rw-r--r--com32/menu/Makefile2
-rw-r--r--com32/modules/Makefile2
-rw-r--r--com32/modules/chain.c2
-rw-r--r--com32/samples/Makefile2
-rw-r--r--comboot.inc4
-rw-r--r--config.inc5
-rw-r--r--doc/gpt.txt92
-rw-r--r--dos/Makefile3
-rw-r--r--extlinux.asm1
-rw-r--r--extlinux/Makefile2
-rw-r--r--isolinux.asm42
-rw-r--r--keywords.inc2
-rw-r--r--ldlinux.asm1
-rw-r--r--localboot.inc78
-rw-r--r--mbr/Makefile9
-rw-r--r--mbr/gptmbr.S288
-rw-r--r--memdisk/Makefile3
-rw-r--r--memdump/Makefile3
-rw-r--r--parseconfig.inc6
-rw-r--r--pxelinux.asm4
-rw-r--r--sample/Makefile7
-rw-r--r--ui.inc2
25 files changed, 512 insertions, 62 deletions
diff --git a/NEWS b/NEWS
index b71dc277..375e0c5d 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,14 @@ Changes in 3.70:
* PXELINUX: Integrate with the gPXE source base; unified image
now included as "gpxelinux.0".
+Changes in 3.64:
+ * SYSLINUX/EXTLINUX: support "localboot" with the same feature
+ set as ISOLINUX.
+ * Add an experimental MBR for GPT partition tables.
+ * Use $(CC) when determining compile flags.
+ * chain.c32: fix booting from logical partitions (Sergey
+ Vlasov.)
+
Changes in 3.63:
* Fix errors in the PCI and DMI detection modules (Erwan Velu,
Sebastian Herbszt).
diff --git a/com32/lib/MCONFIG b/com32/lib/MCONFIG
index 7f88055a..2e36597b 100644
--- a/com32/lib/MCONFIG
+++ b/com32/lib/MCONFIG
@@ -1,13 +1,13 @@
# -*- makefile -*-
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
-gcc_ok = $(shell tmpf=$(TMPFILE); if gcc $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
+gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
GCCOPT := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,)
-CC = gcc
LD = ld
INCLUDE = -I.
AR = ar
diff --git a/com32/libutil/Makefile b/com32/libutil/Makefile
index 5514f8b6..01de06a3 100644
--- a/com32/libutil/Makefile
+++ b/com32/libutil/Makefile
@@ -30,13 +30,13 @@
##
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,)
-CC = gcc
LD = ld -m elf_i386
AR = ar
NASM = nasm
diff --git a/com32/menu/Makefile b/com32/menu/Makefile
index 4e0abc55..8d7b69f4 100644
--- a/com32/menu/Makefile
+++ b/com32/menu/Makefile
@@ -15,13 +15,13 @@
##
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,)
-CC = gcc
LD = ld -m elf_i386
AR = ar
NASM = nasm
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index ff42a348..9890228f 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -15,13 +15,13 @@
##
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,)
-CC = gcc
LD = ld -m elf_i386
AR = ar
NASM = nasm
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index b790bd0b..ec92cd0c 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -228,7 +228,7 @@ find_logical_partition(int whichpart, char *table, struct part_entry *self,
struct part_entry *found;
int i;
- if ( *(uint16_t *)(ptab + 0x1fe) != 0xaa55 )
+ if ( *(uint16_t *)(table + 0x1fe) != 0xaa55 )
return NULL; /* Signature missing */
/* We are assumed to already having enumerated all the data partitions
diff --git a/com32/samples/Makefile b/com32/samples/Makefile
index 189dc187..77feb58c 100644
--- a/com32/samples/Makefile
+++ b/com32/samples/Makefile
@@ -15,13 +15,13 @@
##
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,)
-CC = gcc
LD = ld -m elf_i386
AR = ar
NASM = nasm
diff --git a/comboot.inc b/comboot.inc
index 07ec352a..35cc7f9f 100644
--- a/comboot.inc
+++ b/comboot.inc
@@ -659,13 +659,13 @@ comapi_idle equ comapi_err
;
; INT 22h AX=0014h Local boot
;
-%if IS_PXELINUX || IS_ISOLINUX
+%if HAS_LOCALBOOT
comapi_localboot:
mov ax,P_DX
jmp local_boot
%else
comapi_localboot equ comapi_err
-%endif
+%endif ; HAS_LOCALBOOT
;
; INT 22h AX=0015h Feature flags
diff --git a/config.inc b/config.inc
index d6a981e8..f0f59ce4 100644
--- a/config.inc
+++ b/config.inc
@@ -28,6 +28,11 @@ MAX_FKEYS equ 12 ; Number of F-key help files
%assign DO_WBINVD 0 ; Should we use WBINVD or not?
;
+; Local boot supported
+;
+%assign HAS_LOCALBOOT 1
+
+;
; Set this to return the A20 gate to its previous state, instead of
; leaving it open. This has caused problems, because there appear
; to be a race condition between disabling the A20 gate and trying to
diff --git a/doc/gpt.txt b/doc/gpt.txt
new file mode 100644
index 00000000..42a4da18
--- /dev/null
+++ b/doc/gpt.txt
@@ -0,0 +1,92 @@
+ GPT boot protocol
+
+There is no official MBR-to-partition handover protocol defined for
+booting from disks partitioned using GPT partition tables with
+BIOS-style firmware. This is because the GPT partition format comes
+from the EFI spec, which thinks the universe is all going to be EFI.
+Sigh.
+
+There are thus two alternatives: hybrid booting, and defining a new
+protocol.
+
+ *** Hybrid booting ***
+
+Hybrid booting uses a standard MBR, and has bootable ("active")
+partitions present, as partitions, in the GPT PMBR sector. This means
+the PMBR, instead of containing only one "protective" partition (type
+EE), may contain up to three partitions: a protective partition (EE)
+*before* the active partition, the active partition, and a protective
+partition (EE) *after* the active partition. The active partition is
+limited to the first 2^32 sectors (2 TB) of the disk.
+
+All partitions, including the active partition, should have GPT
+partition entries. Thus, changing which partition is active does NOT
+change the GPT partition table.
+
+This is the only known way to boot Microsoft operating systems from a
+GPT disk with BIOS firmware.
+
+
+ *** New protocol ***
+
+This defines an alternative (experimental) booting protocol for GPT
+partitions with BIOS firmware. It maintains backwards compatibility
+to the extent possible. It is implemented by the file mbr/gptmbr.bin.
+
+ -> The PMBR
+
+The PMBR (the first 512-byte sector of the disk) is divided up as
+follows:
+
+ Offset Size Contents
+ ---------------------------------------------------------
+ 0 424 PMBR boot code
+ 424 16 GUID of the boot partition
+ 440 4 MBR-compatible disk ID
+ 444 2 Magic number: 1D 9A
+ 446 16 PMBR protective entry
+ 462 48 PMBR null entries
+ 510 2 Boot signature: 55 AA
+
+To change the bootable partition, verify that the magic number is
+present (to avoid corrupting software not compatible with this
+specification) and enter the GUID of the boot partition at offset
+424. It might be wise to verify that the data already there is a
+valid partition GUID already, or at least warn the user if that is not
+the case.
+
+ -> The handover protocol
+
+The PMBR boot code loads the first sector of the bootable partition,
+and passes in DL=<disk number>, ES:DI=<pointer to $PnP>, sets EAX to
+0x54504721 ("!GPT") and points DS:SI to a structure of the following
+form:
+
+ Offset Size Contents
+ ---------------------------------------------------------
+ 0 1 0x80 (this is a bootable partition)
+ 1 3 CHS of partition (using INT 13h geometry)
+ 4 1 0xEE (partition type: EFI data partition)
+ 5 3 CHS of partition end
+ 8 4 Partition start LBA
+ 12 4 Partition end LBA
+ 16 varies GPT partition entry
+
+The CHS information is optional; gptmbr.bin currently does *NOT*
+calculate them, and just leaves them as zero.
+
+Bytes 0-15 matches the standard MBR handover (DS:SI points to the
+partition entry), except that the information is provided
+synthetically. The MBR-compatible fields are directly usable if they
+are < 2 TB, otherwise these fields should contain 0xFFFFFFFF and the
+OS will need to understand the GPT partition entry which follows the
+MBR one. The "!GPT" magic number in EAX and the 0xEE partition type
+also informs the OS that the GPT partition information is present.
+
+Currently, this is compatible with Syslinux as long as the Syslinux
+partition is < 2 TB; this probably will be improved in a future
+version.
+
+
+
+
diff --git a/dos/Makefile b/dos/Makefile
index 4f344f49..964c7fdc 100644
--- a/dos/Makefile
+++ b/dos/Makefile
@@ -1,5 +1,7 @@
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
+
gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
@@ -7,7 +9,6 @@ M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) \
$(call gcc_ok,-fno-stack-protector,) \
$(call gcc_ok,-fno-top-level-reorder,$(call gcc_ok,-fno-unit-at-a-time))
-CC = gcc
LD = ld -m elf_i386
OBJCOPY = objcopy
OPTFLAGS = -g -Os -march=i386 -falign-functions=0 -falign-jumps=0 -falign-loops=0 -fomit-frame-pointer
diff --git a/extlinux.asm b/extlinux.asm
index ba634b67..2b43533b 100644
--- a/extlinux.asm
+++ b/extlinux.asm
@@ -1534,6 +1534,7 @@ getfssec:
%include "strecpy.inc" ; strcpy with end pointer check
%include "cache.inc" ; Metadata disk cache
%include "adv.inc" ; Auxillary Data Vector
+%include "localboot.inc" ; Disk-based local boot
; -----------------------------------------------------------------------------
; Begin data section
diff --git a/extlinux/Makefile b/extlinux/Makefile
index 9dd7ec94..f4267020 100644
--- a/extlinux/Makefile
+++ b/extlinux/Makefile
@@ -1,4 +1,5 @@
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) ../dummy.c -o $$tmpf 2>/dev/null; \
then echo '$(1)'; else echo '$(2)'; fi; rm -f $$tmpf)
@@ -6,7 +7,6 @@ gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) ../dummy.c -o $$tmpf 2>/dev/nu
comma := ,
LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,)
-CC = gcc
OPTFLAGS = -g -Os
INCLUDES = -I. -I.. -I../libinstaller
CFLAGS = -W -Wall -Wno-sign-compare -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES)
diff --git a/isolinux.asm b/isolinux.asm
index 42935645..52d426f9 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -1093,46 +1093,6 @@ is_disk_image:
.done_sector: ret
;
-; Boot a specified local disk. AX specifies the BIOS disk number; or
-; 0xFFFF in case we should execute INT 18h ("next device.")
-;
-local_boot:
- call vgaclearmode
- lss sp,[cs:Stack] ; Restore stack pointer
- xor dx,dx
- mov ds,dx
- mov es,dx
- mov fs,dx
- mov gs,dx
- mov si,localboot_msg
- call writestr
- cmp ax,-1
- je .int18
-
- ; Load boot sector from the specified BIOS device and jump to it.
- mov dl,al
- xor dh,dh
- push dx
- xor ax,ax ; Reset drive
- call xint13
- mov ax,0201h ; Read one sector
- mov cx,0001h ; C/H/S = 0/0/1 (first sector)
- mov bx,trackbuf
- call xint13
- pop dx
- cli ; Abandon hope, ye who enter here
- mov si,trackbuf
- mov di,07C00h
- mov cx,512 ; Probably overkill, but should be safe
- rep movsd
- lss sp,[cs:InitStack]
- jmp 0:07C00h ; Jump to new boot sector
-
-.int18:
- int 18h ; Hope this does the right thing...
- jmp kaboom ; If we returned, oh boy...
-
-;
; close_file:
; Deallocates a file structure (pointer in SI)
; Assumes CS == DS.
@@ -1500,6 +1460,7 @@ getfssec:
%include "strcpy.inc" ; strcpy()
%include "rawcon.inc" ; Console I/O w/o using the console functions
%include "adv.inc" ; Auxillary Data Vector
+%include "localboot.inc" ; Disk-based local boot
; -----------------------------------------------------------------------------
; Begin data section
@@ -1507,7 +1468,6 @@ getfssec:
section .data
-localboot_msg db 'Booting from local disk...', CR, LF, 0
default_str db 'default', 0
default_len equ ($-default_str)
boot_dir db '/boot' ; /boot/isolinux
diff --git a/keywords.inc b/keywords.inc
index e98f879c..b6a701bb 100644
--- a/keywords.inc
+++ b/keywords.inc
@@ -90,7 +90,7 @@ keywd_table:
%if IS_PXELINUX
keyword ipappend, pc_ipappend
%endif
-%if IS_PXELINUX || IS_ISOLINUX
+%if HAS_LOCALBOOT
keyword localboot, pc_localboot
%endif
diff --git a/ldlinux.asm b/ldlinux.asm
index b12403eb..012fd3da 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -1549,6 +1549,7 @@ getfatsector:
%include "strcpy.inc" ; strcpy()
%include "cache.inc" ; Metadata disk cache
%include "adv.inc" ; Auxillary Data Vector
+%include "localboot.inc" ; Disk-based local boot
; -----------------------------------------------------------------------------
; Begin data section
diff --git a/localboot.inc b/localboot.inc
new file mode 100644
index 00000000..288d390a
--- /dev/null
+++ b/localboot.inc
@@ -0,0 +1,78 @@
+; -----------------------------------------------------------------------
+;
+; Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+; Boston MA 02110-1301, USA; either version 2 of the License, or
+; (at your option) any later version; incorporated herein by reference.
+;
+; -----------------------------------------------------------------------
+
+;
+; localboot.inc
+;
+; Boot from a local disk, or invoke INT 18h.
+;
+
+%if HAS_LOCALBOOT
+
+;
+; Boot a specified local disk. AX specifies the BIOS disk number; or
+; -1 in case we should execute INT 18h ("next device.")
+;
+ section .text
+
+local_boot:
+ call vgaclearmode
+ lss sp,[cs:Stack] ; Restore stack pointer
+ xor dx,dx
+ mov ds,dx
+ mov es,dx
+ mov fs,dx
+ mov gs,dx
+ mov si,localboot_msg
+ call writestr
+ cmp ax,-1
+ je .int18
+
+ ; Load boot sector from the specified BIOS device and jump to it.
+ mov dl,al
+ xor dh,dh
+ push dx
+ xor ax,ax ; Reset drive
+ int 13h
+ mov ax,0201h ; Read one sector
+ mov cx,0001h ; C/H/S = 0/0/1 (first sector)
+ mov bx,trackbuf
+ mov bp,retry_count
+.again:
+ pusha
+ int 13h
+ popa
+ jnc .ok
+ dec bp
+ jnz .again
+ jmp kaboom ; Failure...
+.ok:
+ pop dx
+ cli ; Abandon hope, ye who enter here
+ mov si,trackbuf
+ mov di,07C00h
+ mov cx,512 ; Probably overkill, but should be safe
+ rep movsd
+ mov ss,cx ; SS <- 0
+ mov sp,7C00h
+ jmp 0:07C00h ; Jump to new boot sector
+
+.int18:
+ int 18h ; Hope this does the right thing...
+ jmp kaboom ; If we returned, oh boy...
+
+ section .data
+localboot_msg db 'Booting from local disk...', CR, LF, 0
+
+ section .text
+
+%endif ; HAS_LOCALBOOT
diff --git a/mbr/Makefile b/mbr/Makefile
index 6a1bcb7b..76a47e05 100644
--- a/mbr/Makefile
+++ b/mbr/Makefile
@@ -29,7 +29,7 @@ PERL = perl
.SUFFIXES: .S .s .o .elf
-all: mbr.bin
+all: mbr.bin gptmbr.bin
.PRECIOUS: %.o
%.o: %.S
@@ -42,6 +42,13 @@ mbr.bin: mbr.elf checksize.pl
$(OBJCOPY) -O binary $< $@
$(PERL) checksize.pl mbr.bin 440
+gptmbr.elf: gptmbr.o mbr.ld
+ $(LD) -T mbr.ld -e _start -o $@ $<
+
+gptmbr.bin: gptmbr.elf checksize.pl
+ $(OBJCOPY) -O binary $< $@
+ $(PERL) checksize.pl gptmbr.bin 424
+
tidy:
rm -f *.o *.elf *.lst
diff --git a/mbr/gptmbr.S b/mbr/gptmbr.S
new file mode 100644
index 00000000..77408b75
--- /dev/null
+++ b/mbr/gptmbr.S
@@ -0,0 +1,288 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+ .code16
+ .text
+
+ .globl bootsec
+stack = 0x7c00
+
+/* Partition table header here */
+phdr = stack /* Above the stack, overwritten by bootsect */
+/* Partition table sector here */
+/* To handle > 32K we need to play segment tricks... */
+psec = _phdr + 512
+
+/* BootGUID */
+bootguid = _start + 0x1a8
+/* Where we put DS:SI */
+dssi_out = _start + 0x1be
+
+BIOS_page = 0x462
+
+ /* gas/ld has issues with doing this as absolute addresses... */
+ .section ".bootsec", "a", @nobits
+ .globl bootsec
+bootsec:
+ .space 512
+
+ .text
+ .globl _start
+_start:
+ cli
+ xorw %ax, %ax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw $stack, %sp
+ movw %sp, %si
+ pushw %es /* 4(%bp) es:di -> $PnP header */
+ pushw %di /* 2(%bp) */
+ pushw %dx /* 0(%bp) = %dl -> drive number */
+ movw %ax, %es
+ sti
+ cld
+
+ /* Copy down to 0:0x600 */
+ movw $_start, %di
+ movw $(512/2), %cx
+ rep; movsw
+
+ ljmpw $0, $next
+
+next:
+ /* Check to see if we have EBIOS */
+ pushw %dx /* drive number */
+ movb $0x41, %ah /* %al == 0 already */
+ movw $0x55aa, %bx
+ xorw %cx, %cx
+ xorb %dh, %dh
+ stc
+ int $0x13
+ jc 1f
+ cmpw $0xaa55, %bx
+ jne 1f
+ shrw %cx /* Bit 0 = fixed disk subset */
+ jnc 1f
+
+ /* We have EBIOS; patch in the following code at
+ read_sector_cbios: movb $0x42, %ah ; jmp read_common */
+ movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
+ (read_sector_cbios)
+
+1:
+ popw %dx
+
+ /* Get (C)HS geometry */
+ movb $0x08, %ah
+ int $0x13
+ andw $0x3f, %cx /* Sector count */
+ movw %sp, %bp /* %bp -> frame pointer: LEAVE UNCHANGED */
+ pushw %cx /* -2(%bp) Save sectors on the stack */
+ movzbw %dh, %ax /* dh = max head */
+ incw %ax /* From 0-based max to count */
+ mulw %cx /* Heads*sectors -> sectors per cylinder */
+
+ /* Save sectors/cylinder on the stack */
+ pushw %dx /* -4(%bp) High word */
+ pushw %ax /* -6(%bp) Low word */
+
+ /* Load partition table header */
+ xorl %eax,%eax
+ cltd
+ incw %ax /* %edx:%eax = 1 */
+ movw $phdr, %bx
+ pushw %bx /* -8(%bp) phdr == bootsect */
+ call read_sector
+
+ /* Number of partition sectors */
+ /* We assume the partition table is 32K or less, and that
+ the sector size is 512. */
+ /* Note: phdr == 6(%bp) */
+ movw (80+6)(%bp),%cx /* NumberOfPartitionEntries */
+ movw (84+6)(%bp),%ax /* SizeOfPartitionEntry */
+ pushw %ax
+ pushw %cx
+ mulw %cx
+ shrw $9,%ax
+ xchgw %ax,%cx
+ incw %cx
+
+ /* Starting LBA of partition array */
+ movl (72+6)(%bp),%eax
+ movl (76+6)(%bp),%edx
+
+ pushw %bx
+get_ptab:
+ call read_sector
+ call inc64
+ loopw get_ptab
+
+ /* Find the boot partition */
+ popw %si /* Partition table in memory */
+ popw %cx /* NumberOfPartitionEntries */
+ popw %ax /* SizeOfPartitionEntry */
+find_part:
+ pushw %cx
+ pushw %si
+ addw $16,%si
+ movw $bootguid,%di
+ movw $8,%cx
+ repe; cmpsw
+ popw %si
+ popw %cx
+ je found_part
+ addw %ax,%si
+ loopw find_part
+
+ call error
+ .ascii "Boot partition not found\r\n"
+
+found_part:
+ xchgw %ax,%cx /* Set up %cx for rep movsb further down */
+
+ movw $dssi_out,%di
+ pushw %di
+
+ /* 80 00 00 00 ee 00 00 00
+ - bootable partition, type EFI (EE), no CHS information */
+ xorl %eax,%eax
+ movb $0x80,%al
+ stosl
+ movb $0xee,%al
+ stosl
+ movl 32(%si),%eax
+ movl 36(%si),%edx
+ call saturate_stosl /* Partition start */
+
+ movl 40(%si),%eax
+ movl 48(%si),%edx
+ subl 32(%si),%eax
+ sbbl 36(%si),%edx
+ call inc64
+ call saturate_stosl /* Partition length */
+
+ rep; movsb /* GPT entry follows MBR entry */
+ popw %si
+
+/*
+ * boot: invoke the actual bootstrap. %ds:%si points to the
+ * partition information in memory. The top word on the stack
+ * is phdr == 0x7c00 == the address of the boot sector.
+ */
+boot:
+ movl (32+16)(%si),%eax
+ movl (36+16)(%si),%edx
+ popw %bx
+ call read_sector
+ cmpw $0xaa55, -2(%bx)
+ jne missing_os /* Not a valid boot sector */
+ movw %bp, %sp /* driveno == bootsec-6 */
+ popw %dx /* dl -> drive number */
+ popw %di /* es:di -> $PnP vector */
+ popw %es
+ movl $0x54504721,%eax /* !GPT magic number */
+ cli
+ jmpw *%sp /* %sp == bootsec */
+
+missing_os:
+ call error
+ .ascii "Operating system not bootable\r\n"
+
+saturate_stosl:
+ pushl %eax
+ andl %edx,%edx
+ jz 1f
+ orl $-1,%eax
+1: stosl
+ popl %eax
+ ret
+
+inc64:
+ addl $1,%eax
+ adcl $0,%edx
+ ret
+
+/*
+ * read_sector: read a single sector pointed to by %edx:%eax to
+ * %es:%bx. CF is set on error. All registers saved.
+ */
+read_sector:
+ pushal
+ pushl %edx /* MSW of LBA */
+ pushl %eax /* LSW of LBA */
+ pushw %es /* Buffer segment */
+ pushw %bx /* Buffer offset */
+ pushw $1 /* Sector count */
+ pushw $16 /* Size of packet */
+ movw %sp, %si
+
+ /* This chunk is skipped if we have ebios */
+ /* Do not clobber %es:%bx or %edx:%eax before this chunk! */
+read_sector_cbios:
+ divl -6(%bp) /* secpercyl */
+ shlb $6, %ah
+ movb %ah, %cl
+ movb %al, %ch
+ xchgw %dx, %ax
+ divb -2(%bp) /* sectors */
+ movb %al, %dh
+ orb %ah, %cl
+ incw %cx /* Sectors are 1-based */
+ movw $0x0201, %ax
+
+read_common:
+ movb (%bp), %dl /* driveno */
+ int $0x13
+ addw $16, %sp /* Drop DAPA */
+ popal
+ jc disk_error
+ addb $2, %bh /* bx += 512: point to the next buffer */
+ ret
+
+disk_error:
+ call error
+ .ascii "Disk error on boot\r\n"
+
+/*
+ * Print error messages. This is invoked with "call", with the
+ * error message at the return address.
+ */
+error:
+ popw %si
+2:
+ lodsb
+ movb $0x0e, %ah
+ movb (BIOS_page), %bh
+ movb $0x07, %bl
+ int $0x10 /* May destroy %bp */
+ cmpb $10, %al /* Newline? */
+ jne 2b
+
+ int $0x18 /* Boot failure */
+die:
+ hlt
+ jmp die
diff --git a/memdisk/Makefile b/memdisk/Makefile
index d9cc7f9f..3c288ca4 100644
--- a/memdisk/Makefile
+++ b/memdisk/Makefile
@@ -14,6 +14,8 @@ VERSION := $(shell cat ../version)
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
+
gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
@@ -21,7 +23,6 @@ M32 := $(call gcc_ok,-m32,)
ALIGN := $(call gcc_ok,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0)
FREE := $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector,)
-CC = gcc
CFLAGS = $(M32) $(FREE) -g -W -Wall -Wno-sign-compare \
-Os -fomit-frame-pointer -march=i386 $(ALIGN) \
-DVERSION='"$(VERSION)"' -DDATE='"$(DATE)"'
diff --git a/memdump/Makefile b/memdump/Makefile
index 585381d6..60c4229b 100644
--- a/memdump/Makefile
+++ b/memdump/Makefile
@@ -1,11 +1,12 @@
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
+
gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector,)
-CC = gcc
LD = ld -m elf_i386
OBJCOPY = objcopy
OPTFLAGS = -g -Os -march=i386 -falign-functions=0 -falign-jumps=0 -falign-loops=0 -fomit-frame-pointer
diff --git a/parseconfig.inc b/parseconfig.inc
index 90c1f3c9..2ef9c3a2 100644
--- a/parseconfig.inc
+++ b/parseconfig.inc
@@ -81,7 +81,8 @@ pc_ipappend: call getint
;
; "localboot" command (PXELINUX, ISOLINUX)
;
-%if IS_PXELINUX || IS_ISOLINUX
+%if HAS_LOCALBOOT
+
pc_localboot: call getint
cmp byte [VKernel],0 ; ("label" section only)
je .err
@@ -97,7 +98,8 @@ pc_localboot: call getint
mov [VKernelBuf+vk_rname+1], bx ; Return type
%endif
.err: ret
-%endif
+
+%endif ; HAS_LOCALBOOT
;
; "kernel", "config", ... command
diff --git a/pxelinux.asm b/pxelinux.asm
index b3f1cbb8..8be844fa 100644
--- a/pxelinux.asm
+++ b/pxelinux.asm
@@ -852,6 +852,8 @@ config_scan:
; Boot to the local disk by returning the appropriate PXE magic.
; AX contains the appropriate return code.
;
+%if HAS_LOCALBOOT
+
local_boot:
push cs
pop ds
@@ -870,6 +872,8 @@ local_boot:
popfd
retf ; Return to PXE
+%endif
+
;
; kaboom: write a message and bail out. Wait for quite a while,
; or a user keypress, then do a hard reboot.
diff --git a/sample/Makefile b/sample/Makefile
index 3ed7907e..d2a00f9b 100644
--- a/sample/Makefile
+++ b/sample/Makefile
@@ -16,12 +16,13 @@
TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
+CC = gcc
+
gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector,)
-CC = gcc
LD = ld -m elf_i386
AR = ar
NASM = nasm
@@ -33,7 +34,7 @@ LDFLAGS = -s
OBJCOPY = objcopy
PPMTOLSS16 = ../ppmtolss16
LIB = liboldcom32.a
-GZIP = gzip
+GZIPPROG = gzip
PNGTOPNM = pngtopnm
LIBOBJS = conio.o atou.o skipatou.o printf.o c32exit.o
@@ -67,7 +68,7 @@ $(LIB): $(LIBOBJS)
$(RANLIB) $@
%.lss: %.ppm.gz $(PPMTOLSS16)
- $(GZIP) -cd $< | \
+ $(GZIPPROG) -cd $< | \
$(PPMTOLSS16) \#000000=0 \#d0d0d0=7 \#f6f6f6=15 \
> $@
diff --git a/ui.inc b/ui.inc
index 06777332..3fc3e639 100644
--- a/ui.inc
+++ b/ui.inc
@@ -343,7 +343,7 @@ vk_check:
mov al, [VKernelBuf+vk_type]
mov [KernelType], al
-%if IS_PXELINUX || IS_ISOLINUX
+%if HAS_LOCALBOOT
; Is this a "localboot" pseudo-kernel?
%if IS_PXELINUX
cmp byte [VKernelBuf+vk_rname+4], 0