From 4487bada1a0997294e70cd418c74a53047cf784e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 30 Jan 2007 17:57:07 -0800 Subject: MEMDISK: Default to floppy = EDD off, hard disk = EDD on, give option Default to having EDD off on floppies and EDD on on hard disks. Additionally, add options "edd" and "noedd" to force this choice. --- memdisk/memdisk.asm | 11 ++++++----- memdisk/memdisk.doc | 8 +++++++- memdisk/setup.c | 21 ++++++++++++++++++--- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm index 09055d8f..1d3d39de 100644 --- a/memdisk/memdisk.asm +++ b/memdisk/memdisk.asm @@ -6,7 +6,7 @@ ; A program to emulate an INT 13h disk BIOS from a "disk" in extended ; memory. ; -; Copyright (C) 2001-2006 H. Peter Anvin +; Copyright (C) 2001-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 @@ -152,8 +152,8 @@ Int13Start: mov bp,sp ; Point BP to the entry stack frame TRACER 'F' ; Note: AH == P_AH here - cmp ah,Int13FuncsMax - jae Invalid_jump + cmp ah,[Int13MaxFunc] + ja Invalid_jump xor al,al ; AL = 0 is standard entry condition mov di,ax shr di,7 ; Convert AH to an offset in DI @@ -870,7 +870,7 @@ Int13Funcs dw Reset ; 00h - RESET %endif Int13FuncsEnd equ $ -Int13FuncsMax equ (Int13FuncsEnd-Int13Funcs) >> 1 +Int13FuncsCnt equ (Int13FuncsEnd-Int13Funcs) >> 1 %if EDD EDD_DPT: @@ -933,8 +933,9 @@ OldInt15 dd 0 ; INT 15h in chain OldDosMem dw 0 ; Old position of DOS mem end BootLoaderID db 0 ; Boot loader ID from header ; ---- MDI structure ends here --- - db 0, 0, 0 ; pad +Int13MaxFunc db Int13FuncsCnt-1 ; Max INT 13h function (to disable EDD) + db 0, 0 ; pad MemInt1588 dw 0 ; 1MB-65MB memory amount (1K) Cylinders dw 0 ; Cylinder count diff --git a/memdisk/memdisk.doc b/memdisk/memdisk.doc index fdcc259e..759a7b27 100644 --- a/memdisk/memdisk.doc +++ b/memdisk/memdisk.doc @@ -89,6 +89,12 @@ d) MEMDISK normally uses the BIOS "INT 15h mover" API to access high safeint Use INT 15h access to protected memory, but invoke INT 15h the way it was *before* MEMDISK was loaded. +e) MEMDISK by default supports EDD/EBIOS on hard disks, but not on + floppy disks. This can be controlled with the options: + + edd Enable EDD/EBIOS + noedd Disable EDD/EBIOS + Some interesting things to note: @@ -136,7 +142,7 @@ http://www.ctyme.com/rbrown.htm, for a detailed description. The MEMDISK info structure currently contains: - [ES:DI] word Total size of structure (currently 27 bytes) + [ES:DI] word Total size of structure (currently 28 bytes) [ES:DI+2] byte MEMDISK minor version [ES:DI+3] byte MEMDISK major version [ES:DI+4] dword Pointer to MEMDISK data in high memory diff --git a/memdisk/setup.c b/memdisk/setup.c index 8c83f039..70dc1d65 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -70,8 +70,10 @@ struct patch_area { uint16_t olddosmem; uint8_t bootloaderid; + uint8_t maxint13func; +#define MAXINT13_NOEDD 0x16 - uint8_t _pad[3]; + uint8_t _pad[2]; uint16_t memint1588; uint16_t cylinders; @@ -552,6 +554,7 @@ void setup(syscall_t cs_syscall, void *cs_bounce) com32sys_t regs; uint32_t ramdisk_image, ramdisk_size; int bios_drives; + int do_edd = -1; /* -1 = default, 0 = no, 1 = yes */ /* Set up global variables */ syscall = cs_syscall; @@ -579,11 +582,19 @@ void setup(syscall_t cs_syscall, void *cs_bounce) geometry = get_disk_image_geometry(ramdisk_image, ramdisk_size); - printf("Disk is %s %d, %u K, C/H/S = %u/%u/%u\n", + if (getcmditem("edd") != CMD_NOTFOUND) + do_edd = 1; + else if (getcmditem("noedd") != CMD_NOTFOUND) + do_edd = 0; + else + do_edd = (geometry->driveno & 0x80) ? 1 : 0; + + printf("Disk is %s %d, %u K, C/H/S = %u/%u/%u, EDD %s\n", (geometry->driveno & 0x80) ? "hard disk" : "floppy", geometry->driveno & 0x7f, geometry->sectors >> 1, - geometry->c, geometry->h, geometry->s); + geometry->c, geometry->h, geometry->s, + do_edd ? "on" : "off"); /* Reserve the ramdisk memory */ insertrange(ramdisk_image, ramdisk_size, 2); @@ -633,6 +644,10 @@ void setup(syscall_t cs_syscall, void *cs_bounce) pptr->configflags |= CONFIG_BIGRAW|CONFIG_RAW; } + /* pptr->maxint13func defaults to EDD enabled, if compiled in */ + if (!do_edd) + pptr->maxint13func = MAXINT13_NOEDD; + /* Set up a drive parameter table */ if ( geometry->driveno & 0x80 ) { /* Hard disk */ -- cgit v1.2.1 From 56d06ed1af5b29f6fc6130b02730f762f5ab384e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 30 Jan 2007 17:58:38 -0800 Subject: MEMDISK: ebios/noebios as synonyms to edd/noedd --- memdisk/setup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/memdisk/setup.c b/memdisk/setup.c index 70dc1d65..96e87b08 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -582,9 +582,11 @@ void setup(syscall_t cs_syscall, void *cs_bounce) geometry = get_disk_image_geometry(ramdisk_image, ramdisk_size); - if (getcmditem("edd") != CMD_NOTFOUND) + if (getcmditem("edd") != CMD_NOTFOUND || + getcmditem("ebios") != CMD_NOTFOUND) do_edd = 1; - else if (getcmditem("noedd") != CMD_NOTFOUND) + else if (getcmditem("noedd") != CMD_NOTFOUND || + getcmditem("noebios") != CMD_NOTFOUND) do_edd = 0; else do_edd = (geometry->driveno & 0x80) ? 1 : 0; -- cgit v1.2.1 From ac7d5bd715bb28f4e2cfef3c1cb158d2eace0e4a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 30 Jan 2007 17:59:14 -0800 Subject: MEMDISK: add alias "cbios" == "noebios" == "noedd" --- memdisk/setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/memdisk/setup.c b/memdisk/setup.c index 96e87b08..d1eabc58 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -586,7 +586,8 @@ void setup(syscall_t cs_syscall, void *cs_bounce) getcmditem("ebios") != CMD_NOTFOUND) do_edd = 1; else if (getcmditem("noedd") != CMD_NOTFOUND || - getcmditem("noebios") != CMD_NOTFOUND) + getcmditem("noebios") != CMD_NOTFOUND || + getcmditem("cbios") != CMD_NOTFOUND) do_edd = 0; else do_edd = (geometry->driveno & 0x80) ? 1 : 0; -- cgit v1.2.1 From b975c239110ad83691c6c5084a6f588e0ecffe32 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 30 Jan 2007 18:00:26 -0800 Subject: New version 3.36: document changes so far --- NEWS | 4 ++++ version | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 3320566e..4ef8cd9a 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ Starting with 1.47, changes marked with SYSLINUX/PXELINUX/ISOLINUX apply to that specific program only; other changes apply to all of 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". + Changes in 3.35: * MEMDISK: New "safeint" mode. * MEMDISK: Be more compliant with the PnP BIOS spec. diff --git a/version b/version index e182c31e..04370598 100644 --- a/version +++ b/version @@ -1 +1 @@ -3.35 +3.36 -- cgit v1.2.1 From 1dbb3f4d9e4ca52f13ca4312a8c83245d8d986c9 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 31 Jan 2007 23:45:26 -0800 Subject: Unix installer: use Linux-native ioctls instead of libfat Unix installer: use Linux-native ioctls instead of libfat. This should make it smaller, and should also make it possible to use the vfat filesystem (need to clean up the mount code for that to work.) --- unix/Makefile | 4 +- unix/syslinux.c | 130 ++++++++++++++++++++++++++------------------------------ 2 files changed, 63 insertions(+), 71 deletions(-) diff --git a/unix/Makefile b/unix/Makefile index 5dfc0513..021aa538 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -1,10 +1,10 @@ CC = gcc OPTFLAGS = -g -Os -INCLUDES = -I. -I.. -I../libfat +INCLUDES = -I. -I.. CFLAGS = -W -Wall -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES) LDFLAGS = -s -SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c $(wildcard ../libfat/*.c) +SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) .SUFFIXES: .c .o .i .s .S diff --git a/unix/syslinux.c b/unix/syslinux.c index 36826a1b..308e52fd 100644 --- a/unix/syslinux.c +++ b/unix/syslinux.c @@ -13,7 +13,7 @@ /* * syslinux.c - Linux installer program for SYSLINUX * - * This program ought to be portable. I hope so, at least. + * This is Linux-specific by now. * * This is an alternate version of the installer which doesn't require * mtools, but requires root privilege. @@ -46,15 +46,14 @@ #include #include +#include /* FIGETBSZ, FIBMAP */ +#include /* FAT_IOCTL_SET_ATTRIBUTES, SECTOR_* */ + #include "syslinux.h" -#include "libfat.h" #if DO_DIRECT_MOUNT - # include - #else - # include # ifndef _PATH_MOUNT # define _PATH_MOUNT "/bin/mount" @@ -62,7 +61,6 @@ # ifndef _PATH_UMOUNT # define _PATH_UMOUNT "/bin/umount" # endif - #endif const char *program; /* Name of program */ @@ -156,17 +154,43 @@ ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset) } /* - * Version of the read function suitable for libfat + * Create a block map for ldlinux.sys */ -int libfat_xpread(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sector) +int make_block_map(uint32_t *sectors, int len, int dev_fd, int fd) { - off_t offset = (off_t)sector * secsize + filesystem_offset; - return xpread(pp, buf, secsize, offset); + int nsectors = 0; + int blocksize, nblock, block; + int i; + + (void)dev_fd; + + if (ioctl(fd, FIGETBSZ, &blocksize) < 0) + die("ioctl FIGETBSZ failed"); + + blocksize >>= SECTOR_BITS; /* sectors/block */ + + nblock = 0; + while (len > 0) { + block = nblock++; + if (ioctl(fd, FIBMAP, &block) < 0) + die("ioctl FIBMAP failed"); + + for (i = 0; i < blocksize; i++) { + if (len <= 0) + break; + + *sectors++ = (block*blocksize)+i; + nsectors++; + len -= (1 << SECTOR_BITS); + } + } + + return nsectors; } int main(int argc, char *argv[]) { - static unsigned char sectbuf[512]; + static unsigned char sectbuf[SECTOR_SIZE]; unsigned char *dp; const unsigned char *cdp; int dev_fd, fd; @@ -179,10 +203,7 @@ int main(int argc, char *argv[]) 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; + uint32_t sectors[65]; /* 65 is maximum possible */ int nsectors = 0; const char *errmsg; @@ -243,7 +264,7 @@ int main(int argc, char *argv[]) die("not a regular file and an offset specified (use -f to override)"); } - xpread(dev_fd, sectbuf, 512, filesystem_offset); + xpread(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); fsync(dev_fd); /* @@ -370,13 +391,21 @@ int main(int argc, char *argv[]) #endif } - ldlinux_name = alloca(strlen(mntpath)+14); + ldlinux_name = alloca(strlen(mntpath)+14+ + (subdir ? strlen(subdir)+2 : 0)); if ( !ldlinux_name ) { perror(program); err = 1; goto umount; } - sprintf(ldlinux_name, "%s//ldlinux.sys", mntpath); + sprintf(ldlinux_name, "%s%s%s//ldlinux.sys", + subdir ? "//" : "", subdir ? subdir : "", mntpath); + + if ((fd = open(ldlinux_name, O_RDONLY)) >= 0) { + uint32_t zero_attr = 0; + ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &zero_attr); + close(fd); + } unlink(ldlinux_name); fd = open(ldlinux_name, O_WRONLY|O_CREAT|O_TRUNC, 0444); @@ -402,51 +431,22 @@ int main(int argc, char *argv[]) left -= nb; } + fsync(fd); /* - * I don't understand why I need this. Does the DOS filesystems - * not honour the mode passed to open()? + * Set the attributes */ - fchmod(fd, 0400); - - close(fd); - - sync(); + { + uint32_t attr = 0x07; /* Hidden+System+Readonly */ + ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr); + } /* - * 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. + * Create a block map. */ - 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; - } + nsectors = make_block_map(sectors, syslinux_ldlinux_len, dev_fd, fd); - if (mov_err) - fprintf(stderr, "%s: warning: unable to move ldlinux.sys: %s\n", - device, strerror(errno)); - } + close(fd); + sync(); umount: #if DO_DIRECT_MOUNT @@ -491,29 +491,21 @@ umount: /* * Write the now-patched first sector of ldlinux.sys */ - xpwrite(dev_fd, syslinux_ldlinux, 512, filesystem_offset + ((off_t)sectors[0] << 9)); - - /* - * Patch the root directory to set attributes to - * HIDDEN|SYSTEM|READONLY - */ - { - const unsigned char attrib = 0x07; - xpwrite(dev_fd, &attrib, 1, ((off_t)dentry.sector << 9)+dentry.offset+11); - } + xpwrite(dev_fd, syslinux_ldlinux, SECTOR_SIZE, + filesystem_offset+((off_t)sectors[0] << SECTOR_BITS)); /* * To finish up, write the boot sector */ /* Read the superblock again since it might have changed while mounted */ - xpread(dev_fd, sectbuf, 512, filesystem_offset); + xpread(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); /* Copy the syslinux code into the boot sector */ syslinux_make_bootsect(sectbuf); /* Write new boot sector */ - xpwrite(dev_fd, sectbuf, 512, filesystem_offset); + xpwrite(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); close(dev_fd); sync(); -- cgit v1.2.1 From 81dc0b0f79bdec8b91574f3ae6782c3e36f20d97 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 31 Jan 2007 23:47:12 -0800 Subject: Document change in strategy for the "unix" installer. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 2fdb2ca7..c1f55d8f 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ 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". + * SYSLINUX: "unix" installer now uses Linux ioctls instead of + using libfat. Changes in 3.35: * MEMDISK: New "safeint" mode. -- cgit v1.2.1 From 9dca0150cc0e799633523aafc3d0bfb29ec4ed94 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 31 Jan 2007 23:47:58 -0800 Subject: Document that Ghost should now work. --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index c1f55d8f..7235850d 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ 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. -- cgit v1.2.1 From 1a1900a2eda610f90180e120e33fa0474f6e84a9 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 1 Feb 2007 10:51:01 -0800 Subject: Unix FAT installer: #include , FAT_IOCTL_SET_ATTRIBUTES #include , and provide a backup definition for FAT_IOCTL_SET_ATTRIBUTES. --- unix/syslinux.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/unix/syslinux.c b/unix/syslinux.c index 308e52fd..8f924ad7 100644 --- a/unix/syslinux.c +++ b/unix/syslinux.c @@ -46,8 +46,12 @@ #include #include +#include #include /* FIGETBSZ, FIBMAP */ #include /* FAT_IOCTL_SET_ATTRIBUTES, SECTOR_* */ +#ifndef FAT_IOCTL_SET_ATTRIBUTES +# define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, uint32_t) +#endif #include "syslinux.h" -- cgit v1.2.1 From 5528fab0fd41e81e9b876f1bd7ebeb94b30b896c Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 1 Feb 2007 11:15:15 -0800 Subject: Unix FAT installer: separate mount/umount; try vfat before msdos Separate the mounting and unmounting code out into separate functions. Try mounting vfat before trying to mount msdos. --- unix/syslinux.c | 252 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 143 insertions(+), 109 deletions(-) diff --git a/unix/syslinux.c b/unix/syslinux.c index 8f924ad7..d31e01f3 100644 --- a/unix/syslinux.c +++ b/unix/syslinux.c @@ -53,18 +53,21 @@ # define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, uint32_t) #endif +#include +#ifndef _PATH_MOUNT +# define _PATH_MOUNT "/bin/mount" +#endif +#ifndef _PATH_UMOUNT +# define _PATH_UMOUNT "/bin/umount" +#endif +#ifndef _PATH_TMP +# define _PATH_TMP "/tmp/" +#endif + #include "syslinux.h" #if DO_DIRECT_MOUNT # include -#else -# include -# ifndef _PATH_MOUNT -# define _PATH_MOUNT "/bin/mount" -# endif -# ifndef _PATH_UMOUNT -# define _PATH_UMOUNT "/bin/umount" -# endif #endif const char *program; /* Name of program */ @@ -192,6 +195,124 @@ int make_block_map(uint32_t *sectors, int len, int dev_fd, int fd) return nsectors; } +/* + * Mount routine + */ +int do_mount(int dev_fd, int *cookie, const char *mntpath, const char *fstype) +{ + struct stat st; + + (void)cookie; + + if (fstat(dev_fd, &st) < 0) + return errno; + +#if DO_DIRECT_MOUNT + { + if ( !S_ISBLK(st.st_mode) ) { + /* It's file, need to mount it loopback */ + unsigned int n = 0; + struct loop_info64 loopinfo; + int loop_fd; + + for ( n = 0 ; loop_fd < 0 ; n++ ) { + snprintf(devfdname, sizeof devfdname, "/dev/loop%u", n); + loop_fd = open(devfdname, O_RDWR); + if ( loop_fd < 0 && errno == ENOENT ) { + die("no available loopback device!"); + } + if ( ioctl(loop_fd, LOOP_SET_FD, (void *)dev_fd) ) { + close(loop_fd); loop_fd = -1; + if ( errno != EBUSY ) + die("cannot set up loopback device"); + else + continue; + } + + if ( ioctl(loop_fd, LOOP_GET_STATUS64, &loopinfo) || + (loopinfo.lo_offset = filesystem_offset, + ioctl(loop_fd, LOOP_SET_STATUS64, &loopinfo)) ) + die("cannot set up loopback device"); + } + + *cookie = loop_fd; + } else { + snprintf(devfdname, sizeof devfdname, "/proc/%lu/fd/%d", + (unsigned long)mypid, dev_fd); + *cookie = -1; + } + + return mount(devfdname, mntpath, fstype, + MS_NOEXEC|MS_NOSUID, "umask=077,quiet"); + } +#else + { + char devfdname[128], mnt_opts[128]; + pid_t f, w; + int status; + + snprintf(devfdname, sizeof devfdname, "/proc/%lu/fd/%d", + (unsigned long)mypid, dev_fd); + + f = fork(); + if ( f < 0 ) { + return -1; + } else if ( f == 0 ) { + if ( !S_ISBLK(st.st_mode) ) { + snprintf(mnt_opts, sizeof mnt_opts, + "rw,nodev,noexec,loop,offset=%llu,umask=077,quiet", + (unsigned long long)filesystem_offset); + } else { + snprintf(mnt_opts, sizeof mnt_opts, "rw,nodev,noexec,umask=077,quiet"); + } + execl(_PATH_MOUNT, _PATH_MOUNT, "-t", fstype, "-o", mnt_opts, \ + devfdname, mntpath, NULL); + _exit(255); /* execl failed */ + } + + w = waitpid(f, &status, 0); + return ( w != f || status ) ? -1 : 0; + } +#endif +} + +/* + * umount routine + */ +void do_umount(const char *mntpath, int cookie) +{ +#if DO_DIRECT_MOUNT + int loop_fd = cookie; + + if ( umount2(mntpath, 0) ) + die("could not umount path"); + + if ( loop_fd != -1 ) { + ioctl(loop_fd, LOOP_CLR_FD, 0); /* Free loop device */ + close(loop_fd); + loop_fd = -1; + } + +#else + pid_t f = fork(); + pid_t w; + int status; + (void)cookie; + + if ( f < 0 ) { + perror("fork"); + exit(1); + } else if ( f == 0 ) { + execl(_PATH_UMOUNT, _PATH_UMOUNT, mntpath, NULL); + } + + w = waitpid(f, &status, 0); + if ( w != f || status ) { + exit(1); + } +#endif +} + int main(int argc, char *argv[]) { static unsigned char sectbuf[SECTOR_SIZE]; @@ -201,15 +322,14 @@ int main(int argc, char *argv[]) struct stat st; int nb, left; int err = 0; - pid_t f, w; - int status; - char mntname[64], devfdname[64]; + char mntname[128]; char *ldlinux_name, **argp, *opt; int force = 0; /* -f (force) option */ const char *subdir = NULL; uint32_t sectors[65]; /* 65 is maximum possible */ int nsectors = 0; const char *errmsg; + int mnt_cookie; (void)argc; /* Unused */ @@ -260,12 +380,12 @@ int main(int argc, char *argv[]) exit(1); } - if ( !force && !S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode) ) { - die("not a block device or regular file (use -f to override)"); + if ( !S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode) ) { + die("not a device or regular file"); } - if ( !force && filesystem_offset && !S_ISREG(st.st_mode) ) { - die("not a regular file and an offset specified (use -f to override)"); + if ( filesystem_offset && S_ISBLK(st.st_mode) ) { + die("can't combine an offset with a block device"); } xpread(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); @@ -292,7 +412,7 @@ int main(int argc, char *argv[]) /* We're root or at least setuid. Make a temp dir and pass all the gunky options to mount. */ - if ( chdir("/tmp") ) { + if ( chdir(_PATH_TMP) ) { perror(program); exit(1); } @@ -301,7 +421,7 @@ int main(int argc, char *argv[]) if ( stat(".", &dst) || !S_ISDIR(dst.st_mode) || (dst.st_mode & TMP_MODE) != TMP_MODE ) { - die("possibly unsafe /tmp permissions"); + die("possibly unsafe " _PATH_TMP " permissions"); } for ( i = 0 ; ; i++ ) { @@ -328,71 +448,12 @@ int main(int argc, char *argv[]) } mntpath = mntname; + } -#if DO_DIRECT_MOUNT - if ( S_ISREG(st.st_mode) ) { - /* It's file, need to mount it loopback */ - unsigned int n = 0; - struct loop_info64 loopinfo; - - for ( n = 0 ; loop_fd < 0 ; n++ ) { - snprintf(devfdname, sizeof devfdname, "/dev/loop%u", n); - loop_fd = open(devfdname, O_RDWR); - if ( loop_fd < 0 && errno == ENOENT ) { - die("no available loopback device!"); - } - if ( ioctl(loop_fd, LOOP_SET_FD, (void *)dev_fd) ) { - close(loop_fd); loop_fd = -1; - if ( errno != EBUSY ) - die("cannot set up loopback device"); - else - continue; - } - - if ( ioctl(loop_fd, LOOP_GET_STATUS64, &loopinfo) || - (loopinfo.lo_offset = filesystem_offset, - ioctl(loop_fd, LOOP_SET_STATUS64, &loopinfo)) ) - die("cannot set up loopback device"); - } - } else { - snprintf(devfdname, sizeof devfdname, "/proc/%lu/fd/%d", - (unsigned long)mypid, dev_fd); - } - - if ( mount(devfdname, mntpath, "msdos", - MS_NOEXEC|MS_NOSUID, "umask=077,quiet") ) - die("could not mount filesystem"); - -#else - - snprintf(devfdname, sizeof devfdname, "/proc/%lu/fd/%d", - (unsigned long)mypid, dev_fd); - - f = fork(); - if ( f < 0 ) { - perror(program); - rmdir(mntpath); - exit(1); - } else if ( f == 0 ) { - char mnt_opts[128]; - if ( S_ISREG(st.st_mode) ) { - snprintf(mnt_opts, sizeof mnt_opts, "rw,nodev,noexec,loop,offset=%llu,umask=077,quiet", - (unsigned long long)filesystem_offset); - } else { - snprintf(mnt_opts, sizeof mnt_opts, "rw,nodev,noexec,umask=077,quiet"); - } - execl(_PATH_MOUNT, _PATH_MOUNT, "-t", "msdos", "-o", mnt_opts,\ - devfdname, mntpath, NULL); - _exit(255); /* execl failed */ - } - - w = waitpid(f, &status, 0); - if ( w != f || status ) { - rmdir(mntpath); - exit(1); /* Mount failed */ - } - -#endif + if (do_mount(dev_fd, &mnt_cookie, mntpath, "vfat") && + do_mount(dev_fd, &mnt_cookie, mntpath, "msdos")) { + rmdir(mntpath); + die("mount failed"); } ldlinux_name = alloca(strlen(mntpath)+14+ @@ -453,34 +514,7 @@ int main(int argc, char *argv[]) sync(); umount: -#if DO_DIRECT_MOUNT - - if ( umount2(mntpath, 0) ) - die("could not umount path"); - - if ( loop_fd != -1 ) { - ioctl(loop_fd, LOOP_CLR_FD, 0); /* Free loop device */ - close(loop_fd); - loop_fd = -1; - } - -#else - - f = fork(); - if ( f < 0 ) { - perror("fork"); - exit(1); - } else if ( f == 0 ) { - execl(_PATH_UMOUNT, _PATH_UMOUNT, mntpath, NULL); - } - - w = waitpid(f, &status, 0); - if ( w != f || status ) { - exit(1); - } - -#endif - + do_umount(mntpath, mnt_cookie); sync(); rmdir(mntpath); -- cgit v1.2.1 From f0a76c9a7eda891aca9a87a28179e51baffffd11 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 1 Feb 2007 11:15:46 -0800 Subject: Formatting cleanup --- unix/syslinux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unix/syslinux.c b/unix/syslinux.c index d31e01f3..8b5a4cf6 100644 --- a/unix/syslinux.c +++ b/unix/syslinux.c @@ -354,7 +354,8 @@ int main(int argc, char *argv[]) } else if ( *opt == 'd' && argp[1] ) { subdir = *++argp; } else if ( *opt == 'o' && argp[1] ) { - filesystem_offset = (off_t)strtoull(*++argp, NULL, 0); /* Byte offset */ + /* Byte offset */ + filesystem_offset = (off_t)strtoull(*++argp, NULL, 0); } else { usage(); } -- cgit v1.2.1 From cd03ccc66ec264140d4bdd38d4204a26f8a59fb7 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 1 Feb 2007 11:16:24 -0800 Subject: Stealth whitespace cleanup --- Makefile.private | 4 ++-- README.menu | 4 ++-- TODO | 1 - abort.inc | 2 +- comboot.doc | 2 +- comboot.inc | 2 +- font.inc | 2 +- head.inc | 2 +- loadhigh.inc | 2 +- 9 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Makefile.private b/Makefile.private index 63a3bbdf..8573aa44 100644 --- a/Makefile.private +++ b/Makefile.private @@ -35,8 +35,8 @@ burn: isolinux.iso cdrecord -v blank=fast isolinux.iso official: - $(MAKE) spotless CC='$(CC) -m32' - $(MAKE) depend CC='$(CC) -m32' + $(MAKE) spotless CC='$(CC) -m32' + $(MAKE) depend CC='$(CC) -m32' $(MAKE) all CC='$(CC) -m32' $(MAKE) dist CC='$(CC) -m32' diff --git a/README.menu b/README.menu index 6f0fd83c..fe4f9091 100644 --- a/README.menu +++ b/README.menu @@ -186,13 +186,13 @@ MENU COLOR element ansi foreground background shadow represents fully transparent, and #ffffffff represents opaque white. - + "shadow" controls the handling of the graphical console text shadow. Permitted values are "none" (no shadowing), "std" or "standard" (standard shadowing - foreground pixels are raised), "all" (both background and foreground raised), and "rev" or "reverse" (background pixels are raised.) - + If any field is set to "*" or omitted (at the end of the line) then that field is left unchanged. diff --git a/TODO b/TODO index e2aacca6..93f3194d 100644 --- a/TODO +++ b/TODO @@ -31,4 +31,3 @@ - COM32-based CLI. - Rewrite the filesystems to run in protected mode C code. - diff --git a/abort.inc b/abort.inc index e6bf0d52..fd136529 100644 --- a/abort.inc +++ b/abort.inc @@ -62,4 +62,4 @@ error_or_command: mov cx,[OnerrorLen] and cx,cx jnz on_error - jmp enter_command \ No newline at end of file + jmp enter_command diff --git a/comboot.doc b/comboot.doc index c99522ec..8aaa0e78 100644 --- a/comboot.doc +++ b/comboot.doc @@ -686,7 +686,7 @@ AX=0017h [3.30] Report video mode change which are undefined in the current version of SYSLINUX. The following bits in BX are currently defined: - + Bit 0: graphics mode Indicates that the mode is a graphics mode, as opposed diff --git a/comboot.inc b/comboot.inc index fcaa3a7a..0f544c2e 100644 --- a/comboot.inc +++ b/comboot.inc @@ -770,7 +770,7 @@ comapi_userfont: .done: ; CF=0 here mov P_AL,al ret - + ; ; INT 22h AX=0019h Read disk ; diff --git a/font.inc b/font.inc index 04080ba7..f27f8785 100644 --- a/font.inc +++ b/font.inc @@ -75,7 +75,7 @@ use_font: test byte [UsingVGA], 01h ; Are we in graphics mode? jz .text - + .graphics: xor cx,cx mov cl,bh ; CX = bytes/character diff --git a/head.inc b/head.inc index e0682b2f..17562079 100644 --- a/head.inc +++ b/head.inc @@ -1,6 +1,6 @@ ; -*- fundamental -*- (asm-mode sucks) ; ----------------------------------------------------------------------- -; +; ; Copyright 2006 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify diff --git a/loadhigh.inc b/loadhigh.inc index 7d9f57a4..283778f6 100644 --- a/loadhigh.inc +++ b/loadhigh.inc @@ -88,7 +88,7 @@ load_high: sub eax,ecx pop bx ; Pausebird function jnz .read_loop ; More to read... - + .eof: pop es ; ES -- cgit v1.2.1 From cc85ed02fd42780769c93c85e79769c22607ea45 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 1 Feb 2007 12:15:38 -0800 Subject: Mtools installer: disable MTOOLS_NO_VFAT --- mtools/syslinux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" -- cgit v1.2.1 From acd7bcea0b3d07c48cdd7af1de2fdacb7604b409 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 1 Feb 2007 22:10:36 -0800 Subject: Rebalance sections for especially extlinux --- extlinux.asm | 6 +++--- layout.inc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) 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/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. -- cgit v1.2.1 From bec02e93bf31d7ce54724691448fb158a07d2632 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 1 Feb 2007 22:11:12 -0800 Subject: Use LRU caching instead of LRR (least recently read) --- cache.inc | 83 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/cache.inc b/cache.inc index e2595a21..8d471bf6 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,28 @@ 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 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 +76,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 + -- cgit v1.2.1 From ab021ddc666e1708185ec7014382586cf0bab17d Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 1 Feb 2007 22:18:44 -0800 Subject: Remember which sector we cached! --- cache.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/cache.inc b/cache.inc index 8d471bf6..95c5f48e 100644 --- a/cache.inc +++ b/cache.inc @@ -65,6 +65,7 @@ getcachesector: push gs pop es 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 -- cgit v1.2.1 From 7cfd6f9dd9a73eb18c10948aaa0e56a52e0a4228 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sat, 3 Feb 2007 12:42:48 -0800 Subject: Unix FAT inst: fix the order of stitched strings. --- unix/syslinux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/syslinux.c b/unix/syslinux.c index d31e01f3..aa6a0037 100644 --- a/unix/syslinux.c +++ b/unix/syslinux.c @@ -464,7 +464,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; -- cgit v1.2.1 From 56810d7d98194e14c354ac58e1ac5b9d07ce6a2b Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Feb 2007 15:59:37 -0800 Subject: New MBR which supports logical partitions. New MBR which supports logical partitions. Move the MBR to a subdirectory, and convert it to gas with the expectation of including it in util-linux. --- Makefile | 18 ++-- mbr/Makefile | 47 +++++++++ mbr/checksize.pl | 31 ++++++ mbr/mbr.S | 290 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 378 insertions(+), 8 deletions(-) create mode 100644 mbr/Makefile create mode 100755 mbr/checksize.pl create mode 100644 mbr/mbr.S diff --git a/Makefile b/Makefile index 7673cf5c..5814897f 100644 --- a/Makefile +++ b/Makefile @@ -63,12 +63,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 \ @@ -102,9 +106,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 +172,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 diff --git a/mbr/Makefile b/mbr/Makefile new file mode 100644 index 00000000..d96ee467 --- /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,) + +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) -c -o $@ $< + +mbr.elf: mbr.o + $(LD) -Ttext 0x600 -e _start -o $@ $^ + +mbr.bin: mbr.elf checksize.pl + $(OBJCOPY) -O binary $< $@ + $(PERL) checksize.pl mbr.bin 440 + +tidy: + rm -f *.o *.elf + +clean: + rm -f *.o *.elf *.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..edfccfb1 --- /dev/null +++ b/mbr/mbr.S @@ -0,0 +1,290 @@ +/* ----------------------------------------------------------------------- + * + * 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 + +bootsec = 0x7c00 +stack = bootsec +driveno = (stack-4) +heads = (stack-6) +sectors = (stack-8) + +BIOS_page = 0x462 + + .globl _start +_start: + cli + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + movw $stack, %sp + pushw %es /* es:di -> $PnP header */ + pushw %di + pushw %dx /* dl -> drive number */ + movw %ax, %es + sti + cld + + /* Copy down to 0:0x600 */ + movw %sp, %si + 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: + 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) + call read_sector + jc disk_error + cmpw $0xaa55, (bootsec+0x510) + je missing_os /* Not a valid boot sector */ + movw $stack-6, %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 "Failed to load operating system." + .byte 0 +too_many_active_msg: + .ascii "Multiple active partititons." + .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 */ -- cgit v1.2.1 From 5a19d71bffdb6733685461d77233d18ff2f53abd Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Feb 2007 16:01:09 -0800 Subject: Move old MBR into the MBR directory; fix old reference to mbr.bin --- Makefile | 2 +- mbr.asm | 229 --------------------------------------------------------- mbr/oldmbr.asm | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 230 deletions(-) delete mode 100644 mbr.asm create mode 100644 mbr/oldmbr.asm diff --git a/Makefile b/Makefile index 5814897f..0c58ca00 100644 --- a/Makefile +++ b/Makefile @@ -86,7 +86,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 diff --git a/mbr.asm b/mbr.asm deleted file mode 100644 index 31bf1fdf..00000000 --- a/mbr.asm +++ /dev/null @@ -1,229 +0,0 @@ -; ----------------------------------------------------------------------- -; -; Copyright 2003-2004 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. -; -; ----------------------------------------------------------------------- - -; -; mbr.asm -; -; Simple Master Boot Record, including support for EBIOS extensions. -; -; The MBR lives in front of the boot sector, and is responsible for -; loading the boot sector of the active partition. The EBIOS support -; is needed if the active partition starts beyond cylinder 1024. -; -; This MBR determines all geometry info at runtime. It uses only the -; linear block field in the partition table. It does, however, pass -; the partition table information unchanged to the target OS. -; -; This MBR should be "8086-clean", i.e. not require a 386. -; - -%include "bios.inc" - -; -; Note: The MBR is actually loaded at 0:7C00h, but we quickly move it down to -; 0600h. -; - section .text - cpu 8086 - org 0600h - -_start: cli - xor ax,ax - mov ds,ax - mov es,ax - mov ss,ax - mov sp,7C00h - sti - cld - mov si,sp ; Start address - mov di,0600h ; Destination address - mov cx,512/2 - rep movsw - -; -; Now, jump to the copy at 0600h so we can load the boot sector at 7C00h. -; Since some BIOSes seem to think 0000:7C00h and 07C0:0000h are the same -; thing, use a far jump to canonicalize the address. This also makes -; sure that it is a code speculation barrier. -; - - jmp 0:next ; Jump to copy at 0600h - -next: - mov [DriveNo], dl ; Drive number stored in DL -; -; Check for CHS parameters. This doesn't work on floppy disks, -; but for an MBR we don't care. -; - mov ah,08h ; Get drive parameters - int 13h - xor ax,ax - mov al,dh - inc ax ; From 0-based to count - mov [Heads],ax - and cl,3Fh ; Max sector number - mov [Sectors],cl - ; Note: we actually don't care about the number of - ; cylinders, since that's the highest-order division - -; -; Now look for one (and only one) active partition. -; - mov si,PartitionTable - xor ax,ax - mov cx,4 -checkpartloop: - test byte [si],80h - jz .notactive - inc ax - mov di,si -.notactive: add si,byte 16 - loop checkpartloop - - cmp ax,byte 1 ; Better be only one - jnz not_one_partition - -; -; Now we have the active partition partition information in DS:DI. -; Check to see if we support EBIOS. -; - mov dl,[DriveNo] - mov ax,4100h - mov bx,055AAh - xor cx,cx - xor dh,dh - stc - int 13h - jc no_ebios - cmp bx,0AA55h - jne no_ebios - test cl,1 ; LBA device access - jz no_ebios -; -; We have EBIOS. Load the boot sector using LBA. -; - push di - mov si,dapa - mov bx,[di+8] ; Copy the block address - mov [si+8],bx - mov bx,[di+10] - mov [si+10],bx - mov dl,[DriveNo] - mov ah,42h ; Extended Read - jmp short common_tail -; -; No EBIOS. Load the boot sector using CHS. -; -no_ebios: - push di - mov ax,[di+8] - mov dx,[di+10] - div word [Sectors] - inc dx - mov cx,dx ; Sector # - xor dx,dx - div word [Heads] - ; DX = head #, AX = cylinder # - mov ch,al - shr ax,1 - shr ax,1 - and al,0C0h - or cl,al - mov dh,dl ; Head # - mov dl,[DriveNo] - mov bx,7C00h - mov ax,0201h ; Read one sector -common_tail: - int 13h - jc disk_error - pop si ; DS:SI -> partition table entry -; -; Verify that we have a boot sector, jump -; - cmp word [7C00h+510],0AA55h - jne missing_os - cli - jmp 0:7C00h ; Jump to boot sector; far - ; jump is speculation barrier - ; (Probably not neecessary, but - ; there is plenty of space.) - -not_one_partition: - ja too_many_os -missing_os: - mov si,missing_os_msg - jmp short die -too_many_os: -disk_error: - mov si,bad_disk_msg -die: -.msgloop: - lodsb - and al,al - jz .now - mov ah,0Eh ; TTY output - mov bh,[BIOS_page] ; Current page - mov bl,07h - int 10h - jmp short .msgloop -.now: - jmp short .now - - align 4, db 0 ; Begin data area - -; -; EBIOS disk address packet -; -dapa: - dw 16 ; Packet size -.count: dw 1 ; Block count -.off: dw 7C00h ; Offset of buffer -.seg: dw 0 ; Segment of buffer -.lba: dd 0 ; LBA (LSW) - dd 0 ; LBA (MSW) - -; CHS information -Heads: dw 0 -Sectors: dw 0 - -; Error messages -missing_os_msg db 'Missing operating system', 13, 10, 0 -bad_disk_msg db 'Operating system loading error', 13, 10, 0 - -; -; Maximum MBR size: 446 bytes; end-of-boot-sector signature also needed. -; Note that some operating systems (NT, DR-DOS) put additional stuff at -; the end of the MBR, so shorter is better. Location 440 is known to -; have a 4-byte attempt-at-unique-ID for some OSes. -; - -PartitionTable equ $$+446 ; Start of partition table - -; -; BSS data; put at 800h -; -DriveNo equ 0800h diff --git a/mbr/oldmbr.asm b/mbr/oldmbr.asm new file mode 100644 index 00000000..31bf1fdf --- /dev/null +++ b/mbr/oldmbr.asm @@ -0,0 +1,229 @@ +; ----------------------------------------------------------------------- +; +; Copyright 2003-2004 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. +; +; ----------------------------------------------------------------------- + +; +; mbr.asm +; +; Simple Master Boot Record, including support for EBIOS extensions. +; +; The MBR lives in front of the boot sector, and is responsible for +; loading the boot sector of the active partition. The EBIOS support +; is needed if the active partition starts beyond cylinder 1024. +; +; This MBR determines all geometry info at runtime. It uses only the +; linear block field in the partition table. It does, however, pass +; the partition table information unchanged to the target OS. +; +; This MBR should be "8086-clean", i.e. not require a 386. +; + +%include "bios.inc" + +; +; Note: The MBR is actually loaded at 0:7C00h, but we quickly move it down to +; 0600h. +; + section .text + cpu 8086 + org 0600h + +_start: cli + xor ax,ax + mov ds,ax + mov es,ax + mov ss,ax + mov sp,7C00h + sti + cld + mov si,sp ; Start address + mov di,0600h ; Destination address + mov cx,512/2 + rep movsw + +; +; Now, jump to the copy at 0600h so we can load the boot sector at 7C00h. +; Since some BIOSes seem to think 0000:7C00h and 07C0:0000h are the same +; thing, use a far jump to canonicalize the address. This also makes +; sure that it is a code speculation barrier. +; + + jmp 0:next ; Jump to copy at 0600h + +next: + mov [DriveNo], dl ; Drive number stored in DL +; +; Check for CHS parameters. This doesn't work on floppy disks, +; but for an MBR we don't care. +; + mov ah,08h ; Get drive parameters + int 13h + xor ax,ax + mov al,dh + inc ax ; From 0-based to count + mov [Heads],ax + and cl,3Fh ; Max sector number + mov [Sectors],cl + ; Note: we actually don't care about the number of + ; cylinders, since that's the highest-order division + +; +; Now look for one (and only one) active partition. +; + mov si,PartitionTable + xor ax,ax + mov cx,4 +checkpartloop: + test byte [si],80h + jz .notactive + inc ax + mov di,si +.notactive: add si,byte 16 + loop checkpartloop + + cmp ax,byte 1 ; Better be only one + jnz not_one_partition + +; +; Now we have the active partition partition information in DS:DI. +; Check to see if we support EBIOS. +; + mov dl,[DriveNo] + mov ax,4100h + mov bx,055AAh + xor cx,cx + xor dh,dh + stc + int 13h + jc no_ebios + cmp bx,0AA55h + jne no_ebios + test cl,1 ; LBA device access + jz no_ebios +; +; We have EBIOS. Load the boot sector using LBA. +; + push di + mov si,dapa + mov bx,[di+8] ; Copy the block address + mov [si+8],bx + mov bx,[di+10] + mov [si+10],bx + mov dl,[DriveNo] + mov ah,42h ; Extended Read + jmp short common_tail +; +; No EBIOS. Load the boot sector using CHS. +; +no_ebios: + push di + mov ax,[di+8] + mov dx,[di+10] + div word [Sectors] + inc dx + mov cx,dx ; Sector # + xor dx,dx + div word [Heads] + ; DX = head #, AX = cylinder # + mov ch,al + shr ax,1 + shr ax,1 + and al,0C0h + or cl,al + mov dh,dl ; Head # + mov dl,[DriveNo] + mov bx,7C00h + mov ax,0201h ; Read one sector +common_tail: + int 13h + jc disk_error + pop si ; DS:SI -> partition table entry +; +; Verify that we have a boot sector, jump +; + cmp word [7C00h+510],0AA55h + jne missing_os + cli + jmp 0:7C00h ; Jump to boot sector; far + ; jump is speculation barrier + ; (Probably not neecessary, but + ; there is plenty of space.) + +not_one_partition: + ja too_many_os +missing_os: + mov si,missing_os_msg + jmp short die +too_many_os: +disk_error: + mov si,bad_disk_msg +die: +.msgloop: + lodsb + and al,al + jz .now + mov ah,0Eh ; TTY output + mov bh,[BIOS_page] ; Current page + mov bl,07h + int 10h + jmp short .msgloop +.now: + jmp short .now + + align 4, db 0 ; Begin data area + +; +; EBIOS disk address packet +; +dapa: + dw 16 ; Packet size +.count: dw 1 ; Block count +.off: dw 7C00h ; Offset of buffer +.seg: dw 0 ; Segment of buffer +.lba: dd 0 ; LBA (LSW) + dd 0 ; LBA (MSW) + +; CHS information +Heads: dw 0 +Sectors: dw 0 + +; Error messages +missing_os_msg db 'Missing operating system', 13, 10, 0 +bad_disk_msg db 'Operating system loading error', 13, 10, 0 + +; +; Maximum MBR size: 446 bytes; end-of-boot-sector signature also needed. +; Note that some operating systems (NT, DR-DOS) put additional stuff at +; the end of the MBR, so shorter is better. Location 440 is known to +; have a 4-byte attempt-at-unique-ID for some OSes. +; + +PartitionTable equ $$+446 ; Start of partition table + +; +; BSS data; put at 800h +; +DriveNo equ 0800h -- cgit v1.2.1 From 0feb9528fb3f3d1421bec2c4e85f66079829042c Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Feb 2007 16:02:25 -0800 Subject: Fix additional references to mbr.bin --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0c58ca00..ff810827 100644 --- a/Makefile +++ b/Makefile @@ -201,8 +201,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 -- cgit v1.2.1 From bb91cb731b6197f156a7d2c9924089e06b5f708b Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Feb 2007 16:03:25 -0800 Subject: Document new MBR. --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 7235850d..76e516b3 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ Changes in 3.36: 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. Changes in 3.35: * MEMDISK: New "safeint" mode. -- cgit v1.2.1 From 97fe6232e2f5fc3c40e6a455aa5870b789949d96 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Feb 2007 16:52:07 -0800 Subject: MBR: produce a list file. --- mbr/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mbr/Makefile b/mbr/Makefile index d96ee467..1772d14e 100644 --- a/mbr/Makefile +++ b/mbr/Makefile @@ -31,7 +31,7 @@ all: mbr.bin .PRECIOUS: %.o %.o: %.S - $(CC) $(SFLAGS) -c -o $@ $< + $(CC) $(SFLAGS) -Wa,-a=$*.lst -c -o $@ $< mbr.elf: mbr.o $(LD) -Ttext 0x600 -e _start -o $@ $^ @@ -41,7 +41,7 @@ mbr.bin: mbr.elf checksize.pl $(PERL) checksize.pl mbr.bin 440 tidy: - rm -f *.o *.elf + rm -f *.o *.elf *.lst -clean: - rm -f *.o *.elf *.bin +clean: tidy + rm -f *.bin -- cgit v1.2.1 From 3524223967b08ffdcf7addfc606aaeacd872dac3 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Feb 2007 16:52:59 -0800 Subject: MBR: Set %si immediately upon setting %sp --- mbr/mbr.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mbr/mbr.S b/mbr/mbr.S index edfccfb1..82dc5a6e 100644 --- a/mbr/mbr.S +++ b/mbr/mbr.S @@ -43,6 +43,7 @@ _start: 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 */ @@ -51,7 +52,6 @@ _start: cld /* Copy down to 0:0x600 */ - movw %sp, %si movw $_start, %di movw $(512/2), %cx rep; movsw -- cgit v1.2.1 From a86b90de0542948b61f24d7a39652d54761d50b9 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Feb 2007 17:24:10 -0800 Subject: Fix numerous problems in the new MBR code. --- mbr/Makefile | 4 ++-- mbr/mbr.S | 35 ++++++++++++++++++----------- mbr/mbr.ld | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 15 deletions(-) create mode 100644 mbr/mbr.ld diff --git a/mbr/Makefile b/mbr/Makefile index 1772d14e..75da4484 100644 --- a/mbr/Makefile +++ b/mbr/Makefile @@ -33,8 +33,8 @@ all: mbr.bin %.o: %.S $(CC) $(SFLAGS) -Wa,-a=$*.lst -c -o $@ $< -mbr.elf: mbr.o - $(LD) -Ttext 0x600 -e _start -o $@ $^ +mbr.elf: mbr.o mbr.ld + $(LD) -T mbr.ld -e _start -o $@ $< mbr.bin: mbr.elf checksize.pl $(OBJCOPY) -O binary $< $@ diff --git a/mbr/mbr.S b/mbr/mbr.S index 82dc5a6e..81e5dd00 100644 --- a/mbr/mbr.S +++ b/mbr/mbr.S @@ -28,14 +28,21 @@ .code16 .text -bootsec = 0x7c00 -stack = bootsec -driveno = (stack-4) -heads = (stack-6) -sectors = (stack-8) + .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 @@ -74,7 +81,7 @@ next: 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) + movw $0xeb+((read_sector_ebios-read_sector_cbios-2)<< 8), (read_sector_cbios) 1: popw %dx @@ -93,7 +100,6 @@ next: pushl %eax /* Base */ pushl %eax /* Root */ call scan_partition_table - /* If we get here, we have no OS */ jmp missing_os @@ -126,6 +132,7 @@ read_sector_ebios: movl %eax, 8(%si) movb $0x42, %ah read_common: + movb (driveno), %dl int $0x13 ret @@ -232,11 +239,13 @@ 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+0x510) - je missing_os /* Not a valid boot sector */ - movw $stack-6, %sp + 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 @@ -274,10 +283,10 @@ missing_os_msg: .ascii "Missing operating system." .byte 0 disk_error_msg: - .ascii "Failed to load operating system." + .ascii "Operating system load error." .byte 0 too_many_active_msg: - .ascii "Multiple active partititons." + .ascii "Multiple active partitions." .byte 0 .balign 4 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) } +} -- cgit v1.2.1 From 9b7224f6a3419bba497b2a47a0c27f8f4893a3cc Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 6 Feb 2007 15:59:49 -0800 Subject: SYSLINUX: Fix extension-detection for syslinux. --- NEWS | 2 ++ ldlinux.asm | 6 +----- ui.inc | 13 +------------ 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/NEWS b/NEWS index 76e516b3..43912b78 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ Changes in 3.36: * 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/ldlinux.asm b/ldlinux.asm index 733f2ec9..0a872c34 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) diff --git a/ui.inc b/ui.inc index 7c68fc54..ad738e3a 100644 --- a/ui.inc +++ b/ui.inc @@ -485,10 +485,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 +496,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 +517,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 -- cgit v1.2.1 From df2e79ce976ff922c46d56183a6a904f9d5b8cf6 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 6 Feb 2007 16:33:39 -0800 Subject: Deal with various distributions breaking gcc in weird ways --- Makefile | 10 ++++++++-- com32/lib/MCONFIG | 7 ++++++- com32/libutil/Makefile | 2 +- com32/modules/Makefile | 2 +- com32/samples/Makefile | 2 +- dos/Makefile | 7 ++++++- dummy.c | 8 ++++++++ extlinux/Makefile | 8 +++++++- mbr/Makefile | 2 +- memdisk/Makefile | 2 +- menu/Makefile | 2 +- mtools/Makefile | 8 +++++++- sample/Makefile | 2 +- unix/Makefile | 8 +++++++- 14 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 dummy.c diff --git a/Makefile b/Makefile index ff810827..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 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/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/mbr/Makefile b/mbr/Makefile index 75da4484..d61f7f1c 100644 --- a/mbr/Makefile +++ b/mbr/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/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/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/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))) -- cgit v1.2.1 From 945a8c5cb5512e472eb894ffa0520e69b8ab54e8 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 6 Feb 2007 16:36:45 -0800 Subject: For extension *search*, SYSLINUX should now use the same code as the others. --- ldlinux.asm | 10 +++++----- ui.inc | 9 --------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/ldlinux.asm b/ldlinux.asm index 0a872c34..a5637cd1 100644 --- a/ldlinux.asm +++ b/ldlinux.asm @@ -1599,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/ui.inc b/ui.inc index ad738e3a..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) -- cgit v1.2.1 From 92e1735c75ef9fe093d51ffe5ba609aec2b1a532 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 7 Feb 2007 14:12:46 -0800 Subject: fileread: ES:BX -> buffer, not ES:SI --- com32/lib/sys/fileread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com32/lib/sys/fileread.c b/com32/lib/sys/fileread.c index e184fc35..cbdb8ce0 100644 --- a/com32/lib/sys/fileread.c +++ b/com32/lib/sys/fileread.c @@ -46,7 +46,7 @@ ssize_t __file_read(struct file_info *fp, void *buf, size_t count) memset(&ireg, 0, sizeof ireg); ireg.eax.w[0] = 0x0007; /* Read file */ - ireg.esi.w[0] = OFFS(__com32.cs_bounce); + ireg.ebx.w[0] = OFFS(__com32.cs_bounce); ireg.es = SEG(__com32.cs_bounce); while ( count ) { -- cgit v1.2.1 From b1e23e244b881b17b278dc54bacffb6b462a1e2d Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 7 Feb 2007 14:16:33 -0800 Subject: fileread: new file descriptor should be from oreg, not ireg --- com32/lib/sys/fileread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com32/lib/sys/fileread.c b/com32/lib/sys/fileread.c index cbdb8ce0..8fdd9167 100644 --- a/com32/lib/sys/fileread.c +++ b/com32/lib/sys/fileread.c @@ -64,7 +64,7 @@ ssize_t __file_read(struct file_info *fp, void *buf, size_t count) return -1; } - fp->i.filedes = ireg.esi.w[0]; + fp->i.filedes = oreg.esi.w[0]; fp->i.nbytes = min(fp->i.length-fp->i.offset, (unsigned)MAXBLOCK); fp->i.datap = fp->i.buf; memcpy(fp->i.buf, __com32.cs_bounce, fp->i.nbytes); -- cgit v1.2.1 From 0264d03fc1ac26b65ee4c28b136d88794cb88214 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 8 Feb 2007 09:58:09 -0800 Subject: PXELINUX: ES:BX -> PXENV+, so we can't have ES:DI -> $PnP. This broke chainbooting FreeBSD at least. --- NEWS | 1 + bootsect.inc | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 43912b78..c8e472fb 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ Changes in 3.36: * New MBR which can boot from logical partitions. * SYSLINUX: Fix bug in detecting special extensions which was introduced in 3.35 :( + * PXELINUX: Unbreak chainbooting FreeBSD (and possibly others.) Changes in 3.35: * MEMDISK: New "safeint" mode. diff --git a/bootsect.inc b/bootsect.inc index d52aefba..66e1886a 100644 --- a/bootsect.inc +++ b/bootsect.inc @@ -136,6 +136,11 @@ replace_bootstrap: mov [es:di+12],esi ; New ESI mov [es:di+6],bx ; New DS +%ifndef IS_PXELINUX + ; DON'T DO THIS FOR PXELINUX... + ; For PXE, ES:BX -> PXENV+, and this would corrupt + ; that use. + ; Hunt for $PnP header if one exists mov ax,0F000h mov fs,ax @@ -163,6 +168,7 @@ replace_bootstrap: ; Found a valid $PnP header, point ES:DI to it mov [es:di+8], bx ; New DI mov [es:di+4], fs ; New ES +%endif .donepnp: pop ax ; Copy list count -- cgit v1.2.1 From 0498d80af5bae472629762bc953c265d96ebf7c9 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 8 Feb 2007 10:14:55 -0800 Subject: %ifndef IS_PXELINUX won't do much good... %if IS_PXELINUX == 0 is correct --- bootsect.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootsect.inc b/bootsect.inc index 66e1886a..a2137ecf 100644 --- a/bootsect.inc +++ b/bootsect.inc @@ -136,7 +136,7 @@ replace_bootstrap: mov [es:di+12],esi ; New ESI mov [es:di+6],bx ; New DS -%ifndef IS_PXELINUX +%if IS_PXELINUX == 0 ; DON'T DO THIS FOR PXELINUX... ; For PXE, ES:BX -> PXENV+, and this would corrupt ; that use. -- cgit v1.2.1 From 4f089e2e47f023d51ebba87ecf21c944302115cc Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 8 Feb 2007 16:02:41 -0800 Subject: Fix -fno-stack-protector per bug report from Gilles Espinasse --- com32/libutil/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com32/libutil/Makefile b/com32/libutil/Makefile index 8976ebd8..3656fb3f 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,) $(call gcc_ok,-fno_stack_protector,) +M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,) CC = gcc LD = ld -m elf_i386 -- cgit v1.2.1 From d48bb2b249d996587cfe6e39e810a9805d013abe Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 8 Feb 2007 18:05:23 -0800 Subject: Set up the LRU chain correctly (d'oh!) --- cache.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/cache.inc b/cache.inc index 95c5f48e..47d815f6 100644 --- a/cache.inc +++ b/cache.inc @@ -33,6 +33,7 @@ initcache: 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 + mov bx,di add di,cptr_size loop .loop ret -- cgit v1.2.1