diff options
author | H. Peter Anvin <hpa@zytor.com> | 2007-01-28 18:41:56 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2007-01-28 18:41:56 -0800 |
commit | 1970446f95df5ac0a0d3b2b0e90b72e0dd353699 (patch) | |
tree | 72f02e5c97af6a030e9fdead246f5ecae9f7532f | |
parent | 5c2c8ff329b1ae29edc2490bd44c42ada067a123 (diff) | |
parent | aa4b75f7257966f14940848366fa16087debe820 (diff) | |
download | syslinux-1970446f95df5ac0a0d3b2b0e90b72e0dd353699.tar.gz |
Merge with syslinux-3.35syslinux-3.40-pre4
Conflicts:
NEWS
version
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | Makefile.private | 6 | ||||
-rw-r--r-- | NEWS | 17 | ||||
-rw-r--r-- | TODO | 19 | ||||
-rw-r--r-- | abort.inc | 20 | ||||
-rw-r--r-- | com32/include/math.h | 7 | ||||
-rw-r--r-- | com32/lib/MCONFIG | 2 | ||||
-rw-r--r-- | com32/lib/math/strtod.c | 68 | ||||
-rw-r--r-- | comboot.doc | 25 | ||||
-rw-r--r-- | comboot.inc | 25 | ||||
-rw-r--r-- | config.inc | 4 | ||||
-rw-r--r-- | dos/syslinux.c | 83 | ||||
-rw-r--r-- | isolinux.asm | 4 | ||||
-rw-r--r-- | ldlinux.asm | 338 | ||||
-rw-r--r-- | memdisk/Makefile | 26 | ||||
-rw-r--r-- | memdisk/version.h | 4 | ||||
-rw-r--r-- | mtools/syslinux.c | 92 | ||||
-rw-r--r-- | sample/Makefile | 6 | ||||
-rw-r--r-- | syslinux.doc | 50 | ||||
-rw-r--r-- | syslinux.spec.in | 15 | ||||
-rw-r--r-- | ui.inc | 4 | ||||
-rw-r--r-- | unix/syslinux.c | 67 | ||||
-rw-r--r-- | win32/syslinux.c | 56 |
23 files changed, 682 insertions, 263 deletions
@@ -38,7 +38,7 @@ PERL = perl VERSION = $(shell cat version) -.c.o: +%.o: %.c $(CC) $(INCLUDE) $(CFLAGS) -c $< # @@ -196,9 +196,8 @@ libsyslinux.a: bootsect_bin.o ldlinux_bin.o mbr_bin.o syslxmod.o $(LIB_SO): bootsect_bin.o ldlinux_bin.o syslxmod.o $(CC) $(LDFLAGS) -shared -Wl,-soname,$(LIB_SONAME) -o $@ $^ -gethostip.o: gethostip.c - gethostip: gethostip.o + $(CC) $(LDFLAGS) -o $@ $^ mkdiskimage: mkdiskimage.in mbr.bin bin2hex.pl $(PERL) bin2hex.pl < mbr.bin | cat mkdiskimage.in - > $@ @@ -264,4 +263,4 @@ klibc: -include Makefile.private # Include dependencies file --include .depend +include .depend diff --git a/Makefile.private b/Makefile.private index ddbf75b0..63a3bbdf 100644 --- a/Makefile.private +++ b/Makefile.private @@ -1,6 +1,6 @@ ## -*- makefile -*- ------------------------------------------------------ ## -## Copyright 2000-2006 H. Peter Anvin - All Rights Reserved +## Copyright 2000-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 @@ -20,7 +20,7 @@ PRIVATE = Makefile.private .depend */.depend GIT_DIR ?= .git -ABS_GIT_DIR := $(shell cd '$(GIT_DIR)' && pwd) +ABS_GIT_DIR := $(shell cd '$(GIT_DIR)' 2>/dev/null && pwd) -include release/Makefile.secret @@ -43,7 +43,7 @@ official: release: test -d release rm -f '$(GIT_DIR)'/refs/tags/syslinux-$(VERSION) - cg-tag syslinux-$(VERSION) + cg-tag -f syslinux-$(VERSION) -rm -rf release/syslinux-$(VERSION) -rm -f release/syslinux-$(VERSION).* cd release && env GIT_DIR='$(ABS_GIT_DIR)' cg-export -r syslinux-$(VERSION) syslinux-$(VERSION) @@ -8,13 +8,26 @@ Changes in 3.40: * It is now supported to load a different configuration file with the CONFIG keyword. -Changes in 3.32: +Changes in 3.35: * MEMDISK: New "safeint" mode. * MEMDISK: Be more compliant with the PnP BIOS spec. * MEMDISK: Turn on EDD support by default. * MEMDISK: Try to work on some machines on which it would not work when there was no floppy drive in the system. - * Simple menu system: fix serial console support (broken in 3.30). + * Simple menu system: fix serial console support (broken in + 3.30). + * SYSLINUX: Support subdirectories. Like ISOLINUX, the + "current directory" is the directory in which syslinux.cfg + is found; this is searched for in the sequence + /boot/syslinux, /syslinux, /. As a side benefit, label names + like "linux-2.6.18" and "linux-2.6.19" are now supported. + + To install ldlinux.sys in a subdirectory, pass the -d + directory option to the SYSLINUX installer. + + This work was sponsored by slax.org (thanks, Tomas!) + * New API call: read disk. + * Invoke ONERROR on initrd load failure. Changes in 3.31: * The simple menu system (menu.c32 and vesamenu.c32) now @@ -1,6 +1,6 @@ *** To do in the short term: -- PXELINUX: Figure out localboot/idle problems +- PXELINUX: Figure out localboot/idle problems. - PXELINUX: Support changing the default server and boot file prefix? @@ -10,6 +10,10 @@ - Library support for all the comboot system calls. +- Deal with non-512-byte sectors (if I can get media which does...) + +- Add support for getting the hardware address on Infinibad. + *** Future projects: @@ -17,15 +21,14 @@ - Cleaned up documentation, with a real man page. -- Subdirectory support in SYSLINUX. - - Support files that span multiple input media (SYSLINUX) -> Seems to be getting less important; floppies are dying? -- Clean up the handling of sections +- Clean up the handling of sections. + +- API call to get directory listing. + +- COM32-based CLI. -- Add "localboot" support to SYSLINUX (using the ISOLINUX feature - set.) - OBSOLETE: chain.c32 is probably better. +- Rewrite the filesystems to run in protected mode C code. -- API call to get directory listing @@ -1,6 +1,6 @@ ; ----------------------------------------------------------------------- ; -; Copyright 2005-2006 H. Peter Anvin - All Rights Reserved +; Copyright 2005-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 @@ -33,8 +33,8 @@ abort_check: .ret1: ret .kill: mov si,aborted_msg - - ; ... fall through ... + mov bx,enter_command + jmp abort_load_chain ; ; abort_load: Called by various routines which wants to print a fatal @@ -44,10 +44,22 @@ abort_check: ; and the stack forcibly. ; ; SI = offset (in _text) of error message to print +; BX = future entry point (abort_load_chain) ; abort_load: + mov bx,error_or_command +abort_load_chain: RESET_STACK_AND_SEGS AX call cwritestr ; Expects SI -> error msg ; Return to the command prompt - jmp enter_command + jmp bx + +; +; error_or_command: Execute ONERROR if appropriate, otherwise enter_command +; +error_or_command: + mov cx,[OnerrorLen] + and cx,cx + jnz on_error + jmp enter_command
\ No newline at end of file diff --git a/com32/include/math.h b/com32/include/math.h index 5aaa9ada..e3d248fd 100644 --- a/com32/include/math.h +++ b/com32/include/math.h @@ -1,6 +1,13 @@ #ifndef _MATH_H #define _MATH_H +#ifndef __DBL_MIN_EXP__ +# define __DBL_MIN_EXP__ (-1021) +#endif +#ifndef __DBL_MAX_EXP__ +# define __DBL_MAX_EXP__ 1024 +#endif + double pow(double, double); double fabs(double); double strtod(const char *, char **); diff --git a/com32/lib/MCONFIG b/com32/lib/MCONFIG index b542196e..39b62db1 100644 --- a/com32/lib/MCONFIG +++ b/com32/lib/MCONFIG @@ -12,7 +12,7 @@ OBJCOPY = objcopy # zlib and libpng configuration flags LIBFLAGS = -DDYNAMIC_CRC_TABLE -DPNG_NO_CONSOLE_IO \ - -FPNG_NO_WRITE_SUPPORTED \ + -DPNG_NO_WRITE_SUPPORTED \ -DPNG_NO_MNG_FEATURES \ -DPNG_NO_READ_tIME -DPNG_NO_WRITE_tIME diff --git a/com32/lib/math/strtod.c b/com32/lib/math/strtod.c index f0b500cb..7289f90b 100644 --- a/com32/lib/math/strtod.c +++ b/com32/lib/math/strtod.c @@ -1,40 +1,42 @@ -// -// strtod.c -// -// Convert string to double -// -// Copyright (C) 2002 Michael Ringgaard. All rights reserved. -// Copyright (C) 2006 H. Peter Anvin. -// -// 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. -// 3. Neither the name of the project nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -// +/* + * strtod.c + * + * Convert string to double + * + * Copyright (C) 2002 Michael Ringgaard. All rights reserved. + * Copyright (C) 2006-2007 H. Peter Anvin. + * + * 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. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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 <errno.h> #include <ctype.h> #include <stdlib.h> +#include <math.h> static inline int is_real(double x) { diff --git a/comboot.doc b/comboot.doc index 23ab384e..00743835 100644 --- a/comboot.doc +++ b/comboot.doc @@ -340,7 +340,7 @@ AX=0009h [2.00] Call PXE Stack [PXELINUX ONLY] Input: AX 0009h BX PXE function number - ES:DI PXE data buffer + ES:DI PXE parameter structure buffer Output: AX PXE return status code Invoke an arbitrary PXE stack function. On SYSLINUX/ISOLINUX, @@ -362,8 +362,10 @@ AX=000Ah [2.00] Get Derivative-Specific Information [SYSLINUX, EXTLINUX] Input: AX 000Ah + CL 9 (to get a valid return in CL for all versions) Output: AL 31h (SYSLINUX), 34h (EXTLINUX) DL drive number + CL sector size as a power of 2 (9 = 512 bytes) [3.35] ES:BX pointer to partition table entry (if DL >= 80h) Note: This function was broken in EXTLINUX 3.00-3.02. @@ -413,6 +415,7 @@ AX=000Ah [2.00] Get Derivative-Specific Information Input: AX 000Ah Output: AL 33h (ISOLINUX) DL drive number + CL 11 (sector size as a power of 2) [3.35] ES:BX pointer to El Torito spec packet Note: Some very broken El Torito implementations do @@ -731,3 +734,23 @@ AX=0018h [3.30] Query custom font This call queries if a custom display font has been loaded via the "font" configuration file command. If no custom font has been loaded, AL contains zero. + + +AX=0019h [3.35] Read disk [SYSLINUX, ISOLINUX, EXTLINUX] + Input: AX 0019h + EDX Sector number + ESI Reserved - MUST BE ZERO + EDI Reserved - MUST BE ZERO + CX Sector count + ES:BX Buffer address + Output: None + + Read disk blocks from the active filesystem (partition); for + disks, sector number zero is the boot sector. For ISOLINUX, + this call reads the CD-ROM. + + For compatiblity with all systems, the buffer should + *neither* cross 64K boundaries, *nor* wrap around the segment. + + This routine reports "boot failed" (and does not return) on + disk error. diff --git a/comboot.inc b/comboot.inc index d93881a1..fac5753e 100644 --- a/comboot.inc +++ b/comboot.inc @@ -466,6 +466,7 @@ comapi_derinfo: mov P_DL,al mov P_ES,cs mov P_BX,PartInfo + mov P_CL,SECTOR_SHIFT %elif IS_PXELINUX mov ax,[APIVer] mov P_DX,ax @@ -482,6 +483,7 @@ comapi_derinfo: mov P_DL,al mov P_ES,cs mov P_BX,spec_packet + mov P_CL,SECTOR_SHIFT %endif clc ret @@ -775,7 +777,27 @@ comapi_userfont: mov P_AL,al ret - +; +; INT 22h AX=0019h Read disk +; +%if IS_SYSLINUX || IS_MDSLINUX || IS_ISOLINUX || IS_EXTLINUX +comapi_readdisk: + mov esi,P_ESI ; Enforce ESI == EDI == 0, these + or esi,P_EDI ; are reserved for future expansion + jnz .err + mov eax,P_EDX + mov bp,P_CX + mov es,P_ES + mov bx,P_BX + call getlinsec + clc + ret +.err: + stc + ret +%else +comapi_readdisk equ comapi_err +%endif section .data @@ -824,6 +846,7 @@ int22_table: dw comapi_runkernel ; 0016 run kernel image dw comapi_usingvga ; 0017 report video mode change dw comapi_userfont ; 0018 query custom font + dw comapi_readdisk ; 0019 read disk int22_count equ ($-int22_table)/2 APIKeyWait db 0 @@ -1,6 +1,6 @@ ;; ----------------------------------------------------------------------- ;; -;; Copyright 2002-2005 H. Peter Anvin - All Rights Reserved +;; Copyright 2002-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 @@ -38,6 +38,6 @@ BAUD_DIVISOR equ 115200 ; Serial port parameter ; %define version_str VERSION ; Must be 4 characters long! %define date DATE_STR ; Defined from the Makefile -%define year '2005' +%define year '2007' %endif ; _CONFIG_INC diff --git a/dos/syslinux.c b/dos/syslinux.c index f3b08367..31fb9050 100644 --- a/dos/syslinux.c +++ b/dos/syslinux.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1998-2004 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 @@ -36,7 +36,7 @@ uint16_t dos_version; void __attribute__((noreturn)) usage(void) { - puts("Usage: syslinux [-sfma] <drive>: [bootsecfile]\n"); + puts("Usage: syslinux [-sfma][-d directory] <drive>: [bootsecfile]\n"); exit(1); } @@ -51,6 +51,13 @@ void __attribute__((noreturn)) die(const char *msg) exit(1); } +void warning(const char *msg) +{ + puts("syslinux: warning: "); + puts(msg); + putchar('\n'); +} + /* * read/write wrapper functions */ @@ -63,7 +70,7 @@ int creat(const char *filename, int mode) rv = 0x3C00; asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv) + : "=bcdm" (err), "+a" (rv) : "c" (mode), "d" (filename)); if ( err ) { dprintf("rv = %d\n", rv); @@ -87,6 +94,26 @@ void close(int fd) and we really don't care... */ } +int rename(const char *oldname, const char *newname) +{ + uint16_t rv = 0x5600; /* Also support 43FFh? */ + uint8_t err; + + dprintf("rename(\"%s\", \"%s\")\n", oldname, newname); + + asm volatile("int $0x21 ; setc %0" + : "=bcdm" (err), "+a" (rv) + : "d" (oldname), "D" (newname)); + + if ( err ) { + dprintf("rv = %d\n", rv); + warning("cannot move ldlinux.sys"); + return rv; + } + + return 0; +} + ssize_t write_file(int fd, const void *buf, size_t count) { uint16_t rv; @@ -449,7 +476,7 @@ int main(int argc, char *argv[]) { static unsigned char sectbuf[512]; int dev_fd, fd; - static char ldlinux_name[] = "@:\\LDLINUX.SYS"; + static char ldlinux_name[] = "@:\\ldlinux.sys"; char **argp, *opt; int force = 0; /* -f (force) option */ struct libfat_filesystem *fs; @@ -461,6 +488,7 @@ int main(int argc, char *argv[]) int i; int writembr = 0; /* -m (write MBR) option */ int set_active = 0; /* -a (set partition active) option */ + const char *subdir = NULL; dprintf("argv = %p\n", argv); for ( i = 0 ; i <= argc ; i++ ) @@ -490,6 +518,10 @@ int main(int argc, char *argv[]) case 'a': /* Set partition active */ set_active = 1; break; + case 'd': + if ( argp[1] ) + subdir = *++argp; + break; default: usage(); } @@ -558,6 +590,49 @@ int main(int argc, char *argv[]) libfat_close(fs); /* + * If requested, move ldlinux.sys + */ + if (subdir) { + char new_ldlinux_name[160]; + char *cp = new_ldlinux_name+3; + const char *sd; + int slash = 1; + + new_ldlinux_name[0] = dev_fd | 0x40; + new_ldlinux_name[1] = ':'; + new_ldlinux_name[2] = '\\'; + + for (sd = subdir; *sd; sd++) { + char c = *sd; + + if (c == '/' || c == '\\') { + if (slash) + continue; + c = '\\'; + slash = 1; + } else { + slash = 0; + } + + *cp++ = c; + } + + /* Skip if subdirectory == root */ + if (cp > new_ldlinux_name+3) { + if (!slash) + *cp++ = '\\'; + + memcpy(cp, "ldlinux.sys", 12); + + set_attributes(ldlinux_name, 0); + if (rename(ldlinux_name, new_ldlinux_name)) + set_attributes(ldlinux_name, 0x07); + else + set_attributes(new_ldlinux_name, 0x07); + } + } + + /* * Patch ldlinux.sys and the boot sector */ syslinux_patch(sectors, nsectors); diff --git a/isolinux.asm b/isolinux.asm index 91746260..35827f14 100644 --- a/isolinux.asm +++ b/isolinux.asm @@ -1381,9 +1381,9 @@ mangle_name: .mn_end: cmp bx,di ; At the beginning of the buffer? jbe .mn_zero - cmp byte [di-1],'.' ; Terminal dot? + cmp byte [es:di-1],'.' ; Terminal dot? je .mn_kill - cmp byte [di-1],'/' ; Terminal slash? + cmp byte [es:di-1],'/' ; Terminal slash? jne .mn_zero .mn_kill: dec di ; If so, remove it inc cx diff --git a/ldlinux.asm b/ldlinux.asm index a3b24a8c..d1c0c65a 100644 --- a/ldlinux.asm +++ b/ldlinux.asm @@ -11,7 +11,7 @@ ; from MS-LOSS, and can be especially useful in conjunction with the ; umsdos filesystem. ; -; Copyright (C) 1994-2005 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 @@ -30,9 +30,9 @@ ; Some semi-configurable constants... change on your own risk. ; my_id equ syslinux_id -FILENAME_MAX_LG2 equ 4 ; log2(Max filename size Including final null) -FILENAME_MAX equ 11 ; Max mangled filename size -NULLFILE equ ' ' ; First char space == null filename +FILENAME_MAX_LG2 equ 6 ; log2(Max filename size Including final null) +FILENAME_MAX equ (1<<FILENAME_MAX_LG2) ; Max mangled filename size +NULLFILE equ 0 ; First char space == null filename NULLOFFSET equ 0 ; Position in which to look retry_count equ 16 ; How patient are we with the disk? %assign HIGHMEM_SLOP 0 ; Avoid this much memory near the top @@ -900,9 +900,18 @@ getfattype: ; ; Load configuration file ; - mov di,syslinux_cfg + mov di,syslinux_cfg1 + call open + jnz .config_open + mov di,syslinux_cfg2 + call open + jnz .config_open + mov di,syslinux_cfg3 call open jz no_config_file +.config_open: + mov eax,[PrevDir] ; Make the directory with syslinux.cfg ... + mov [CurrentDir],eax ; ... the current directory ; ; Now we have the config file open. Parse the config file and @@ -955,23 +964,27 @@ allocate_file: ret ; -; searchdir: -; Search the root directory for a pre-mangled filename in DS:DI. +; search_dos_dir: +; Search a specific directory for a pre-mangled filename in +; MangledBuf, in the directory starting in sector EAX. ; ; NOTE: This file considers finding a zero-length file an ; error. This is so we don't have to deal with that special ; case elsewhere in the program (most loops have the test ; at the end). ; +; Assumes DS == ES == CS. +; ; If successful: ; ZF clear ; SI = file pointer -; DX:AX = file length in bytes +; EAX = file length (MAY BE ZERO!) +; DL = file attributes ; If unsuccessful ; ZF set ; -searchdir: +search_dos_dir: push bx call allocate_file jnz .alloc_failure @@ -982,9 +995,8 @@ searchdir: push ds pop es ; ES = DS - mov eax,[RootDir] ; First root directory sector - .scansector: + ; EAX <- directory sector to scan call getcachesector ; GS:SI now points to this sector @@ -992,15 +1004,20 @@ searchdir: .scanentry: cmp byte [gs:si],0 jz .failure ; Hit directory high water mark + test byte [gs:si+11],8 ; Ignore volume labels and + ; VFAT long filename entries + jnz .nomatch push cx push si push di + mov di,MangledBuf mov cx,11 gs repe cmpsb pop di pop si pop cx jz .found +.nomatch: add si,32 loop .scanentry @@ -1020,8 +1037,7 @@ searchdir: mov eax,[gs:si+28] ; File size add eax,SECTOR_SIZE-1 shr eax,SECTOR_SHIFT - jz .failure ; Zero-length file - mov [bx+4],eax + mov [bx+4],eax ; Sector count mov cl,[ClustShift] mov dx,[gs:si+20] ; High cluster word @@ -1033,9 +1049,9 @@ searchdir: mov [bx],edx ; Starting sector mov eax,[gs:si+28] ; File length again - mov dx,[gs:si+30] ; 16-bitism, sigh - mov si,bx - and eax,eax ; ZF <- 0 + mov dl,[gs:si+11] ; File attribute + mov si,bx ; File pointer... + and si,si ; ZF <- 0 pop es pop gs @@ -1044,6 +1060,91 @@ searchdir: ret ; +; searchdir: +; +; Open a file +; +; On entry: +; DS:DI = filename +; If successful: +; ZF clear +; SI = file pointer +; DX:AX or EAX = file length in bytes +; If unsuccessful +; ZF set +; +; Assumes CS == DS == ES, and trashes BX and CX. +; +searchdir: + mov eax,[CurrentDir] + cmp byte [di],'/' ; Root directory? + jne .notroot + mov eax,[RootDir] + inc di +.notroot: + +.pathwalk: + push eax ; <A> Current directory sector + mov si,di +.findend: + lodsb + cmp al,' ' + jbe .endpath + cmp al,'/' + jne .findend +.endpath: + xchg si,di + pop eax ; <A> Current directory sector + + mov [PrevDir],eax ; Remember last directory searched + + push di + call mangle_dos_name ; MangledBuf <- component + call search_dos_dir + pop di + jz .notfound ; Pathname component missing + + cmp byte [di-1],'/' ; Do we expect a directory + je .isdir + + ; Otherwise, it should be a file +.isfile: + test dl,18h ; Subdirectory|Volume Label + jnz .badfile ; If not a file, it's a bad thing + + ; SI and EAX are already set + mov edx,eax + shr edx,16 ; Old 16-bit remnant... + and eax,eax ; EAX != 0 + jz .badfile + ret ; Done! + + ; If we expected a directory, it better be one... +.isdir: + test dl,10h ; Subdirectory + jz .badfile + + xor eax,eax + xchg eax,[si+file_sector] ; Get sector number and free file structure + jmp .pathwalk ; Walk the next bit of the path + +.badfile: + xor eax,eax + mov [si],eax ; Free file structure + +.notfound: + xor eax,eax + xor dx,dx + ret + + section .bss + alignb 4 +CurrentDir resd 1 ; Current directory +PrevDir resd 1 ; Last scanned directory + + section .text + +; ; ; kaboom2: once everything is loaded, replace the part of kaboom ; starting with "kaboom.patch" with this part @@ -1057,115 +1158,138 @@ kaboom2: .norge: jmp short .norge ; If int 19h returned; this is the end ; -; mangle_name: Mangle a DOS filename pointed to by DS:SI into a buffer pointed -; to by ES:DI; ends on encountering any whitespace +; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed +; to by ES:DI; ends on encountering any whitespace. +; +; This verifies that a filename is < FILENAME_MAX characters, +; doesn't contain whitespace, zero-pads the output buffer, +; and removes trailing dots and redundant slashes, plus changes +; backslashes to forward slashes, +; so "repe cmpsb" can do a compare, and the path-searching routine +; gets a bit of an easier job. +; ; - mangle_name: + push bx + xor ax,ax + mov cx,FILENAME_MAX-1 + mov bx,di + +.mn_loop: + lodsb + cmp al,' ' ; If control or space, end + jna .mn_end + cmp al,'\' ; Backslash? + jne .mn_not_bs + mov al,'/' ; Change to forward slash +.mn_not_bs: + cmp al,ah ; Repeated slash? + je .mn_skip + xor ah,ah + cmp al,'/' + jne .mn_ok + mov ah,al +.mn_ok stosb +.mn_skip: loop .mn_loop +.mn_end: + cmp bx,di ; At the beginning of the buffer? + jbe .mn_zero + cmp byte [es:di-1],'.' ; Terminal dot? + je .mn_kill + cmp byte [es:di-1],'/' ; Terminal slash? + jne .mn_zero +.mn_kill: dec di ; If so, remove it + inc cx + jmp short .mn_end +.mn_zero: + inc cx ; At least one null byte + xor ax,ax ; Zero-fill name + rep stosb + pop bx + ret ; Done + +; +; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled +; filename to the conventional representation. This is needed +; for the BOOT_IMAGE= parameter for the kernel. +; NOTE: A 13-byte buffer is mandatory, even if the string is +; known to be shorter. +; +; DS:SI -> input mangled file name +; ES:DI -> output buffer +; +; On return, DI points to the first byte after the output name, +; which is set to a null byte. +; +unmangle_name: call strcpy + dec di ; Point to final null byte + ret + +; +; mangle_dos_name: +; Mangle a DOS filename component pointed to by DS:SI +; into [MangledBuf]; ends on encountering any whitespace or slash. +; Assumes CS == DS == ES. +; + +mangle_dos_name: + pusha + mov di,MangledBuf + mov cx,11 ; # of bytes to write -mn_loop: +.loop: lodsb cmp al,' ' ; If control or space, end - jna mn_end + jna .end + cmp al,'/' ; Slash, too + je .end cmp al,'.' ; Period -> space-fill - je mn_is_period + je .is_period cmp al,'a' - jb mn_not_lower + jb .not_lower cmp al,'z' - ja mn_not_uslower + ja .not_uslower sub al,020h - jmp short mn_not_lower -mn_is_period: mov al,' ' ; We need to space-fill -mn_period_loop: cmp cx,3 ; If <= 3 characters left - jbe mn_loop ; Just ignore it + jmp short .not_lower +.is_period: mov al,' ' ; We need to space-fill +.period_loop: cmp cx,3 ; If <= 3 characters left + jbe .loop ; Just ignore it stosb ; Otherwise, write a period - loop mn_period_loop ; Dec CX and (always) jump -mn_not_uslower: cmp al,ucase_low - jb mn_not_lower + loop .period_loop ; Dec CX and (always) jump +.not_uslower: cmp al,ucase_low + jb .not_lower cmp al,ucase_high - ja mn_not_lower + ja .not_lower mov bx,ucase_tab-ucase_low - cs xlatb -mn_not_lower: stosb - loop mn_loop ; Don't continue if too long -mn_end: + xlatb +.not_lower: stosb + loop .loop ; Don't continue if too long +.end: mov al,' ' ; Space-fill name rep stosb ; Doesn't do anything if CX=0 + popa ret ; Done + section .bss +MangledBuf resb 11 + + section .text ; -; Upper-case table for extended characters; this is technically code page 865, +; Case tables for extended characters; this is technically code page 865, ; but code page 437 users will probably not miss not being able to use the ; cent sign in kernel images too much :-) ; ; The table only covers the range 129 to 164; the rest we can deal with. ; + section .data + ucase_low equ 129 ucase_high equ 164 ucase_tab db 154, 144, 'A', 142, 'A', 143, 128, 'EEEIII' db 142, 143, 144, 146, 146, 'O', 153, 'OUUY', 153, 154 db 157, 156, 157, 158, 159, 'AIOU', 165 -; -; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled -; filename to the conventional representation. This is needed -; for the BOOT_IMAGE= parameter for the kernel. -; NOTE: A 13-byte buffer is mandatory, even if the string is -; known to be shorter. -; -; DS:SI -> input mangled file name -; ES:DI -> output buffer -; -; On return, DI points to the first byte after the output name, -; which is set to a null byte. -; -unmangle_name: - push si ; Save pointer to original name - mov cx,8 - mov bp,di -un_copy_body: lodsb - call lower_case - stosb - cmp al,' ' - jbe un_cb_space - mov bp,di ; Position of last nonblank+1 -un_cb_space: loop un_copy_body - mov di,bp - mov al,'.' ; Don't save - stosb - mov cx,3 -un_copy_ext: lodsb - call lower_case - stosb - cmp al,' ' - jbe un_ce_space - mov bp,di -un_ce_space: loop un_copy_ext - mov di,bp - mov byte [es:di], 0 - pop si - ret - -; -; lower_case: Lower case a character in AL -; -lower_case: - cmp al,'A' - jb lc_ret - cmp al,'Z' - ja lc_1 - or al,20h - ret -lc_1: cmp al,lcase_low - jb lc_ret - cmp al,lcase_high - ja lc_ret - push bx - mov bx,lcase_tab-lcase_low - cs xlatb - pop bx -lc_ret: ret - + section .text ; ; getfssec_edx: Get multiple sectors from a file ; @@ -1425,16 +1549,6 @@ getfatsector: ; ----------------------------------------------------------------------------- section .data -; -; Lower-case table for codepage 865 -; -lcase_low equ 128 -lcase_high equ 165 -lcase_tab db 135, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138 - db 139, 140, 141, 132, 134, 130, 145, 145, 147, 148, 149 - db 150, 151, 152, 148, 129, 155, 156, 155, 158, 159, 160 - db 161, 162, 163, 164, 164 - copyright_str db ' Copyright (C) 1994-', year, ' H. Peter Anvin' db CR, LF, 0 boot_prompt db 'boot: ', 0 @@ -1471,11 +1585,11 @@ aborted_msg db ' aborted.' ; Fall through to crlf_msg! crlf_msg db CR, LF null_msg db 0 crff_msg db CR, FF, 0 -syslinux_cfg db 'SYSLINUXCFG' ; Mangled form -ConfigName db 'syslinux.cfg',0 ; Unmangled form -%if IS_MDSLINUX -manifest db 'MANIFEST ' -%endif +syslinux_cfg1 db '/boot' ; /boot/syslinux/syslinux.cfg +syslinux_cfg2 db '/syslinux' ; /syslinux/syslinux.cfg +syslinux_cfg3 db '/' ; /syslinux.cfg +ConfigName db 'syslinux.cfg', 0 ; syslinux.cfg + ; ; Command line options we'd like to take a look at ; diff --git a/memdisk/Makefile b/memdisk/Makefile index f628ff24..1eebe637 100644 --- a/memdisk/Makefile +++ b/memdisk/Makefile @@ -1,6 +1,6 @@ ## ----------------------------------------------------------------------- ## -## Copyright 2001-2004 H. Peter Anvin - All Rights Reserved +## Copyright 2001-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 @@ -19,11 +19,12 @@ 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,) -CC = gcc $(M32) $(FREE) -CFLAGS = -g -W -Wall -Wno-sign-compare \ +CC = gcc +CFLAGS = $(M32) $(FREE) -g -W -Wall -Wno-sign-compare \ -Os -fomit-frame-pointer -march=i386 $(ALIGN) \ -DVERSION='"$(VERSION)"' -DDATE='"$(DATE)"' -LDFLAGS = -g +SFLAGS = $(M32) -march=i386 -D__ASSEMBLY__ +LDFLAGS = $(M32) -g INCLUDE = -I../com32/include LD = ld -m elf_i386 NASM = nasm -O99 @@ -38,7 +39,7 @@ OBJS32 = start32.o setup.o msetup.o e820func.o conio.o memcpy.o memset.o \ unzip.o memdisk.o CSRC = setup.c msetup.c e820func.c conio.c unzip.c -SSRC = +SSRC = start32.S memcpy.S memset.S NASMSRC = memdisk.asm memdisk16.asm all: memdisk e820test @@ -57,10 +58,13 @@ spotless: clean $(NASM) $(NFLAGS) -f elf -l $*.lst -o $@ $< %.o: %.s - $(CC) -x assembler -c -o $@ $< + $(CC) $(SFLAGS) -c -o $@ $< + +%.o: %.S + $(CC) $(INCLUDE) $(SFLAGS) -c -o $@ $< %.o16: %.s16 - $(CC) -x assembler -c -o $@ $< + $(CC) $(SFLAGS) -x assembler -c -o $@ $< %.o: %.c $(CC) $(INCLUDE) $(CFLAGS) -c -o $@ $< @@ -69,10 +73,10 @@ spotless: clean echo '.code16gcc' | cat - $< > $@ %.s: %.S - $(CC) $(INCLUDE) $(CFLAGS) -D__ASSEMBLY__ -E -o $@ $< + $(CC) $(INCLUDE) $(SFLAGS) -E -o $@ $< %.s16: %.S16 - $(CC) $(INCLUDE) $(CFLAGS) -D__ASSEMBLY__ -E -o $@ $< + $(CC) $(INCLUDE) $(SFLAGS) -x assembler-with-cpp -E -o $@ $< %.s: %.c $(CC) $(INCLUDE) $(CFLAGS) -S -o $@ $< @@ -106,8 +110,8 @@ memdisk.o: memdisk.bin .depend: rm -f .depend - for csrc in *.c ; do $(CC) $(INCLUDE) -MM $$csrc | sed -e 's/\.o/\.s/' >> .depend ; done - for ssrc in $(SSRC) ; do $(CC) $(INCLUDE) -x c -traditional -MM $$ssrc | sed -e 's/\.S16\.o/\.o16/' >> .depend ; done + for csrc in *.c ; do $(CC) $(INCLUDE) $(CFLAGS) -MM $$csrc >> .depend ; done + for ssrc in *.S ; do $(CC) $(INCLUDE) $(SFLAGS) -MM $$ssrc >> .depend ; done for nsrc in $(NASMSRC) ; do $(NASM) -DDEPEND $(NINCLUDE) -o `echo $$nsrc | sed -e 's/\.asm/\.bin/'` -M $$nsrc >> .depend ; done depend: diff --git a/memdisk/version.h b/memdisk/version.h index 9d457388..ceca7961 100644 --- a/memdisk/version.h +++ b/memdisk/version.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 2002 H. Peter Anvin - All Rights Reserved + * Copyright 2002-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 @@ -20,6 +20,6 @@ #define MEMDISK_VERSION_H #define FIRSTYEAR "2001" -#define COPYYEAR "2005" +#define COPYYEAR "2007" #endif diff --git a/mtools/syslinux.c b/mtools/syslinux.c index b55d2d49..29259dff 100644 --- a/mtools/syslinux.c +++ b/mtools/syslinux.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1998-2004 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 @@ -45,7 +45,7 @@ off_t filesystem_offset = 0; /* Offset of filesystem */ void __attribute__((noreturn)) usage(void) { - fprintf(stderr, "Usage: %s [-sf] [-o offset] device\n", program); + fprintf(stderr, "Usage: %s [-sf][-d directory][-o offset] device\n", program); exit(1); } @@ -131,6 +131,7 @@ int main(int argc, char *argv[]) char **argp, *opt; int force = 0; /* -f (force) option */ char mtools_conf[] = "/tmp/syslinux-mtools-XXXXXX"; + const char *subdir = NULL; int mtc_fd; FILE *mtc, *mtp; struct libfat_filesystem *fs; @@ -157,6 +158,8 @@ int main(int argc, char *argv[]) syslinux_make_stupid(); /* Use "safe, slow and stupid" code */ } else if ( *opt == 'f' ) { force = 1; /* Force install */ + } else if ( *opt == 'd' && argp[1] ) { + subdir = *++argp; } else if ( *opt == 'o' && argp[1] ) { filesystem_offset = (off_t)strtoull(*++argp, NULL, 0); /* Byte offset */ } else { @@ -226,9 +229,9 @@ int main(int argc, char *argv[]) } /* This command may fail legitimately */ - system("mattrib -h -r -s s:ldlinux.sys 2>/dev/null"); + system("mattrib -h -r -s s:/ldlinux.sys 2>/dev/null"); - mtp = popen("mcopy -D o -D O -o - s:ldlinux.sys", "w"); + mtp = popen("mcopy -D o -D O -o - s:/ldlinux.sys", "w"); if ( !mtp || (fwrite(syslinux_ldlinux, 1, syslinux_ldlinux_len, mtp) != syslinux_ldlinux_len) || @@ -236,16 +239,6 @@ int main(int argc, char *argv[]) die("failed to create ldlinux.sys"); } - status = system("mattrib +r +h +s s:ldlinux.sys"); - - if ( !WIFEXITED(status) || WEXITSTATUS(status) ) { - fprintf(stderr, - "%s: warning: failed to set system bit on ldlinux.sys\n", - program); - } - - unlink(mtools_conf); - /* * Now, use libfat to create a block map */ @@ -261,15 +254,76 @@ int main(int argc, char *argv[]) } libfat_close(fs); - /* - * Patch ldlinux.sys and the boot sector - */ + /* Patch ldlinux.sys and the boot sector */ syslinux_patch(sectors, nsectors); + /* Write the now-patched first sector of ldlinux.sys */ + xpwrite(dev_fd, syslinux_ldlinux, 512, + filesystem_offset + ((off_t)sectors[0] << 9)); + + /* Move ldlinux.sys to the desired location */ + if (subdir) { + char target_file[4096], command[5120]; + char *cp = target_file, *ep = target_file+sizeof target_file-16; + const char *sd; + int slash = 1; + + cp += sprintf(cp, "'s:/"); + for (sd = subdir; *sd; sd++) { + if (*sd == '/' || *sd == '\\') { + if (slash) + continue; /* Remove duplicated slashes */ + slash = 1; + } else if (*sd == '\'' || *sd == '!') { + slash = 0; + if (cp < ep) *cp++ = '\''; + if (cp < ep) *cp++ = '\\'; + if (cp < ep) *cp++ = *sd; + if (cp < ep) *cp++ = '\''; + continue; + } else { + slash = 0; + } + + if (cp < ep) + *cp++ = *sd; + } + if (!slash) + *cp++ = '/'; + strcpy(cp, "ldlinux.sys'"); + + /* This command may fail legitimately */ + sprintf(command, "mattrib -h -r -s %s 2>/dev/null", target_file); + system(command); + + sprintf(command, "mmove -D o -D O s:/ldlinux.sys %s", target_file); + status = system(command); + + if ( !WIFEXITED(status) || WEXITSTATUS(status) ) { + fprintf(stderr, + "%s: warning: unable to move ldlinux.sys\n", + program); + + status = system("mattrib +r +h +s s:/ldlinux.sys"); + } else { + sprintf(command, "mattrib +r +h +s %s", target_file); + status = system(command); + } + } else { + status = system("mattrib +r +h +s s:/ldlinux.sys"); + } + + if ( !WIFEXITED(status) || WEXITSTATUS(status) ) { + fprintf(stderr, + "%s: warning: failed to set system bit on ldlinux.sys\n", + program); + } + + /* - * Write the now-patched first sector of ldlinux.sys + * Cleanup */ - xpwrite(dev_fd, syslinux_ldlinux, 512, filesystem_offset + ((off_t)sectors[0] << 9)); + unlink(mtools_conf); /* * To finish up, write the boot sector diff --git a/sample/Makefile b/sample/Makefile index b92f820b..e24ab5be 100644 --- a/sample/Makefile +++ b/sample/Makefile @@ -19,13 +19,13 @@ gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \ M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) -CC = gcc $(M32) +CC = gcc LD = ld -m elf_i386 AR = ar NASM = nasm RANLIB = ranlib -CFLAGS = -W -Wall -march=i386 -Os -fomit-frame-pointer -I../com32/include -SFLAGS = -march=i386 +CFLAGS = $(M32) -W -Wall -march=i386 -Os -fomit-frame-pointer -I../com32/include +SFLAGS = $(M32) -march=i386 LDFLAGS = -s OBJCOPY = objcopy PPMTOLSS16 = ../ppmtolss16 diff --git a/syslinux.doc b/syslinux.doc index 75968f66..a5500873 100644 --- a/syslinux.doc +++ b/syslinux.doc @@ -36,9 +36,9 @@ In order to create a bootable Linux floppy using SYSLINUX, prepare a normal MS-DOS formatted floppy. Copy one or more Linux kernel files to it, then execute the DOS command: - syslinux [-s] a: + syslinux [-sfma][-d directory] a: -(or whichever drive letter is appropriate; the [] meaning -s is optional) +(or whichever drive letter is appropriate; the [] meaning optional.) Use "syslinux.com" (in the dos subdirectory of the distribution) for plain DOS (MS-DOS, DR-DOS, PC-DOS, FreeDOS...) or Win9x/ME. @@ -48,12 +48,13 @@ WinNT/2000/XP. Under Linux, execute the command: - syslinux [-s] [-o offset] /dev/fd0 + syslinux [-sf][-d directory][-o offset] /dev/fd0 (or, again, whichever device is the correct one.) This will alter the boot sector on the disk and copy a file named -LDLINUX.SYS into its root directory. +LDLINUX.SYS into its root directory (or a subdirectory, if the -d +option is specified.) The -s option, if given, will install a "safe, slow and stupid" version of SYSLINUX. This version may work on some very buggy BIOSes @@ -65,6 +66,10 @@ mode. The -o option is used with a disk image file and specifies the byte offset of the filesystem image in the file. +For the DOS and Windows installers, the -m and -a options can be used +on hard drives to write a Master Boot Record (MBR), and to mark the +specific partition active. + On boot time, by default, the kernel will be loaded from the image named LINUX on the boot floppy. This default can be changed, see the section on the SYSLINUX config file. @@ -86,10 +91,17 @@ which requires root privilege. ++++ CONFIGURATION FILE ++++ All the configurable defaults in SYSLINUX can be changed by putting a -file called SYSLINUX.CFG in the root directory of the boot floppy. This -is a text file in either UNIX or DOS format, containing one or more of -the following items (case is insensitive for keywords; upper case is used -here to indicate that a word should be typed verbatim): +file called "syslinux.cfg" in the root directory of the boot disk. + +This is a text file in either UNIX or DOS format, containing one or +more of the following items (case is insensitive for keywords; upper +case is used here to indicate that a word should be typed verbatim): + +Starting with version 3.35, the configuration file can also be in +either the /boot/syslinux or /syslinux directories (searched in that +order.) If that is the case, then all filenames are assumed to be +relative to that same directory, unless preceded with a slash or +backslash. All options here applies to PXELINUX, ISOLINUX and EXTLINUX as well as SYSLINUX unless otherwise noted. See the respective .doc files. @@ -174,14 +186,11 @@ LABEL label kernel mykernel append myoptions - Notes: Labels are mangled as if they were filenames, and must be - unique after mangling. For example, two labels - "v2.1.30" and "v2.1.31" will not be distinguishable - under SYSLINUX, since both mangle to the same DOS filename. - This is also true for "foo bar" and "foo baz". + Note: The "kernel" doesn't have to be a Linux kernel; it can + be a boot sector or a COMBOOT file (see below.) - The "kernel" doesn't have to be a Linux kernel; it can - be a boot sector or a COMBOOT file (see below.) + Since version 3.32 label names are no longer mangled into DOS + format (for SYSLINUX.) LINUX image - Linux kernel image (default) BOOT image - Bootstrap program (.bs, .0, .bin) @@ -688,10 +697,13 @@ The Linux boot protocol supports a "boot loader ID", a single byte where the upper nybble specifies a boot loader family (3 = SYSLINUX) and the lower nybble is version or, in the case of SYSLINUX, media: - 0x31 = SYSLINUX - 0x32 = PXELINUX - 0x33 = ISOLINUX - 0x34 = EXTLINUX + 0x31 (49) = SYSLINUX + 0x32 (50) = PXELINUX + 0x33 (51) = ISOLINUX + 0x34 (52) = EXTLINUX + +In recent versions of Linux, this ID is available as +/proc/sys/kernel/bootloader_type. ++++ BUG REPORTS ++++ diff --git a/syslinux.spec.in b/syslinux.spec.in index b6128e79..115a6f20 100644 --- a/syslinux.spec.in +++ b/syslinux.spec.in @@ -15,8 +15,10 @@ BuildPrereq: nasm >= 0.98.38, perl Autoreq: 0 %ifarch x86_64 Requires: mtools, libc.so.6()(64bit) +%define my_cc gcc %else Requires: mtools, libc.so.6 +%define my_cc gcc -m32 %endif # NOTE: extlinux belongs in /sbin, not in /usr/sbin, since it is typically @@ -61,9 +63,9 @@ booting in the /tftpboot directory. %setup -q -n syslinux-%{VERSION} %build -make clean -make installer -make -C sample tidy +make CC='%{my_cc}' clean +make CC='%{my_cc}' installer +make CC='%{my_cc}' -C sample tidy %install rm -rf %{buildroot} @@ -72,10 +74,10 @@ mkdir -p %{buildroot}%{_sbindir} mkdir -p %{buildroot}%{_datadir}/syslinux mkdir -p %{buildroot}%{_includedir} mkdir -p %{buildroot}/boot %{buildroot}/tftpboot/pxelinux.cfg -make install-all \ +make CC='%{my_cc}' install-all \ INSTALLROOT=%{buildroot} BINDIR=%{_bindir} SBINDIR=%{_sbindir} \ LIBDIR=%{_datadir} INCDIR=%{_includedir} -make -C sample tidy +make CC='%{my_cc}' -C sample tidy cp mkdiskimage sys2ansi.pl keytab-lilo.pl %{buildroot}%{_datadir}/syslinux cp %{buildroot}%{_datadir}/syslinux/*.c32 %{buildroot}/boot cp %{buildroot}%{_datadir}/syslinux/memdisk %{buildroot}/boot @@ -121,6 +123,9 @@ if [ -f /boot/extlinux.conf ]; then extlinux --update /boot; fi %postun %changelog +* Thu Jan 25 2007 H. Peter Anvin <hpa@zytor.com> +- Hacks to make the 32-bit version build correctly on 64-bit machines. + * Mon Sep 19 2006 H. Peter Anvin <hpa@zytor.com> - Add a syslinux-tftpboot module. - Factor extlinux into its own package. @@ -1,6 +1,6 @@ ;; ----------------------------------------------------------------------- ;; -;; Copyright 1994-2005 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 @@ -376,7 +376,7 @@ bad_kernel: jmp abort_load ; Ask user for clue ; -; on_error: bad kernel, but we have onerror set +; on_error: bad kernel, but we have onerror set; CX = OnerrorLen ; on_error: mov si,Onerror diff --git a/unix/syslinux.c b/unix/syslinux.c index a9a900e5..36826a1b 100644 --- a/unix/syslinux.c +++ b/unix/syslinux.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1998-2005 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 @@ -76,7 +76,7 @@ int loop_fd = -1; /* Loop device */ void __attribute__((noreturn)) usage(void) { - fprintf(stderr, "Usage: %s [-sf] [-o offset] device\n", program); + fprintf(stderr, "Usage: %s [-sf][-d directory][-o offset] device\n", program); exit(1); } @@ -178,11 +178,12 @@ int main(int argc, char *argv[]) char mntname[64], devfdname[64]; char *ldlinux_name, **argp, *opt; int force = 0; /* -f (force) option */ + const char *subdir = NULL; struct libfat_filesystem *fs; struct libfat_direntry dentry; libfat_sector_t s, *secp, sectors[65]; /* 65 is maximum possible */ int32_t ldlinux_cluster; - int nsectors; + int nsectors = 0; const char *errmsg; (void)argc; /* Unused */ @@ -205,6 +206,8 @@ int main(int argc, char *argv[]) syslinux_make_stupid(); /* Use "safe, slow and stupid" code */ } else if ( *opt == 'f' ) { force = 1; /* Force install */ + } else if ( *opt == 'd' && argp[1] ) { + subdir = *++argp; } else if ( *opt == 'o' && argp[1] ) { filesystem_offset = (off_t)strtoull(*++argp, NULL, 0); /* Byte offset */ } else { @@ -367,13 +370,13 @@ int main(int argc, char *argv[]) #endif } - ldlinux_name = alloca(strlen(mntpath)+13); + ldlinux_name = alloca(strlen(mntpath)+14); if ( !ldlinux_name ) { perror(program); err = 1; goto umount; } - sprintf(ldlinux_name, "%s/ldlinux.sys", mntpath); + sprintf(ldlinux_name, "%s//ldlinux.sys", mntpath); unlink(ldlinux_name); fd = open(ldlinux_name, O_WRONLY|O_CREAT|O_TRUNC, 0444); @@ -409,6 +412,42 @@ int main(int argc, char *argv[]) sync(); + /* + * Now, use libfat to create a block map. This probably + * should be changed to use ioctl(...,FIBMAP,...) since + * this is supposed to be a simple, privileged version + * of the installer. + */ + fs = libfat_open(libfat_xpread, dev_fd); + ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", &dentry); + secp = sectors; + nsectors = 0; + s = libfat_clustertosector(fs, ldlinux_cluster); + while ( s && nsectors < 65 ) { + *secp++ = s; + nsectors++; + s = libfat_nextsector(fs, s); + } + libfat_close(fs); + + /* Move ldlinux.sys to the desired location */ + if (subdir) { + char *new_ldlinux_name = alloca(strlen(mntpath)+ + strlen(subdir)+15); + int mov_err = 1; + + if ( new_ldlinux_name ) { + sprintf(new_ldlinux_name, "%s//%s//ldlinux.sys", mntpath, subdir); + + if (!rename(ldlinux_name, new_ldlinux_name)) + mov_err = 0; + } + + if (mov_err) + fprintf(stderr, "%s: warning: unable to move ldlinux.sys: %s\n", + device, strerror(errno)); + } + umount: #if DO_DIRECT_MOUNT @@ -445,24 +484,6 @@ umount: exit(err); /* - * Now, use libfat to create a block map. This probably - * should be changed to use ioctl(...,FIBMAP,...) since - * this is supposed to be a simple, privileged version - * of the installer. - */ - fs = libfat_open(libfat_xpread, dev_fd); - ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", &dentry); - secp = sectors; - nsectors = 0; - s = libfat_clustertosector(fs, ldlinux_cluster); - while ( s && nsectors < 65 ) { - *secp++ = s; - nsectors++; - s = libfat_nextsector(fs, s); - } - libfat_close(fs); - - /* * Patch ldlinux.sys and the boot sector */ syslinux_patch(sectors, nsectors); diff --git a/win32/syslinux.c b/win32/syslinux.c index db5007db..613b1fc1 100644 --- a/win32/syslinux.c +++ b/win32/syslinux.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- * * * Copyright 2003 Lars Munch Christensen - All Rights Reserved - * Copyright 1998-2004 H. Peter Anvin - All Rights Reserved + * Copyright 1998-2007 H. Peter Anvin - All Rights Reserved * * Based on the Linux installer program for SYSLINUX by H. Peter Anvin * @@ -233,7 +233,7 @@ int libfat_readfile(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sect noreturn usage(void) { - fprintf(stderr, "Usage: syslinux.exe [-sfma] <drive>: [bootsecfile]\n"); + fprintf(stderr, "Usage: syslinux.exe [-sfma][-d directory] <drive>: [bootsecfile]\n"); exit(1); } @@ -256,6 +256,7 @@ int main(int argc, char *argv[]) uint32_t ldlinux_cluster; int nsectors; const char *bootsecfile = NULL; + const char *subdir = NULL; int force = 0; /* -f (force) option */ int mbr = 0; /* -m (MBR) option */ @@ -291,6 +292,10 @@ int main(int argc, char *argv[]) case 'a': /* Mark this partition active */ setactive = 1; break; + case 'd': + if ( argp[1] ) + subdir = *++argp; + break; default: usage(); break; @@ -446,6 +451,53 @@ int main(int argc, char *argv[]) /* Close file */ CloseHandle(f_handle); + /* Move the file to the desired location */ + if (subdir) { + char new_ldlinux_name[strlen(subdir)+16]; + char *cp = new_ldlinux_name+3; + const char *sd; + int slash = 1; + + new_ldlinux_name[0] = drive[0]; + new_ldlinux_name[1] = ':'; + new_ldlinux_name[2] = '\\'; + + for (sd = subdir; *sd; sd++) { + char c = *sd; + + if (c == '/' || c == '\\') { + if (slash) + continue; + c = '\\'; + slash = 1; + } else { + slash = 0; + } + + *cp++ = c; + } + + /* Skip if subdirectory == root */ + if (cp > new_ldlinux_name+3) { + if (!slash) + *cp++ = '\\'; + + memcpy(cp, "ldlinux.sys", 12); + + /* Delete any previous file */ + SetFileAttributes(new_ldlinux_name, FILE_ATTRIBUTE_NORMAL); + DeleteFile(new_ldlinux_name); + if (!MoveFile(ldlinux_name, new_ldlinux_name)) + SetFileAttributes(ldlinux_name, FILE_ATTRIBUTE_READONLY | + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + else + SetFileAttributes(new_ldlinux_name, FILE_ATTRIBUTE_READONLY | + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + } + } + + + /* Make the syslinux boot sector */ syslinux_make_bootsect(sectbuf); |