aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--adv.inc19
-rw-r--r--bin2c.pl26
-rw-r--r--dos/Makefile8
-rw-r--r--extlinux.asm3
-rw-r--r--extlinux/Makefile8
-rw-r--r--extlinux/extlinux.c333
-rw-r--r--layout.inc7
-rw-r--r--libinstaller/syslinux.h (renamed from syslinux.h)10
-rw-r--r--libinstaller/syslxmod.c (renamed from syslxmod.c)0
-rw-r--r--mtools/Makefile4
-rw-r--r--unix/Makefile4
-rw-r--r--win32/Makefile7
13 files changed, 324 insertions, 107 deletions
diff --git a/Makefile b/Makefile
index 73b06b42..931af2ad 100644
--- a/Makefile
+++ b/Makefile
@@ -181,7 +181,7 @@ extlinux_bss_bin.c: extlinux.bss bin2c.pl
$(PERL) bin2c.pl extlinux_bootsect < $< > $@
extlinux_sys_bin.c: extlinux.sys bin2c.pl
- $(PERL) bin2c.pl extlinux_image < $< > $@
+ $(PERL) bin2c.pl extlinux_image 512 < $< > $@
libsyslinux.a: bootsect_bin.o ldlinux_bin.o mbr_bin.o syslxmod.o
rm -f $@
diff --git a/adv.inc b/adv.inc
index b84ae049..03869514 100644
--- a/adv.inc
+++ b/adv.inc
@@ -46,16 +46,16 @@ adv_retries equ 6 ; Disk retries
section .adv
; Introduce the ADVs to valid but blank
adv0:
-.head dd ADV_MAGIC1
-.csum dd ADV_MAGIC2
-.data times ADV_LEN db 0
-.tail dd ADV_MAGIC3
+.head resd 1
+.csum resd 1
+.data resb ADV_LEN
+.tail resd 1
.end
adv1:
-.head dd ADV_MAGIC1
-.csum dd ADV_MAGIC2
-.data times ADV_LEN db 0
-.tail dd ADV_MAGIC3
+.head resd 1
+.csum resd 1
+.data resb ADV_LEN
+.tail resd 1
.end
section .text
@@ -67,7 +67,8 @@ adv_init:
cmp byte [ADVDrive],-1
jne adv_read
-%if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
+;%if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
+%if IS_EXTLINUX ; Not yet implemented for the other derivatives
;
; Update pointers to default ADVs...
;
diff --git a/bin2c.pl b/bin2c.pl
index 5ef1c034..2bd95d59 100644
--- a/bin2c.pl
+++ b/bin2c.pl
@@ -18,12 +18,14 @@
eval { use bytes; };
eval { binmode STDIN; };
-if ( $#ARGV != 0 ) {
- print STDERR "Usage: $0 table_name < input_file > output_file\n";
+($table_name, $pad) = @ARGV;
+
+if ( !defined($table_name) ) {
+ print STDERR "Usage: $0 table_name [pad] < input_file > output_file\n";
exit 1;
}
-($table_name) = @ARGV;
+$pad = 1 if ($pad < 1);
printf "unsigned char %s[] = {\n", $table_name;
@@ -49,6 +51,24 @@ while ( ($n = read(STDIN, $data, 4096)) > 0 ) {
}
}
+$align = $total_len % $pad;
+if ($align != 0) {
+ $n = $pad - $align;
+ $total_len += $n;
+ for ( $i = 0 ; $i < $n ; $i++ ) {
+ if ( $pos >= $linelen ) {
+ print ",\n\t";
+ $pos = 0;
+ } elsif ( $pos > 0 ) {
+ print ", ";
+ } else {
+ print "\t";
+ }
+ print '0x00';
+ $pos++;
+ }
+}
+
printf "\n};\n\nunsigned int %s_len = %u;\n", $table_name, $total_len;
@st = stat STDIN;
diff --git a/dos/Makefile b/dos/Makefile
index 53406b19..1bfc5135 100644
--- a/dos/Makefile
+++ b/dos/Makefile
@@ -3,13 +3,15 @@ TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX)
gcc_ok = $(shell tmpf=$(TMPFILE); if gcc $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \
then echo $(1); else echo $(2); fi; rm -f $$tmpf)
-M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector,)
+M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) \
+ $(call gcc_ok,-fno-stack-protector,) \
+ $(call gcc_ok,-fno-top-level-reorder,$(call gcc_ok,-fno-unit-at-a-time))
CC = gcc
LD = ld -m elf_i386
OBJCOPY = objcopy
OPTFLAGS = -g -Os -march=i386 -falign-functions=0 -falign-jumps=0 -falign-loops=0 -fomit-frame-pointer
-INCLUDES = -include code16.h -I. -I.. -I../libfat
+INCLUDES = -include code16.h -I. -I.. -I../libfat -I ../libinstaller
CFLAGS = $(M32) -mregparm=3 -DREGPARM=3 -W -Wall -msoft-float $(OPTFLAGS) $(INCLUDES)
LDFLAGS = -T com16.ld
AR = ar
@@ -25,7 +27,7 @@ LIBOBJS = conio.o memcpy.o memset.o skipatou.o atou.o malloc.o free.o \
.SUFFIXES: .c .o .i .s .S .elf .com
-VPATH = .:..:../libfat
+VPATH = .:..:../libfat:../libinstaller
TARGETS = syslinux.com
diff --git a/extlinux.asm b/extlinux.asm
index 818d7548..27eaed34 100644
--- a/extlinux.asm
+++ b/extlinux.asm
@@ -599,9 +599,6 @@ CheckSum dd 0 ; Checksum starting at ldlinux_sys
; value = LDLINUX_MAGIC - [sum of dwords]
CurrentDir dd 2 ; "Current" directory inode number
-; Pointer to auxilliary data vector, for the benefit of the installer.
-ADVPtr dw adv0
-
; Space for up to 64 sectors, the theoretical maximum
SectorPtrs times 64 dd 0
diff --git a/extlinux/Makefile b/extlinux/Makefile
index d2ea6f9b..908d1ce5 100644
--- a/extlinux/Makefile
+++ b/extlinux/Makefile
@@ -8,16 +8,16 @@ LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,)
CC = gcc
OPTFLAGS = -g -Os
-INCLUDES = -I. -I.. -I../libfat
+INCLUDES = -I. -I.. -I../libinstaller
CFLAGS = -W -Wall -Wno-sign-compare -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES)
-LDFLAGS = $(LDHASH) -s
+LDFLAGS = $(LDHASH) # -s
-SRCS = extlinux.c ../extlinux_bss_bin.c ../extlinux_sys_bin.c
+SRCS = extlinux.c setadv.c extlinux_bss_bin.c extlinux_sys_bin.c
OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
.SUFFIXES: .c .o .i .s .S
-VPATH = .:..
+VPATH = .:..:../libinstaller
all: installer
diff --git a/extlinux/extlinux.c b/extlinux/extlinux.c
index a3d57bd2..ac244970 100644
--- a/extlinux/extlinux.c
+++ b/extlinux/extlinux.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 1998-2005 H. Peter Anvin - All Rights Reserved
+ * Copyright 1998-2007 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,6 +43,7 @@ typedef uint64_t u64;
#include "ext2_fs.h"
#include "../version.h"
+#include "syslxint.h"
#ifdef DEBUG
# define dprintf printf
@@ -59,10 +60,14 @@ struct my_options {
unsigned int sectors;
unsigned int heads;
int raid_mode;
+ int reset_adv;
+ const char *set_once;
} opt = {
.sectors = 0,
.heads = 0,
.raid_mode = 0,
+ .reset_adv = 0,
+ .set_once = NULL,
};
static void __attribute__((noreturn)) usage(int rv)
@@ -75,6 +80,9 @@ static void __attribute__((noreturn)) usage(int rv)
" --sectors=# -S Force the number of sectors per track\n"
" --heads=# -H Force number of heads\n"
" --raid -r Fall back to the next device on boot failure\n"
+ " --once=... -o Execute a command once upon boot\n"
+ " --clear-once -O Clear the boot-once command\n"
+ " --reset-adv Reset auxilliary data\n"
"\n"
" Note: geometry is determined at boot time for devices which\n"
" are considered hard disks by the BIOS. Unfortunately, this is\n"
@@ -88,19 +96,27 @@ static void __attribute__((noreturn)) usage(int rv)
exit(rv);
}
+enum long_only_opt {
+ OPT_NONE,
+ OPT_RESET_ADV,
+};
+
static const struct option long_options[] = {
- { "install", 0, NULL, 'i' },
- { "update", 0, NULL, 'U' },
- { "zipdrive", 0, NULL, 'z' },
- { "sectors", 1, NULL, 'S' },
- { "heads", 1, NULL, 'H' },
- { "raid-mode", 0, NULL, 'r' },
- { "version", 0, NULL, 'v' },
- { "help", 0, NULL, 'h' },
+ { "install", 0, NULL, 'i' },
+ { "update", 0, NULL, 'U' },
+ { "zipdrive", 0, NULL, 'z' },
+ { "sectors", 1, NULL, 'S' },
+ { "heads", 1, NULL, 'H' },
+ { "raid-mode", 0, NULL, 'r' },
+ { "version", 0, NULL, 'v' },
+ { "help", 0, NULL, 'h' },
+ { "once", 1, NULL, 'o' },
+ { "clear-once", 0, NULL, 'O' },
+ { "reset-adv", 0, NULL, OPT_RESET_ADV },
{ 0, 0, 0, 0 }
};
-static const char short_options[] = "iUuzS:H:rvh";
+static const char short_options[] = "iUuzS:H:rvho:O";
#if defined(__linux__) && !defined(BLKGETSIZE64)
/* This takes a u64, but the size field says size_t. Someone screwed big. */
@@ -158,66 +174,10 @@ enum bs_offsets {
#define bsCode bs32Code /* The common safe choice */
#define bsCodeLen (bsSignature-bs32Code)
-/*
- * Access functions for littleendian numbers, possibly misaligned.
- */
-static inline uint8_t get_8(const unsigned char *p)
-{
- return *(const uint8_t *)p;
-}
-
-static inline uint16_t get_16(const unsigned char *p)
-{
-#if defined(__i386__) || defined(__x86_64__)
- /* Littleendian and unaligned-capable */
- return *(const uint16_t *)p;
-#else
- return (uint16_t)p[0] + ((uint16_t)p[1] << 8);
-#endif
-}
-
-static inline uint32_t get_32(const unsigned char *p)
-{
-#if defined(__i386__) || defined(__x86_64__)
- /* Littleendian and unaligned-capable */
- return *(const uint32_t *)p;
-#else
- return (uint32_t)p[0] + ((uint32_t)p[1] << 8) +
- ((uint32_t)p[2] << 16) + ((uint32_t)p[3] << 24);
-#endif
-}
-
-static inline void set_16(unsigned char *p, uint16_t v)
-{
-#if defined(__i386__) || defined(__x86_64__)
- /* Littleendian and unaligned-capable */
- *(uint16_t *)p = v;
-#else
- p[0] = (v & 0xff);
- p[1] = ((v >> 8) & 0xff);
-#endif
-}
-
-static inline void set_32(unsigned char *p, uint32_t v)
-{
-#if defined(__i386__) || defined(__x86_64__)
- /* Littleendian and unaligned-capable */
- *(uint32_t *)p = v;
-#else
- p[0] = (v & 0xff);
- p[1] = ((v >> 8) & 0xff);
- p[2] = ((v >> 16) & 0xff);
- p[3] = ((v >> 24) & 0xff);
-#endif
-}
-
#ifndef EXT2_SUPER_OFFSET
#define EXT2_SUPER_OFFSET 1024
#endif
-#define SECTOR_SHIFT 9 /* 512-byte sectors */
-#define SECTOR_SIZE (1 << SECTOR_SHIFT)
-
const char *program;
/*
@@ -490,6 +450,7 @@ patch_file_and_bootblock(int fd, int dirfd, int devfd)
dprintf("directory inode = %lu\n", (unsigned long) dirst.st_ino);
nsect = (boot_image_len+SECTOR_SIZE-1) >> SECTOR_SHIFT;
+ nsect += 2; /* Two sectors for the ADV */
sectp = alloca(sizeof(uint32_t)*nsect);
if ( sectmap(fd, sectp, nsect) ) {
perror("bmap");
@@ -505,9 +466,10 @@ patch_file_and_bootblock(int fd, int dirfd, int devfd)
patcharea = p+8;
/* Set up the totals */
- dw = boot_image_len >> 2; /* COMPLETE dwords! */
+ dw = boot_image_len >> 2; /* COMPLETE dwords, excluding ADV */
set_16(patcharea, dw);
- set_16(patcharea+2, nsect); /* Does not include the first sector! */
+ set_16(patcharea+2, nsect); /* Not including the first sector, but
+ including the ADV */
set_32(patcharea+8, dirst.st_ino); /* "Current" directory */
/* Set the sector pointers */
@@ -530,6 +492,163 @@ patch_file_and_bootblock(int fd, int dirfd, int devfd)
}
/*
+ * Read the ADV from an existing instance, or initialize if invalid.
+ * Returns -1 on fatal errors, 0 if ADV is okay, and 1 if no valid
+ * ADV was found.
+ */
+int
+read_adv(const char *path)
+{
+ char *file;
+ int fd = -1;
+ struct stat st;
+ int err = 0;
+
+ asprintf(&file, "%s%sextlinux.sys",
+ path,
+ path[0] && path[strlen(path)-1] == '/' ? "" : "/");
+
+ if ( !file ) {
+ perror(program);
+ return -1;
+ }
+
+ fd = open(file, O_RDONLY);
+ if ( fd < 0 ) {
+ if ( errno != ENOENT ) {
+ err = -1;
+ } else {
+ syslinux_reset_adv(syslinux_adv);
+ }
+ } else if (fstat(fd, &st)) {
+ err = -1;
+ } else if (st.st_size < 2*ADV_SIZE) {
+ /* Too small to be useful */
+ syslinux_reset_adv(syslinux_adv);
+ err = 0; /* Nothing to read... */
+ } else if (xpread(fd, syslinux_adv, 2*ADV_SIZE,
+ st.st_size-2*ADV_SIZE) != 2*ADV_SIZE) {
+ err = -1;
+ } else {
+ /* We got it... maybe? */
+ err = syslinux_validate_adv(syslinux_adv) ? 1 : 0;
+ }
+
+ if (err < 0)
+ perror(file);
+
+ if (fd >= 0)
+ close(fd);
+ if (file)
+ free(file);
+
+ return err;
+}
+
+/*
+ * Update the ADV in an existing installation.
+ */
+int
+write_adv(const char *path)
+{
+ unsigned char advtmp[2*ADV_SIZE];
+ char *file;
+ int fd = -1;
+ struct stat st, xst;
+ int err = 0;
+ int flags, nflags;
+
+ asprintf(&file, "%s%sextlinux.sys",
+ path,
+ path[0] && path[strlen(path)-1] == '/' ? "" : "/");
+
+ if ( !file ) {
+ perror(program);
+ return -1;
+ }
+
+ fd = open(file, O_RDONLY);
+ if ( fd < 0 ) {
+ err = -1;
+ } else if (fstat(fd, &st)) {
+ err = -1;
+ } else if (st.st_size < 2*ADV_SIZE) {
+ /* Too small to be useful */
+ err = -2;
+ } else if (xpread(fd, advtmp, 2*ADV_SIZE,
+ st.st_size-2*ADV_SIZE) != 2*ADV_SIZE) {
+ err = -1;
+ } else {
+ /* We got it... maybe? */
+ err = syslinux_validate_adv(advtmp) ? -2 : 0;
+ if (!err) {
+ /* Got a good one, write our own ADV here */
+ if (!ioctl(fd, EXT2_IOC_GETFLAGS, &flags)) {
+ nflags = flags & ~EXT2_IMMUTABLE_FL;
+ if (nflags != flags)
+ ioctl(fd, EXT2_IOC_SETFLAGS, &nflags);
+ }
+ if (!(st.st_mode & S_IWUSR))
+ fchmod(fd, st.st_mode | S_IWUSR);
+
+ /* Need to re-open read-write */
+ close(fd);
+ fd = open(file, O_RDWR|O_SYNC);
+ if (fd < 0) {
+ err = -1;
+ } else if (fstat(fd, &xst) || xst.st_ino != st.st_ino ||
+ xst.st_dev != st.st_dev || xst.st_size != st.st_size) {
+ fprintf(stderr, "%s: race condition on write\n", file);
+ err = -2;
+ }
+ /* Write our own version ... */
+ if (xpwrite(fd, syslinux_adv, 2*ADV_SIZE,
+ st.st_size-2*ADV_SIZE) != 2*ADV_SIZE) {
+ err = -1;
+ }
+
+ sync();
+
+ if (!(st.st_mode & S_IWUSR))
+ fchmod(fd, st.st_mode);
+
+ if (nflags != flags)
+ ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+ }
+ }
+
+ if (err == -2)
+ fprintf(stderr, "%s: cannot write auxilliary data (need --update)?\n",
+ file);
+ else if (err == -1)
+ perror(file);
+
+ if (fd >= 0)
+ close(fd);
+ if (file)
+ free(file);
+
+ return err;
+}
+
+/*
+ * Make any user-specified ADV modifications
+ */
+int modify_adv(void)
+{
+ int rv = 0;
+
+ if (opt.set_once) {
+ if (syslinux_setadv(ADV_BOOTONCE, strlen(opt.set_once), opt.set_once)) {
+ fprintf(stderr, "%s: not enough space for boot-once command\n", program);
+ rv = -1;
+ }
+ }
+
+ return rv;
+}
+
+/*
* Install the boot block on the specified device.
* Must be run AFTER install_file()!
*/
@@ -595,14 +714,15 @@ install_file(const char *path, int devfd, struct stat *rst)
}
close(fd);
- fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR|S_IRGRP|S_IROTH);
+ fd = open(file, O_WRONLY|O_TRUNC|O_CREAT|O_SYNC, S_IRUSR|S_IRGRP|S_IROTH);
if ( fd < 0 ) {
perror(file);
goto bail;
}
/* Write it the first time */
- if ( xpwrite(fd, boot_image, boot_image_len, 0) != boot_image_len ) {
+ if ( xpwrite(fd, boot_image, boot_image_len, 0) != boot_image_len ||
+ xpwrite(fd, syslinux_adv, 2*ADV_SIZE, boot_image_len) != 2*ADV_SIZE ) {
fprintf(stderr, "%s: write failure on %s\n", program, file);
goto bail;
}
@@ -610,8 +730,9 @@ install_file(const char *path, int devfd, struct stat *rst)
/* Map the file, and patch the initial sector accordingly */
patch_file_and_bootblock(fd, dirfd, devfd);
- /* Write it again - this relies on the file being overwritten in place! */
- if ( xpwrite(fd, boot_image, boot_image_len, 0) != boot_image_len ) {
+ /* Write the first sector again - this relies on the file being
+ overwritten in place! */
+ if ( xpwrite(fd, boot_image, SECTOR_SIZE, 0) != SECTOR_SIZE ) {
fprintf(stderr, "%s: write failure on %s\n", program, file);
goto bail;
}
@@ -665,6 +786,17 @@ static void device_cleanup(void)
}
#endif
+/* Verify that a device fd and a pathname agree.
+ Return 0 on valid, -1 on error. */
+static int validate_device(const char *path, int devfd)
+{
+ struct stat pst, dst;
+
+ if (stat(path, &pst) || fstat(devfd, &dst))
+ return -1;
+
+ return (pst.st_dev == dst.st_rdev) ? 0 : -1;
+}
int
install_loader(const char *path, int update_only)
@@ -738,12 +870,30 @@ install_loader(const char *path, int update_only)
return 1;
}
+ /* Verify that the device we opened is the device intended */
+ if (validate_device(path, devfd)) {
+ fprintf(stderr, "%s: path %s doesn't match device %s\n",
+ program, path, devname);
+ return 1;
+ }
+
if ( update_only && !already_installed(devfd) ) {
fprintf(stderr, "%s: no previous extlinux boot sector found\n", program);
return 1;
}
- install_file(path, devfd, &fst);
+ /* Read a pre-existing ADV, if already installed */
+ if (opt.reset_adv)
+ syslinux_reset_adv(syslinux_adv);
+ else if (read_adv(path) < 0)
+ return 1;
+
+ if (modify_adv() < 0)
+ return 1;
+
+ /* Install extlinux.sys */
+ if (install_file(path, devfd, &fst))
+ return 1;
if ( fst.st_dev != st.st_dev ) {
fprintf(stderr, "%s: file system changed under us - aborting!\n",
@@ -759,6 +909,26 @@ install_loader(const char *path, int update_only)
return rv;
}
+/*
+ * Modify the ADV of an existing installation
+ */
+int
+modify_existing_adv(const char *path)
+{
+ if (opt.reset_adv)
+ syslinux_reset_adv(syslinux_adv);
+ else if (read_adv(path) < 0)
+ return 1;
+
+ if (modify_adv() < 0)
+ return 1;
+
+ if (write_adv(path) < 0)
+ return 1;
+
+ return 0;
+}
+
int
main(int argc, char *argv[])
{
@@ -804,6 +974,15 @@ main(int argc, char *argv[])
case 'h':
usage(0);
break;
+ case 'o':
+ opt.set_once = optarg;
+ break;
+ case 'O':
+ opt.set_once = "";
+ break;
+ case OPT_RESET_ADV:
+ opt.reset_adv = 1;
+ break;
case 'v':
fputs("extlinux " VERSION "\n", stderr);
exit(0);
@@ -818,9 +997,11 @@ main(int argc, char *argv[])
usage(EX_USAGE);
if ( update_only == -1 ) {
- fprintf(stderr, "%s: warning: a future version will require "
- "--install or --update\n", program);
- update_only = 0;
+ if (opt.reset_adv || opt.set_once) {
+ return modify_existing_adv(directory);
+ } else {
+ usage(EX_USAGE);
+ }
}
return install_loader(directory, update_only);
diff --git a/layout.inc b/layout.inc
index 33bd4455..200ef9e3 100644
--- a/layout.inc
+++ b/layout.inc
@@ -56,7 +56,12 @@ STACK_START equ TEXT_START-STACK_SIZE
; NASM BUG: .data always follows .text; can't override
section .data align=16 ; follows=.text
- section .adv progbits align=512 follows=.config
+ ; This empty section works around a NASM bug with regards
+ ; to follows= and nobits sections following a section which
+ ; has VMA != LMA.
+ section .advpad progbits align=512 follows=.config
+
+ section .adv nobits align=512 follows=.advpad
; .uibss contains bss data which is guaranteed to be
; safe to clobber during the loading of the image. This
diff --git a/syslinux.h b/libinstaller/syslinux.h
index 60b36ce5..dd04aadf 100644
--- a/syslinux.h
+++ b/libinstaller/syslinux.h
@@ -14,6 +14,7 @@
#define SYSLINUX_H
#include <inttypes.h>
+#include "advconst.h"
/* The standard boot sector and ldlinux image */
extern unsigned char syslinux_bootsect[];
@@ -38,4 +39,13 @@ const char *syslinux_check_bootsect(const void *bs);
int syslinux_patch(const uint32_t *sectors, int nsectors,
int stupid, int raid_mode);
+/* ADV information */
+#define ADV_SIZE 512 /* Total size */
+#define ADV_LEN (ADV_SIZE-3*4) /* Usable data size */
+extern unsigned char syslinux_adv[2*ADV_SIZE];
+
+int syslinux_setadv(int tag, size_t size, const void *data);
+void syslinux_reset_adv(unsigned char *advbuf);
+int syslinux_validate_adv(unsigned char *advbuf);
+
#endif
diff --git a/syslxmod.c b/libinstaller/syslxmod.c
index 425756f3..425756f3 100644
--- a/syslxmod.c
+++ b/libinstaller/syslxmod.c
diff --git a/mtools/Makefile b/mtools/Makefile
index 16d63a69..4b52cb67 100644
--- a/mtools/Makefile
+++ b/mtools/Makefile
@@ -8,7 +8,7 @@ LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,)
CC = gcc
OPTFLAGS = -g -Os
-INCLUDES = -I. -I.. -I../libfat
+INCLUDES = -I. -I.. -I../libfat -I../libinstaller
CFLAGS = -W -Wall -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES)
LDFLAGS = $(LDHASH) -s
@@ -17,7 +17,7 @@ OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
.SUFFIXES: .c .o .i .s .S
-VPATH = .:..:../libfat
+VPATH = .:..:../libfat:../libinstaller
all: installer
diff --git a/unix/Makefile b/unix/Makefile
index b0465299..75f7cba2 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -8,7 +8,7 @@ LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,)
CC = gcc
OPTFLAGS = -g -Os
-INCLUDES = -I. -I..
+INCLUDES = -I. -I.. -I../libinstaller
CFLAGS = -W -Wall -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES)
LDFLAGS = $(LDHASH) -s
@@ -17,7 +17,7 @@ OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
.SUFFIXES: .c .o .i .s .S
-VPATH = .:..:../libfat
+VPATH = .:..:../libinstaller
all: installer
diff --git a/win32/Makefile b/win32/Makefile
index 6130e29a..9bd483a5 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -36,11 +36,12 @@ WINAR = i386-mingw32-ar
WINRANLIB = i386-mingw32-ranlib
endif
-WINCFLAGS = -W -Wall -Wno-sign-compare -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
+WINCFLAGS = -W -Wall -Wno-sign-compare -Os -fomit-frame-pointer \
+ -D_FILE_OFFSET_BITS=64
WINPIC =
WINLDFLAGS = -Os -s
endif
-WINCFLAGS += -I. -I.. -I../libfat
+WINCFLAGS += -I. -I.. -I../libfat -I../libinstaller
WINCC_IS_GOOD := $(shell $(WINCC) $(WINCFLAGS) $(WINLDFLAGS) -o hello.exe hello.c >/dev/null 2>&1 ; echo $$?)
@@ -50,7 +51,7 @@ SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c \
../mbr_bin.c $(wildcard ../libfat/*.c)
OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
-VPATH = .:..:../libfat
+VPATH = .:..:../libfat:../libinstaller
TARGETS = syslinux.exe