aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile34
-rw-r--r--NEWS4
-rw-r--r--cache.inc84
-rw-r--r--com32/lib/MCONFIG7
-rw-r--r--com32/libutil/Makefile2
-rw-r--r--com32/modules/Makefile2
-rw-r--r--com32/samples/Makefile2
-rw-r--r--dos/Makefile7
-rw-r--r--dummy.c8
-rw-r--r--extlinux.asm6
-rw-r--r--extlinux/Makefile8
-rw-r--r--layout.inc4
-rw-r--r--ldlinux.asm16
-rw-r--r--mbr/Makefile47
-rwxr-xr-xmbr/checksize.pl31
-rw-r--r--mbr/mbr.S299
-rw-r--r--mbr/mbr.ld73
-rw-r--r--mbr/oldmbr.asm (renamed from mbr.asm)0
-rw-r--r--memdisk/Makefile2
-rw-r--r--menu/Makefile2
-rw-r--r--mtools/Makefile8
-rw-r--r--mtools/syslinux.c2
-rw-r--r--sample/Makefile2
-rw-r--r--ui.inc22
-rw-r--r--unix/Makefile8
-rw-r--r--unix/syslinux.c2
26 files changed, 594 insertions, 88 deletions
diff --git a/Makefile b/Makefile
index 7673cf5c..5a27526c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
## -----------------------------------------------------------------------
##
-## Copyright 1998-2006 H. Peter Anvin - All Rights Reserved
+## Copyright 1998-2007 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
@@ -17,12 +17,18 @@
# No builtin rules
MAKEFLAGS = -r
+gcc_ok = $(shell if gcc $(1) dummy.c -o /dev/null 2>/dev/null; \
+ then echo '$(1)'; else echo '$(2)'; fi)
+
+comma := ,
+LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,)
+
OSTYPE = $(shell uname -msr)
CC = gcc
INCLUDE =
CFLAGS = -W -Wall -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
PIC = -fPIC
-LDFLAGS = -O2 -s
+LDFLAGS = -O2 -s $(LDHASH)
AR = ar
RANLIB = ranlib
@@ -63,12 +69,16 @@ BINFILES = bootsect_bin.c ldlinux_bin.c mbr_bin.c \
# mingw suite installed
BTARGET = kwdhash.gen version.gen version.h \
ldlinux.bss ldlinux.sys ldlinux.bin \
- pxelinux.0 mbr.bin isolinux.bin isolinux-debug.bin \
+ pxelinux.0 isolinux.bin isolinux-debug.bin \
extlinux.bin extlinux.bss extlinux.sys
-BOBJECTS = $(BTARGET) dos/syslinux.com win32/syslinux.exe memdisk/memdisk
+BOBJECTS = $(BTARGET) mbr/mbr.bin dos/syslinux.com win32/syslinux.exe memdisk/memdisk
+# BESUBDIRS and IESUBDIRS are "early", i.e. before the root; BSUBDIRS
+# and ISUBDIRS are "late", after the root.
+BESUBDIRS = mbr
BSUBDIRS = memdisk dos win32
ITARGET = copybs.com gethostip mkdiskimage
IOBJECTS = $(ITARGET) mtools/syslinux unix/syslinux extlinux/extlinux
+IESUBDIRS =
ISUBDIRS = mtools unix extlinux sample com32
DOCS = COPYING NEWS README TODO BUGS *.doc sample menu com32
OTHER = Makefile bin2c.pl now.pl genhash.pl keywords findpatch.pl \
@@ -82,7 +92,7 @@ INSTALL_BIN = mtools/syslinux gethostip ppmtolss16 lss16toppm
INSTALL_SBIN = extlinux/extlinux
# Things to install in /usr/lib/syslinux
INSTALL_AUX = pxelinux.0 isolinux.bin isolinux-debug.bin \
- dos/syslinux.com copybs.com memdisk/memdisk mbr.bin
+ dos/syslinux.com copybs.com memdisk/memdisk mbr/mbr.bin
INSTALL_AUX_OPT = win32/syslinux.exe
# The DATE is set on the make command line when building binaries for
@@ -102,9 +112,10 @@ MAKE += DATE=$(DATE) HEXDATE=$(HEXDATE)
# error every time you try to build.
#
-all: all-local
- set -e ; for i in $(BSUBDIRS) $(ISUBDIRS) ; do $(MAKE) -C $$i $@ ; done
+all:
+ set -e ; for i in $(BESUBDIRS) $(IESUBDIRS) ; do $(MAKE) -C $$i $@ ; done
$(MAKE) all-local
+ set -e ; for i in $(BSUBDIRS) $(ISUBDIRS) ; do $(MAKE) -C $$i $@ ; done
-ls -l $(BOBJECTS) $(IOBJECTS)
all-local: $(BTARGET) $(ITARGET) $(BINFILES)
@@ -167,10 +178,7 @@ extlinux.bss: extlinux.bin
extlinux.sys: extlinux.bin
dd if=$< of=$@ bs=512 skip=1
-mbr.bin: mbr.asm
- $(NASM) -f bin -l mbr.lst -o mbr.bin mbr.asm
-
-mbr_bin.c: mbr.bin bin2c.pl
+mbr_bin.c: mbr/mbr.bin bin2c.pl
$(PERL) bin2c.pl syslinux_mbr < $< > $@
copybs.com: copybs.asm
@@ -199,8 +207,8 @@ $(LIB_SO): bootsect_bin.o ldlinux_bin.o syslxmod.o
gethostip: gethostip.o
$(CC) $(LDFLAGS) -o $@ $^
-mkdiskimage: mkdiskimage.in mbr.bin bin2hex.pl
- $(PERL) bin2hex.pl < mbr.bin | cat mkdiskimage.in - > $@
+mkdiskimage: mkdiskimage.in mbr/mbr.bin bin2hex.pl
+ $(PERL) bin2hex.pl < mbr/mbr.bin | cat mkdiskimage.in - > $@
chmod a+x $@
install: installer
diff --git a/NEWS b/NEWS
index c1f55d8f..43912b78 100644
--- a/NEWS
+++ b/NEWS
@@ -5,8 +5,12 @@ them.
Changes in 3.36:
* MEMDISK: Disable EDD by default on floppy disks. EDD can be
enabled with the "edd" option and disabled with "noedd".
+ This (hopefully) should make Ghost work again.
* SYSLINUX: "unix" installer now uses Linux ioctls instead of
using libfat.
+ * New MBR which can boot from logical partitions.
+ * SYSLINUX: Fix bug in detecting special extensions which was
+ introduced in 3.35 :(
Changes in 3.35:
* MEMDISK: New "safeint" mode.
diff --git a/cache.inc b/cache.inc
index e2595a21..95c5f48e 100644
--- a/cache.inc
+++ b/cache.inc
@@ -1,6 +1,6 @@
; -*- fundamental -*- ---------------------------------------------------
;
-; Copyright 2004 H. Peter Anvin - All Rights Reserved
+; Copyright 2004-2007 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
@@ -11,17 +11,32 @@
; -----------------------------------------------------------------------
section .text
+
+ struc cptr
+.sector: resd 1 ; Sector number
+.prev: resw 1 ; LRU pointer to previous (less recent)
+.next: resw 1 ; LRU pointer to next (more recent)
+ endstruc
+cptr_size_lg2 equ 3
+
+NCacheEntries equ 65536/SECTOR_SIZE
+
;
; initcache: Initialize the cache data structures
;
initcache:
xor eax,eax ; We don't care about sector 0
mov di,CachePtrs
- mov cx,65536/SECTOR_SIZE
- rep stosd
+ mov cx,NCacheEntries+1
+ mov bx,CachePtrs+NCacheEntries*cptr_size ; "prev" pointer
+.loop:
+ mov [di+cptr.sector],eax ; Zero sector number
+ mov [di+cptr.prev],bx ; Previous pointer
+ mov [bx+cptr.next],di ; Previous entry's next pointer
+ add di,cptr_size
+ loop .loop
ret
-
;
; getcachesector: Check for a particular sector (EAX) in the sector cache,
; and if it is already there, return a pointer in GS:SI
@@ -31,32 +46,29 @@ initcache:
;
getcachesector:
push cx
+ push bx
+ push di
mov si,cache_seg
mov gs,si
- mov si,CachePtrs ; Sector cache pointers
- mov cx,65536/SECTOR_SIZE
+ mov si,CachePtrs+cptr_size ; Real sector cache pointers
+ mov cx,NCacheEntries
.search:
cmp eax,[si]
jz .hit
- add si,4
+ add si,cptr_size
loop .search
.miss:
TRACER 'M'
- ; Need to load it. Highly inefficient cache replacement
- ; algorithm: Least Recently Written (LRW)
- push bx
+ ; Need to load it.
push es
push gs
pop es
- mov bx,[NextCacheSlot]
- inc bx
- and bx,(1 << (16-SECTOR_SHIFT))-1
- mov [NextCacheSlot],bx
- shl bx,2
- mov [CachePtrs+bx],eax
- shl bx,SECTOR_SHIFT-2
+ mov bx,[CachePtrs+cptr.next] ; "Next most recent than head node"
+ mov [bx+cptr.sector],eax
mov si,bx
+ sub bx,CachePtrs+cptr_size
+ shl bx,SECTOR_SHIFT-cptr_size_lg2 ; Buffer address
pushad
%if IS_EXTLINUX
call getonesec_ext
@@ -65,18 +77,38 @@ getcachesector:
%endif
popad
pop es
- pop bx
- pop cx
- ret
-
-.hit: ; We have it; get the pointer
+.hit:
+ ; Update LRU, then compute buffer address
TRACER 'H'
- sub si,CachePtrs
- shl si,SECTOR_SHIFT-2
+
+ ; Remove from current position in the list
+ mov bx,[si+cptr.prev]
+ mov di,[si+cptr.next]
+ mov [bx+cptr.next],di
+ mov [di+cptr.prev],bx
+
+ ; Add to just before head node
+ mov bx,[CachePtrs+cptr.prev]
+ mov [si+cptr.prev],bx
+ mov [bx+cptr.next],si
+ mov [CachePtrs+cptr.prev],si
+ mov word [si+cptr.next],CachePtrs
+
+ sub si,CachePtrs+cptr_size
+ shl si,SECTOR_SHIFT-cptr_size_lg2 ; Buffer address
+
+ pop di
+ pop bx
pop cx
ret
section .latebss
+
+ ; Each CachePtr contains:
+ ; - Block pointer
+ ; - LRU previous pointer
+ ; - LRU next pointer
+ ; The first entry is the head node of the list
alignb 4
-CachePtrs resd 65536/SECTOR_SIZE ; Cached sector pointers
-NextCacheSlot resw 1 ; Next cache slot to occupy
+CachePtrs resb (NCacheEntries+1)*cptr_size
+
diff --git a/com32/lib/MCONFIG b/com32/lib/MCONFIG
index 39b62db1..461ada44 100644
--- a/com32/lib/MCONFIG
+++ b/com32/lib/MCONFIG
@@ -1,5 +1,10 @@
# -*- makefile -*-
+gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
+ then echo $(1); else echo $(2); fi)
+
+GCCOPT := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,)
+
CC = gcc
LD = ld
INCLUDE = -I.
@@ -21,7 +26,7 @@ LIBFLAGS = -DDYNAMIC_CRC_TABLE -DPNG_NO_CONSOLE_IO \
# fallback anyway, just use that on old machines...
# LIBFLAGS += -DPNG_NO_FLOATING_POINT_SUPPORTED
-REQFLAGS = -g -m32 -mregparm=3 -DREGPARM=3 -D__COM32__ -I. -I./sys -I../include
+REQFLAGS = $(GCCOPT) -g -mregparm=3 -DREGPARM=3 -D__COM32__ -I. -I./sys -I../include
OPTFLAGS = -Os -march=i386 -falign-functions=0 -falign-jumps=0 \
-falign-labels=0 -ffast-math -fomit-frame-pointer
WARNFLAGS = -W -Wall -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline
diff --git a/com32/libutil/Makefile b/com32/libutil/Makefile
index 9adeec66..8976ebd8 100644
--- a/com32/libutil/Makefile
+++ b/com32/libutil/Makefile
@@ -32,7 +32,7 @@
gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
then echo $(1); else echo $(2); fi)
-M32 := $(call gcc_ok,-m32,)
+M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno_stack_protector,)
CC = gcc
LD = ld -m elf_i386
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 3c272f26..877ce399 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -17,7 +17,7 @@
gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
then echo $(1); else echo $(2); fi)
-M32 := $(call gcc_ok,-m32,)
+M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,)
CC = gcc
LD = ld -m elf_i386
diff --git a/com32/samples/Makefile b/com32/samples/Makefile
index 213ae1a3..291413a6 100644
--- a/com32/samples/Makefile
+++ b/com32/samples/Makefile
@@ -17,7 +17,7 @@
gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
then echo $(1); else echo $(2); fi)
-M32 := $(call gcc_ok,-m32,)
+M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,)
CC = gcc
LD = ld -m elf_i386
diff --git a/dos/Makefile b/dos/Makefile
index 61423cec..5fd52d1b 100644
--- a/dos/Makefile
+++ b/dos/Makefile
@@ -1,9 +1,14 @@
+gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
+ then echo $(1); else echo $(2); fi)
+
+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
INCLUDES = -include code16.h -I. -I.. -I../libfat
-CFLAGS = -m32 -mregparm=3 -DREGPARM=3 -W -Wall -ffreestanding -msoft-float $(OPTFLAGS) $(INCLUDES)
+CFLAGS = $(M32) -mregparm=3 -DREGPARM=3 -W -Wall -msoft-float $(OPTFLAGS) $(INCLUDES)
LDFLAGS = -T com16.ld
AR = ar
RANLIB = ranlib
diff --git a/dummy.c b/dummy.c
new file mode 100644
index 00000000..81f2586c
--- /dev/null
+++ b/dummy.c
@@ -0,0 +1,8 @@
+/*
+ * Trivial C program to test the compiler
+ */
+
+int main(int argc, char *argv[])
+{
+ return 0;
+}
diff --git a/extlinux.asm b/extlinux.asm
index 7ddc278a..e41f6ae3 100644
--- a/extlinux.asm
+++ b/extlinux.asm
@@ -5,7 +5,7 @@
;
; A program to boot Linux kernels off an ext2/ext3 filesystem.
;
-; Copyright (C) 1994-2006 H. Peter Anvin
+; Copyright (C) 1994-2007 H. Peter Anvin
;
; 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
@@ -111,7 +111,7 @@ trackbuf resb trackbufsize ; Track buffer goes here
getcbuf resb trackbufsize
; ends at 4800h
- section .latebss
+ section .bss
SuperBlock resb 1024 ; ext2 superblock
SuperInfo resq 16 ; DOS superblock expanded
ClustSize resd 1 ; Bytes/cluster ("block")
@@ -1023,7 +1023,7 @@ open_inode:
pop di
ret
- section .latebss
+ section .bss
alignb 4
ThisInode resb EXT2_GOOD_OLD_INODE_SIZE ; The most recently opened inode
diff --git a/extlinux/Makefile b/extlinux/Makefile
index a450a3dc..8d347a98 100644
--- a/extlinux/Makefile
+++ b/extlinux/Makefile
@@ -1,8 +1,14 @@
+gcc_ok = $(shell if gcc $(1) ../dummy.c -o /dev/null 2>/dev/null; \
+ then echo '$(1)'; else echo '$(2)'; fi)
+
+comma := ,
+LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,)
+
CC = gcc
OPTFLAGS = -g -Os
INCLUDES = -I. -I.. -I../libfat
CFLAGS = -W -Wall -Wno-sign-compare -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES)
-LDFLAGS = -s
+LDFLAGS = $(LDHASH) -s
SRCS = extlinux.c ../extlinux_bss_bin.c ../extlinux_sys_bin.c
OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
diff --git a/layout.inc b/layout.inc
index d688a6e9..f4e03079 100644
--- a/layout.inc
+++ b/layout.inc
@@ -1,6 +1,6 @@
; -----------------------------------------------------------------------
;
-; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
+; Copyright 1994-2007 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
@@ -26,7 +26,7 @@ TEXT_START equ 7C00h
; The secondary BSS section, above the text; we really wish we could
; just make it follow .bcopy32 or hang off the end,
; but it doesn't seem to work that way.
-LATEBSS_START equ 0B400h
+LATEBSS_START equ 0B200h
; Reserve memory for the stack. This causes checkov to abort the
; compile if we violate this space.
diff --git a/ldlinux.asm b/ldlinux.asm
index 733f2ec9..a5637cd1 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -122,7 +122,6 @@ RootDir resd 1 ; Location of root directory proper
DataArea resd 1 ; Location of data area
RootDirSize resd 1 ; Root dir size in sectors
TotalSectors resd 1 ; Total number of sectors
-EndSector resd 1 ; Location of filesystem end
ClustSize resd 1 ; Bytes/cluster
ClustMask resd 1 ; Sectors/cluster - 1
CopySuper resb 1 ; Distinguish .bs versus .bss
@@ -794,9 +793,6 @@ genfatinfo:
.have_secs:
mov [TotalSectors],edx
- add edx,eax
- mov [EndSector],edx
-
mov eax,[bxResSectors]
mov [FAT],eax ; Beginning of FAT
mov edx,[bxFATsecs]
@@ -834,7 +830,7 @@ genfatinfo:
; FAT12, FAT16 or FAT28^H^H32? This computation is fscking ridiculous.
;
getfattype:
- mov eax,[EndSector]
+ mov eax,[TotalSectors]
sub eax,[DataArea]
shr eax,cl ; cl == ClustShift
mov cl,nextcluster_fat12-(nextcluster+2)
@@ -1603,11 +1599,11 @@ initrd_cmd_len equ 7
;
; Extensions to search for (in *forward* order).
;
-exten_table: db 'CBT',0 ; COMBOOT (specific)
- db 'BSS',0 ; Boot Sector (add superblock)
- db 'BS ',0 ; Boot Sector
- db 'COM',0 ; COMBOOT (same as DOS)
- db 'C32',0 ; COM32
+exten_table: db '.cbt' ; COMBOOT (specific)
+ db '.bss' ; Boot Sector (add superblock)
+ db '.bs', 0 ; Boot Sector
+ db '.com' ; COMBOOT (same as DOS)
+ db '.c32' ; COM32
exten_table_end:
dd 0, 0 ; Need 8 null bytes here
diff --git a/mbr/Makefile b/mbr/Makefile
new file mode 100644
index 00000000..d61f7f1c
--- /dev/null
+++ b/mbr/Makefile
@@ -0,0 +1,47 @@
+## -----------------------------------------------------------------------
+##
+## Copyright 2007 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., 53 Temple Place Ste 330,
+## Boston MA 02111-1307, USA; either version 2 of the License, or
+## (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+#
+# Makefile for MBR
+#
+
+gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
+ then echo $(1); else echo $(2); fi)
+
+M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector)
+
+CC = gcc
+LD = ld -m elf_i386
+SFLAGS = $(M32) -march=i386
+OBJCOPY = objcopy
+PERL = perl
+
+.SUFFIXES: .S .s .o .elf
+
+all: mbr.bin
+
+.PRECIOUS: %.o
+%.o: %.S
+ $(CC) $(SFLAGS) -Wa,-a=$*.lst -c -o $@ $<
+
+mbr.elf: mbr.o mbr.ld
+ $(LD) -T mbr.ld -e _start -o $@ $<
+
+mbr.bin: mbr.elf checksize.pl
+ $(OBJCOPY) -O binary $< $@
+ $(PERL) checksize.pl mbr.bin 440
+
+tidy:
+ rm -f *.o *.elf *.lst
+
+clean: tidy
+ rm -f *.bin
diff --git a/mbr/checksize.pl b/mbr/checksize.pl
new file mode 100755
index 00000000..b7d560a0
--- /dev/null
+++ b/mbr/checksize.pl
@@ -0,0 +1,31 @@
+## -----------------------------------------------------------------------
+##
+## Copyright 2007 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., 53 Temple Place Ste 330,
+## Boston MA 02111-1307, USA; either version 2 of the License, or
+## (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## checksize.pl
+##
+## Check the size of a binary file
+##
+
+($file, $maxsize) = @ARGV;
+
+@st = stat($file);
+if (!defined($size = $st[7])) {
+ die "$0: $file: $!\n";
+}
+if ($size > $maxsize) {
+ print STDERR "$file: too big ($size > $maxsize)\n";
+ exit 1;
+} else {
+ exit 0;
+}
+
diff --git a/mbr/mbr.S b/mbr/mbr.S
new file mode 100644
index 00000000..81e5dd00
--- /dev/null
+++ b/mbr/mbr.S
@@ -0,0 +1,299 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2007 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
+driveno = (stack-6)
+heads = (stack-8)
+sectors = (stack-10)
+
+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 /* es:di -> $PnP header */
+ pushw %di
+ pushw %dx /* 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 */
+ movw $0x4100, %ax
+ movw $0x55aa, %bx
+ xorw %cx, %cx
+ xorb %dh, %dh
+ stc
+ int $0x13
+ jc 1f
+ cmpw $0xaa55, %bx
+ jne 1f
+ testb $0x01, %cl
+ jz 1f
+
+ /* We have EBIOS; patch in a jump to read_sector_ebios */
+ movw $0xeb+((read_sector_ebios-read_sector_cbios-2)<< 8), (read_sector_cbios)
+
+1:
+ popw %dx
+
+ /* Get (C)HS geometry */
+ movb $0x08, %ah
+ int $0x13
+ xorw %ax, %ax
+ movb %dh, %al /* dh = number of heads */
+ incw %ax /* From 0-based to count */
+ pushw %ax /* Save heads on the stack */
+ andw $0x3f, %cx /* Sector count */
+ pushw %cx /* Save sectors on the stack */
+
+ xorl %eax, %eax
+ pushl %eax /* Base */
+ pushl %eax /* Root */
+ call scan_partition_table
+
+ /* If we get here, we have no OS */
+ jmp missing_os
+
+/*
+ * read_sector: read a single sector pointed to by %eax to 0x7c00.
+ * CF is set on error. All registers clobbered.
+ */
+read_sector:
+read_sector_cbios:
+ movl %eax, %edx
+ shrl $16, %edx
+ divw (sectors)
+ incw %dx
+ movw %dx, %cx
+ xorw %dx, %dx
+ divw (heads)
+ /* dx = head, ax = cylinder */
+ movb %al, %ch
+ shrw $2, %ax
+ shrw %ax
+ andb $0xc0, %al
+ orb %al, %cl
+ movb %dl, %dh
+ movw $bootsec, %bx
+ movw $0x0201, %ax
+ jmp read_common
+read_sector_ebios:
+ movw $dapa, %si
+ movl %eax, 8(%si)
+ movb $0x42, %ah
+read_common:
+ movb (driveno), %dl
+ int $0x13
+ ret
+
+/*
+ * read_partition_table:
+ * Read a partition table (pointed to by %eax), and copy
+ * the partition table into the ptab buffer.
+ * Preserve registers.
+ */
+ptab = _start+446
+
+read_partition_table:
+ pushal
+ call read_sector
+ jc 20f
+ movw $bootsec+446, %si
+ movw $ptab, %di
+ movw $(16*4/2), %cx
+ rep ; movsw
+20:
+ popal
+ ret
+
+/*
+ * scan_partition_table:
+ * Scan a partition table currently loaded in the partition table
+ * area. Preserve 16-bit registers.
+ *
+ * On stack:
+ * 18(%bp) - root (offset from MBR, or 0 for MBR)
+ * 22(%bp) - base (location of this partition table)
+ */
+
+scan_partition_table:
+ pusha
+ movw %sp, %bp
+
+ /* Search for active partitions */
+ movw $ptab, %di
+ movw $4, %cx
+ xorw %ax, %ax
+5:
+ testb $0x80, (%di)
+ jz 6f
+ incw %ax
+ movw %di, %si
+6:
+ addw $16, %di
+ loopw 5b
+
+ cmpw $1, %ax /* Number of active partitions found */
+ je boot
+ ja too_many_active
+
+ /* No active partitions found, look for extended partitions */
+ movw $ptab, %di
+ movb $4, %cl /* cx == 0 here */
+7:
+ movb 4(%di), %al
+ cmpb $0x05, %al /* MS-DOS extended */
+ je 8f
+ cmpb $0x0f, %al /* Win9x extended */
+ je 8f
+ cmpb $0x85, %al /* Linux extended */
+ jne 9f
+
+ /* It is an extended partition. Read the extended partition and
+ try to scan it. If the scan returns, re-load the current
+ partition table and resume scan. */
+8:
+ movl 8(%di), %eax /* Partition table offset */
+ movl 18(%bp), %edx /* "Root" */
+ addl %edx, %eax /* Compute location of new ptab */
+ andl %edx, %edx /* Is this the MBR? */
+ jnz 10f
+ movl %eax, %edx /* Offset -> root if this was MBR */
+10:
+ pushl %eax /* Push new base */
+ pushl %edx /* Push new root */
+ call read_partition_table
+ jc 11f
+ call scan_partition_table
+11:
+ addw $8, %sp
+ /* This returned, so we need to reload the current partition table */
+ movl 22(%bp), %eax
+ call read_partition_table
+
+ /* fall through */
+9:
+ /* Not an extended partition */
+ addw $16, %di
+ loopw 7b
+
+ /* Nothing found, return */
+ popa
+ ret
+
+/*
+ * boot: invoke the actual bootstrap. (%si) points to the partition
+ * table entry, and 22(%bp) has the partition table base.
+ */
+boot:
+ movl 8(%si), %eax
+ addl 22(%bp), %eax
+ movl %eax, 8(%si)
+ pushw %si
+ call read_sector
+ popw %si
+ jc disk_error
+ cmpw $0xaa55, (bootsec+510)
+ jne missing_os /* Not a valid boot sector */
+ movw $driveno, %sp
+ popw %dx /* dl -> drive number */
+ popw %di /* es:di -> $PnP vector */
+ popw %es
+ cli
+ jmp bootsec
+
+/*
+ * error messages
+ */
+missing_os:
+ movw $missing_os_msg, %si
+ jmp error
+disk_error:
+ movw $disk_error_msg, %si
+ jmp error
+too_many_active:
+ movw $too_many_active_msg, %si
+ /* jmp error */
+
+error:
+2:
+ lodsb
+ andb %al, %al
+ jz 3f
+ movb $0x0e, %ah
+ movb (BIOS_page), %bh
+ movb $0x07, %bl
+ int $0x10
+ jmp 2b
+3:
+ int $0x18 /* Boot failure */
+ jmp . /* Die */
+
+missing_os_msg:
+ .ascii "Missing operating system."
+ .byte 0
+disk_error_msg:
+ .ascii "Operating system load error."
+ .byte 0
+too_many_active_msg:
+ .ascii "Multiple active partitions."
+ .byte 0
+
+ .balign 4
+dapa:
+ .short 16 /* Size of packet */
+ .short 1 /* Sector count */
+ .short 0x7c00 /* Buffer offset */
+ .short 0 /* Buffer segment */
+ .long 0 /* LSW of LBA */
+ .long 0 /* MSW of LBA */
diff --git a/mbr/mbr.ld b/mbr/mbr.ld
new file mode 100644
index 00000000..d14ba802
--- /dev/null
+++ b/mbr/mbr.ld
@@ -0,0 +1,73 @@
+/*
+ * Linker script for MBR
+ */
+
+/* Script for -z combreloc: combine and sort reloc sections */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386",
+ "elf32-i386")
+OUTPUT_ARCH(i386)
+EXTERN(_start)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0x600;
+ .text :
+ {
+ *(.text*)
+ *(.rodata*)
+ } =0x90909090
+
+ . = ALIGN(4);
+ .data :
+ {
+ *(.data*)
+ }
+
+ . = ALIGN(128);
+ .bss :
+ {
+ *(.bss*)
+ }
+
+ . = 0x7c00;
+ .bootsec :
+ {
+ *(.bootsec)
+ }
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /DISCARD/ : { *(.note.GNU-stack) }
+}
diff --git a/mbr.asm b/mbr/oldmbr.asm
index 31bf1fdf..31bf1fdf 100644
--- a/mbr.asm
+++ b/mbr/oldmbr.asm
diff --git a/memdisk/Makefile b/memdisk/Makefile
index 1eebe637..72234cab 100644
--- a/memdisk/Makefile
+++ b/memdisk/Makefile
@@ -17,7 +17,7 @@ gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
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,)
+FREE := $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector,)
CC = gcc
CFLAGS = $(M32) $(FREE) -g -W -Wall -Wno-sign-compare \
diff --git a/menu/Makefile b/menu/Makefile
index 91a8697e..cee1c3af 100644
--- a/menu/Makefile
+++ b/menu/Makefile
@@ -17,7 +17,7 @@
gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
then echo $(1); else echo $(2); fi)
-M32 := $(call gcc_ok,-m32,)
+M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,)
CC = gcc
LD = ld -m elf_i386
diff --git a/mtools/Makefile b/mtools/Makefile
index 26909a30..546e3d14 100644
--- a/mtools/Makefile
+++ b/mtools/Makefile
@@ -1,8 +1,14 @@
+gcc_ok = $(shell if gcc $(1) ../dummy.c -o /dev/null 2>/dev/null; \
+ then echo '$(1)'; else echo '$(2)'; fi)
+
+comma := ,
+LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,)
+
CC = gcc
OPTFLAGS = -g -Os
INCLUDES = -I. -I.. -I../libfat
CFLAGS = -W -Wall -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES)
-LDFLAGS = -s
+LDFLAGS = $(LDHASH) -s
SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c $(wildcard ../libfat/*.c)
OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
diff --git a/mtools/syslinux.c b/mtools/syslinux.c
index 29259dff..e65b081f 100644
--- a/mtools/syslinux.c
+++ b/mtools/syslinux.c
@@ -210,7 +210,7 @@ int main(int argc, char *argv[])
exit(1);
}
fprintf(mtc,
- "MTOOLS_NO_VFAT=1\n"
+ /* "MTOOLS_NO_VFAT=1\n" */
"MTOOLS_SKIP_CHECK=1\n" /* Needed for some flash memories */
"drive s:\n"
" file=\"/proc/%lu/fd/%d\"\n"
diff --git a/sample/Makefile b/sample/Makefile
index e24ab5be..bacc57ca 100644
--- a/sample/Makefile
+++ b/sample/Makefile
@@ -17,7 +17,7 @@
gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
then echo $(1); else echo $(2); fi)
-M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,)
+M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector,)
CC = gcc
LD = ld -m elf_i386
diff --git a/ui.inc b/ui.inc
index 7c68fc54..ddde6bb5 100644
--- a/ui.inc
+++ b/ui.inc
@@ -316,10 +316,6 @@ vk_check:
; Find the kernel on disk
;
get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/extension
-%if IS_SYSLINUX || IS_MDSLINUX ; SYSLINUX has to deal with DOS mangled names...
- mov eax,[KernelName+8] ; Save initial extension
- mov [exten_table_end],eax ; Last case == initial ext.
-%else
mov di,KernelName+4*IS_PXELINUX
xor al,al
mov cx,FILENAME_MAX-5 ; Need 4 chars + null
@@ -327,7 +323,6 @@ get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/e
jne .no_skip
dec di ; Point to final null
.no_skip: mov [KernelExtPtr],di
-%endif
mov bx,exten_table
.search_loop: push bx
mov di,KernelName ; Search on disk
@@ -335,13 +330,9 @@ get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/e
pop bx
jnz kernel_good
mov eax,[bx] ; Try a different extension
-%if IS_SYSLINUX || IS_MDSLINUX
- mov [KernelName+8],eax
-%else
mov si,[KernelExtPtr]
mov [si],eax
mov byte [si+4],0
-%endif
add bx,byte 4
cmp bx,exten_table_end
jna .search_loop ; allow == case (final case)
@@ -485,10 +476,6 @@ kernel_good:
mov [KernelCNameLen],di
popa
-%if IS_SYSLINUX || IS_MDSLINUX
- mov ecx,[KernelName+7]
- mov cl,'.'
-%else
push di
push ax
mov di,KernelName+4*IS_PXELINUX
@@ -500,7 +487,6 @@ kernel_good:
.one_step: mov ecx,[di-4] ; 4 bytes before end
pop ax
pop di
-%endif
;
; At this point, DX:AX contains the size of the kernel, and SI contains
@@ -522,19 +508,13 @@ kernel_good:
je is_bss_sector
cmp ecx,'.bin'
je is_bootsector
-%if IS_SYSLINUX || IS_MDSLINUX
- cmp ecx,'.bs '
- je is_bootsector
- cmp ecx,'.0 '
- je is_bootsector
-%else
shr ecx,8
cmp ecx,'.bs'
je is_bootsector
shr ecx,8
cmp cx,'.0'
je is_bootsector
-%endif
+
; Otherwise Linux kernel
section .bss
diff --git a/unix/Makefile b/unix/Makefile
index 021aa538..f0ab279a 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -1,8 +1,14 @@
+gcc_ok = $(shell if gcc $(1) ../dummy.c -o /dev/null 2>/dev/null; \
+ then echo '$(1)'; else echo '$(2)'; fi)
+
+comma := ,
+LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,)
+
CC = gcc
OPTFLAGS = -g -Os
INCLUDES = -I. -I..
CFLAGS = -W -Wall -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES)
-LDFLAGS = -s
+LDFLAGS = $(LDHASH) -s
SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c
OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
diff --git a/unix/syslinux.c b/unix/syslinux.c
index 8b5a4cf6..4270d728 100644
--- a/unix/syslinux.c
+++ b/unix/syslinux.c
@@ -465,7 +465,7 @@ int main(int argc, char *argv[])
goto umount;
}
sprintf(ldlinux_name, "%s%s%s//ldlinux.sys",
- subdir ? "//" : "", subdir ? subdir : "", mntpath);
+ mntpath, subdir ? "//" : "", subdir ? subdir : "");
if ((fd = open(ldlinux_name, O_RDONLY)) >= 0) {
uint32_t zero_attr = 0;