diff --git a/com32/elflink/ldlinux/kernel.c b/com32/elflink/ldlinux/kernel.c index f3ba37fa..942f97cc 100644 --- a/com32/elflink/ldlinux/kernel.c +++ b/com32/elflink/ldlinux/kernel.c @@ -48,14 +48,6 @@ int new_linux_kernel(char *okernel, char *ocmdline) sprintf(cmdline, "BOOT_IMAGE=%s %s", kernel_name, args); - /* "keeppxe" handling */ -#if IS_PXELINUX - extern char KeepPXE; - - if (strstr(cmdline, "keeppxe")) - KeepPXE |= 1; -#endif - if (strstr(cmdline, "quiet")) opt_quiet = true; diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c index 26c39c1a..0edb7712 100644 --- a/com32/lib/syslinux/load_linux.c +++ b/com32/lib/syslinux/load_linux.c @@ -48,6 +48,7 @@ #include #include #include +#include #define BOOT_MAGIC 0xAA55 #define LINUX_MAGIC ('H' + ('d' << 8) + ('r' << 16) + ('S' << 24)) @@ -166,6 +167,7 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, struct syslinux_memmap *amap = NULL; uint32_t memlimit = 0; uint16_t video_mode = 0; + uint16_t bootflags = 0; const char *arg; cmdline_size = strlen(cmdline) + 1; @@ -200,6 +202,14 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, } } + if (syslinux_filesystem() == SYSLINUX_FS_PXELINUX && + strstr(cmdline, "keeppxe")) { + extern __weak char KeepPXE; + + KeepPXE |= 1; /* for pxelinux_scan_memory */ + bootflags = 3; /* for unload_pxe */ + } + /* Copy the header into private storage */ /* Use whdr to modify the actual kernel header */ memcpy(&hdr, kernel_buf, sizeof hdr); @@ -495,7 +505,7 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, dprintf("*** vga=current, not calling syslinux_force_text_mode()...\n"); } - syslinux_shuffle_boot_rm(fraglist, mmap, 0, ®s); + syslinux_shuffle_boot_rm(fraglist, mmap, bootflags, ®s); dprintf("shuffle_boot_rm failed\n"); bail: diff --git a/core/Makefile b/core/Makefile index 46cb037c..50ff35af 100644 --- a/core/Makefile +++ b/core/Makefile @@ -41,9 +41,9 @@ BTARGET = kwdhash.gen \ # All primary source files for the main syslinux files NASMSRC := $(sort $(wildcard $(SRC)/*.asm)) NASMHDR := $(sort $(wildcard $(SRC)/*.inc)) -CSRC := $(shell find $(SRC) -name '*.c' -print) -SSRC := $(shell find $(SRC) -name '*.S' -print) -CHDR := $(shell find $(SRC) -name '*.h' -print) +CSRC := $(sort $(shell find $(SRC) -name '*.c' -print)) +SSRC := $(sort $(shell find $(SRC) -name '*.S' -print)) +CHDR := $(sort $(shell find $(SRC) -name '*.h' -print)) OTHERSRC := keywords ALLSRC = $(NASMSRC) $(NASMHDR) $(CSRC) $(SSRC) $(CHDR) $(OTHERSRC) @@ -56,13 +56,13 @@ CORE_PXE_CSRC = \ $(addprefix $(SRC)/fs/pxe/, dhcp_option.c pxe.c tftp.c urlparse.c bios.c) LPXELINUX_CSRC = $(CORE_PXE_CSRC) \ - $(shell find $(SRC)/lwip -name '*.c' -print) \ + $(sort $(shell find $(SRC)/lwip -name '*.c' -print)) \ $(addprefix $(SRC)/fs/pxe/, \ core.c dnsresolv.c ftp.c ftp_readdir.c gpxeurl.c http.c \ http_readdir.c idle.c isr.c tcp.c) PXELINUX_CSRC = $(CORE_PXE_CSRC) \ - $(shell find $(SRC)/legacynet -name '*.c' -print) + $(sort $(shell find $(SRC)/legacynet -name '*.c' -print)) LPXELINUX_OBJS = $(subst $(SRC)/,,$(LPXELINUX_CSRC:%.c=%.o)) PXELINUX_OBJS = $(subst $(SRC)/,,$(PXELINUX_CSRC:%.c=%.o)) diff --git a/core/fs/ext2/ext2.c b/core/fs/ext2/ext2.c index 76bd1d5a..4bc0a535 100644 --- a/core/fs/ext2/ext2.c +++ b/core/fs/ext2/ext2.c @@ -25,22 +25,17 @@ static enum dirent_type ext2_cvt_type(unsigned int d_file_type) return inode_type[d_file_type]; } -/* - * get the group's descriptor of group_num - */ -static const struct ext2_group_desc * -ext2_get_group_desc(struct fs_info *fs, uint32_t group_num) +static const void *__ext2_get_group_desc(struct fs_info *fs, uint32_t group_num) { struct ext2_sb_info *sbi = EXT2_SB(fs); uint32_t desc_block, desc_index; - const struct ext2_group_desc *desc_data_block; + uint8_t *p; if (group_num >= sbi->s_groups_count) { printf ("ext2_get_group_desc" "block_group >= groups_count - " "block_group = %d, groups_count = %d", group_num, sbi->s_groups_count); - return NULL; } @@ -49,8 +44,17 @@ ext2_get_group_desc(struct fs_info *fs, uint32_t group_num) desc_block += sbi->s_first_data_block + 1; - desc_data_block = get_cache(fs->fs_dev, desc_block); - return &desc_data_block[desc_index]; + p = get_cache(fs->fs_dev, desc_block); + return p + sbi->s_desc_size * desc_index; +} + +/* + * get the group's descriptor of group_num + */ +static inline const struct ext2_group_desc * +ext2_get_group_desc(struct fs_info *fs, uint32_t group_num) +{ + return __ext2_get_group_desc(fs, group_num); } /* @@ -306,6 +310,7 @@ static int ext2_fs_init(struct fs_info *fs) if (sb.s_desc_size < sizeof(struct ext2_group_desc)) sb.s_desc_size = sizeof(struct ext2_group_desc); sbi->s_desc_per_block = BLOCK_SIZE(fs) / sb.s_desc_size; + sbi->s_desc_size = sb.s_desc_size; sbi->s_groups_count = (sb.s_blocks_count - sb.s_first_data_block + EXT2_BLOCKS_PER_GROUP(fs) - 1) / EXT2_BLOCKS_PER_GROUP(fs); diff --git a/core/fs/ext2/ext2_fs.h b/core/fs/ext2/ext2_fs.h index 803a9954..d8d07ebd 100644 --- a/core/fs/ext2/ext2_fs.h +++ b/core/fs/ext2/ext2_fs.h @@ -278,6 +278,7 @@ struct ext2_sb_info { uint32_t s_first_data_block; /* First Data Block */ int s_inode_size; uint8_t s_uuid[16]; /* 128-bit uuid for volume */ + int s_desc_size; /* size of group descriptor */ }; static inline struct ext2_sb_info *EXT2_SB(struct fs_info *fs) diff --git a/efi/Makefile b/efi/Makefile index d3788d90..f4501e7f 100644 --- a/efi/Makefile +++ b/efi/Makefile @@ -14,18 +14,20 @@ VPATH = $(SRC) include $(MAKEDIR)/lib.mk include $(MAKEDIR)/efi.mk +CC_FOR_BUILD ?= $(CC) + # Upstream gnu-efi has old-style function definitions. CFLAGS += -Wno-strict-prototypes -CORE_CSRC := $(wildcard $(core)/*.c $(core)/*/*.c $(core)/*/*/*.c) +CORE_CSRC := $(sort $(wildcard $(core)/*.c $(core)/*/*.c $(core)/*/*/*.c)) CORE_COBJ := $(subst $(core),$(OBJ)/../core,$(patsubst %.c,%.o,$(CORE_CSRC))) # We don't want to include any of the networking stack or the thread # code since it will be implemented completely differently for EFI. -FILTERED_OBJS:= $(subst $(core),$(OBJ)/../core,$(patsubst %.c,%.o, \ +FILTERED_OBJS:= $(sort $(subst $(core),$(OBJ)/../core,$(patsubst %.c,%.o, \ $(wildcard $(core)/legacynet/*.c) \ $(wildcard $(core)/fs/pxe/*.c) \ - $(wildcard $(core)/thread/*.c))) + $(wildcard $(core)/thread/*.c)))) # Don't include unit tests FILTERED_OBJS += $(subst $(core),$(OBJ)/../core, \ @@ -44,7 +46,7 @@ CORE_OBJS += $(addprefix $(OBJ)/../core/, \ LIB_OBJS = $(addprefix $(objdir)/com32/lib/,$(CORELIBOBJS)) \ $(LIBEFI) -CSRC = $(wildcard $(SRC)/*.c) +CSRC = $(sort $(wildcard $(SRC)/*.c)) OBJS = $(subst $(SRC)/,,$(filter-out %wrapper.o, $(patsubst %.c,%.o,$(CSRC)))) OBJS += $(objdir)/core/codepage.o $(ARCH)/linux.o @@ -78,7 +80,7 @@ syslinux.so: $(OBJS) $(CORE_OBJS) $(LIB_OBJS) # cp $^ $@ wrapper: wrapper.c - $(CC) $^ -o $@ + $(CC_FOR_BUILD) $^ -o $@ # # Build the wrapper app and wrap our .so to produce a .efi diff --git a/efi/udp.c b/efi/udp.c index 1088f470..288010cf 100644 --- a/efi/udp.c +++ b/efi/udp.c @@ -10,14 +10,6 @@ extern EFI_GUID Udp4ServiceBindingProtocol, Udp4Protocol; -/* - * This UDP binding is configured to operate in promiscuous mode. It is - * only used for reading packets. It has no associated state unlike - * socket->net.efi.binding, which has a remote IP address and port - * number. - */ -static struct efi_binding *udp_reader; - static int volatile efi_udp_has_recv = 0; int volatile efi_net_def_addr = 1; @@ -76,17 +68,11 @@ int core_udp_open(struct pxe_pvt_inode *socket) EFI_STATUS status; EFI_UDP4 *udp; - (void)socket; - - udp_reader = efi_create_binding(&Udp4ServiceBindingProtocol, &Udp4Protocol); - if (!udp_reader) - return -1; - b = efi_create_binding(&Udp4ServiceBindingProtocol, &Udp4Protocol); if (!b) goto bail; - udp = (EFI_UDP4 *)udp_reader->this; + udp = (EFI_UDP4 *)b->this; memset(&udata, 0, sizeof(udata)); @@ -114,9 +100,6 @@ int core_udp_open(struct pxe_pvt_inode *socket) if (b) efi_destroy_binding(b, &Udp4ServiceBindingProtocol); - efi_destroy_binding(udp_reader, &Udp4ServiceBindingProtocol); - udp_reader = NULL; - return -1; } @@ -127,9 +110,6 @@ int core_udp_open(struct pxe_pvt_inode *socket) */ void core_udp_close(struct pxe_pvt_inode *socket) { - efi_destroy_binding(udp_reader, &Udp4ServiceBindingProtocol); - udp_reader = NULL; - if (!socket->net.efi.binding) return; @@ -158,18 +138,24 @@ void core_udp_connect(struct pxe_pvt_inode *socket, uint32_t ip, /* Re-use the existing local port number */ udata.StationPort = socket->net.efi.localport; +retry: if (efi_net_def_addr) { udata.UseDefaultAddress = TRUE; } else { udata.UseDefaultAddress = FALSE; memcpy(&udata.StationAddress, &IPInfo.myip, sizeof(IPInfo.myip)); - memcpy(&udata.StationAddress, &IPInfo.netmask, sizeof(IPInfo.netmask)); + memcpy(&udata.SubnetMask, &IPInfo.netmask, sizeof(IPInfo.netmask)); } memcpy(&udata.RemoteAddress, &ip, sizeof(ip)); udata.RemotePort = port; udata.TimeToLive = 64; status = core_udp_configure(udp, &udata, L"core_udp_connect"); + if (efi_net_def_addr && (status == EFI_NO_MAPPING)) { + efi_net_def_addr = 0; + Print(L"disable UseDefaultAddress\n"); + goto retry; + } if (status != EFI_SUCCESS) { Print(L"Failed to configure UDP: %d\n", status); return; @@ -233,7 +219,7 @@ int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len, (void)socket; - b = udp_reader; + b = socket->net.efi.binding; udp = (EFI_UDP4 *)b->this; memset(&token, 0, sizeof(token)); @@ -392,6 +378,7 @@ void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data, /* Re-use the existing local port number */ udata.StationPort = socket->net.efi.localport; +retry: if (efi_net_def_addr) { udata.UseDefaultAddress = TRUE; } else { @@ -404,6 +391,11 @@ void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data, udata.TimeToLive = 64; status = core_udp_configure(udp, &udata, L"core_udp_sendto"); + if (efi_net_def_addr && (status == EFI_NO_MAPPING)) { + efi_net_def_addr = 0; + Print(L"disable UseDefaultAddress\n"); + goto retry; + } if (status != EFI_SUCCESS) goto bail; diff --git a/libinstaller/bin2c.pl b/libinstaller/bin2c.pl index 07c11ddb..c79a506f 100755 --- a/libinstaller/bin2c.pl +++ b/libinstaller/bin2c.pl @@ -71,8 +71,11 @@ printf "\n};\n\nconst unsigned int %s_len = %u;\n", $table_name, $total_len; -@st = stat STDIN; - -printf "\nconst int %s_mtime = %d;\n", $table_name, $st[9]; +if (defined $ENV{'SOURCE_DATE_EPOCH'}) { + printf "\nconst int %s_mtime = %s;\n", $table_name, $ENV{'SOURCE_DATE_EPOCH'}; +} else { + @st = stat STDIN; + printf "\nconst int %s_mtime = %d;\n", $table_name, $st[9]; +} exit 0; diff --git a/lzo/prepcore.c b/lzo/prepcore.c index 9147b2e4..b5ebe88b 100644 --- a/lzo/prepcore.c +++ b/lzo/prepcore.c @@ -331,7 +331,7 @@ int main(int argc, char *argv[]) unsigned int ptr; outfile_len = ((offset - start + out_len + 2047) & ~2047) - (offset - start); - for (ptr = 64; ptr < offset; ptr += 4) + for (ptr = start + 64; ptr < offset; ptr += 4) csum += get_32((uint32_t *) (infile + ptr)); for (ptr = 0; ptr < outfile_len; ptr += 4) csum += get_32((uint32_t *) (out + ptr)); diff --git a/man/extlinux.1 b/man/extlinux.1 index 5daa4e52..14e6be12 100644 --- a/man/extlinux.1 +++ b/man/extlinux.1 @@ -1,17 +1,17 @@ -.TH extlinux "1" "18 December 2007" "SYSLINUX for ext2/ext3 filesystem" +.TH extlinux "1" "18 December 2007" "SYSLINUX for ext/btrfs/xfs filesystems" .SH NAME -extlinux \- install the \s-1SYSLINUX\s+1 bootloader on a ext2/ext3 filesystem +extlinux \- install the \s-1SYSLINUX\s+1 bootloader on an ext2/ext3/ext4/btrfs/xfs filesystem .SH SYNOPSIS .B extlinux [\fIoptions\fP] \fIdirectory\fP .SH DESCRIPTION -\fBEXTLINUX\fP is a new syslinux derivative, which boots from a Linux ext2/ext3 +\fBEXTLINUX\fP is a new syslinux derivative, which boots from a Linux ext2/ext3/ext4/btrfs or xfs filesystem. It works the same way as \fBSYSLINUX\fP, with a few slight modifications. It is intended to simplify first-time installation of Linux, and for creation of rescue and other special-purpose boot disks. .PP The installer is designed to be run on a mounted directory. For example, if you have an -ext2 or ext3 usb key mounted on /mnt, you can run the following command: +ext2, ext3, ext4, or btrfs usb key mounted on /mnt, you can run the following command: .IP .B extlinux --install /mnt .SH OPTIONS @@ -56,6 +56,9 @@ The extlinux configuration file needs to be named syslinux.cfg or extlinux.conf and needs to be stored in the extlinux installation directory. For more information about the contents of extlinux.conf, see syslinux(1) manpage, section files. +.SH LIMITATIONS +Booting from XFS only works when an MBR partition table is used (not on GPT +partition tables). .SH BUGS I would appreciate hearing of any problems you have with \s-1SYSLINUX\s+1. I would also like to hear from you if you have successfully used \s-1SYSLINUX\s+1, @@ -66,8 +69,14 @@ about your system and your BIOS; the vast majority of all problems reported turn out to be BIOS or hardware bugs, and I need as much information as possible in order to diagnose the problems. .PP -There is a mailing list for discussion among \s-1SYSLINUX\s+1 users and for -announcements of new and test versions. To join, send a message to -majordomo@linux.kernel.org with the line: +There is a +.MT syslinux@\:zytor.com +mailing list +.ME +for discussion among \s-1SYSLINUX\s+1 users and for announcements of new and +test versions. You can +.UR http://\:www.zytor.com/\:mailman/\:listinfo/\:syslinux +subscribe to this mailing list +.UE . .SH SEE ALSO .BR syslinux (1) diff --git a/mbr/isohdpfx.S b/mbr/isohdpfx.S index 17e1efe1..4b107e4b 100644 --- a/mbr/isohdpfx.S +++ b/mbr/isohdpfx.S @@ -167,20 +167,22 @@ next: read_sector_cbios: movb $0x42, %ah ; jmp read_common */ movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \ (read_sector_cbios) - jmp 1f + jmp 2f 1: + xor %cx, %cx /* Clear EBIOS flag. */ +2: popw %dx pushw %cx /* EBIOS flag */ /* Get (C)HS geometry */ movb $0x08, %ah int $0x13 - andw $0x3f, %cx /* Sector count */ popw %bx /* EBIOS flag */ - pushw %cx /* -16: Save sectors on the stack */ movzbw %dh, %ax /* dh = max head */ incw %ax /* From 0-based max to count */ - pushw %ax /* -18: Save heads on the stack */ + pushw %ax /* -16: Save heads on the stack */ + andw $0x3f, %cx /* Sector count */ + pushw %cx /* -18: Save sectors on the stack */ mulw %cx /* Heads*sectors -> sectors per cylinder */ pushw %bx /* -20: EBIOS flag */ diff --git a/memdisk/Makefile b/memdisk/Makefile index 42e56e00..ccd5738b 100644 --- a/memdisk/Makefile +++ b/memdisk/Makefile @@ -78,7 +78,7 @@ memdisk16.o: memdisk16.asm $(NASM) -f bin $(NASMOPT) $(NFLAGS) $(NINCLUDE) -o $@ -l $*.lst $< memdisk_%.o: memdisk_%.bin - $(LD) -r -b binary -o $@ $< + $(LD) --oformat elf32-i386 -r -b binary -o $@ $< memdisk16.elf: $(OBJS16) $(LD) -Ttext 0 -o $@ $^ diff --git a/utils/Makefile b/utils/Makefile index dfe62590..b1031249 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -17,8 +17,10 @@ VPATH = $(SRC) include $(MAKEDIR)/syslinux.mk -CFLAGS = $(GCCWARN) -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64 -I$(SRC) -LDFLAGS = -O2 +CC_FOR_BUILD ?= $(CC) + +CFLAGS = $(CFLAGS_FOR_BUILD) $(GCCWARN) -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64 -I$(SRC) +LDFLAGS = $(LDFLAGS_FOR_BUILD) -O2 C_TARGETS = isohybrid gethostip memdiskfind SCRIPT_TARGETS = mkdiskimage @@ -35,7 +37,7 @@ ISOHDPFX = $(addprefix $(OBJ)/,../mbr/isohdpfx.bin ../mbr/isohdpfx_f.bin \ all: $(TARGETS) %.o: %.c - $(CC) $(UMAKEDEPS) $(CFLAGS) -c -o $@ $< + $(CC_FOR_BUILD) $(UMAKEDEPS) $(CFLAGS) -c -o $@ $< mkdiskimage: mkdiskimage.in ../mbr/mbr.bin bin2hex.pl $(PERL) $(SRC)/bin2hex.pl < $(OBJ)/../mbr/mbr.bin | cat $(SRC)/mkdiskimage.in - > $@ @@ -51,13 +53,13 @@ isohdpfx.c: $(ISOHDPFX) isohdpfxarray.pl $(PERL) $(SRC)/isohdpfxarray.pl $(ISOHDPFX) > $@ isohybrid: isohybrid.o isohdpfx.o - $(CC) $(LDFLAGS) -o $@ $^ -luuid + $(CC_FOR_BUILD) $(LDFLAGS) -o $@ $^ -luuid gethostip: gethostip.o - $(CC) $(LDFLAGS) -o $@ $^ + $(CC_FOR_BUILD) $(LDFLAGS) -o $@ $^ memdiskfind: memdiskfind.o - $(CC) $(LDFLAGS) -o $@ $^ + $(CC_FOR_BUILD) $(LDFLAGS) -o $@ $^ tidy dist: rm -f *.o .*.d isohdpfx.c diff --git a/utils/isohybrid.c b/utils/isohybrid.c index 1a203213..a9e38d4d 100644 --- a/utils/isohybrid.c +++ b/utils/isohybrid.c @@ -967,7 +967,7 @@ main(int argc, char *argv[]) srand(time(NULL) << (getppid() << getpid())); - if (!(fp = fopen(argv[0], "r+"))) + if (!(fp = fopen(argv[0], "rb+"))) err(1, "could not open file `%s'", argv[0]); if (fseeko(fp, (off_t) (16 << 11), SEEK_SET)) diff --git a/utils/sha1pass b/utils/sha1pass index 3be2dbc1..34cc99c0 100755 --- a/utils/sha1pass +++ b/utils/sha1pass @@ -1,7 +1,7 @@ #!/usr/bin/perl use bytes; -use Digest::SHA1; +use Digest::SHA; use MIME::Base64; sub random_bytes($) { @@ -29,6 +29,6 @@ sub random_bytes($) { unless (defined($salt)) { $salt = MIME::Base64::encode(random_bytes(6), ''); } -$pass = Digest::SHA1::sha1_base64($salt, $pass); +$pass = Digest::SHA::sha1_base64($salt, $pass); print '$4$', $salt, '$', $pass, "\$\n";