aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS14
-rw-r--r--com32/gfxboot/gfxboot.c63
-rw-r--r--com32/lib/strspn.c4
-rw-r--r--com32/modules/chain.c49
-rw-r--r--doc/extlinux.txt2
-rw-r--r--doc/syslinux.txt17
-rw-r--r--utils/isohybrid.c12
7 files changed, 105 insertions, 56 deletions
diff --git a/NEWS b/NEWS
index 8ecb6cd9..48cbbea6 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,20 @@ Starting with 1.47, changes marked with SYSLINUX, PXELINUX, ISOLINUX
or EXTLINUX apply to that specific program only; other changes apply
to all derivatives.
+Changes in 4.03:
+ * Don't hang if no configuration file is found.
+ * Better support for booting from MBRs which don't pass
+ handover information.
+ * EXTLINUX: Try to be smarter about finding the partition
+ offset.
+ * chain.c32: support chainloading Dell Real Mode Kernel (Gene
+ Cumm).
+ * chain.c32: fix booting in CHS mode.
+ * rosh.c32 updated (Gene Cumm).
+ * Fix the -s option to the syslinux/extlinux installer (Arwin
+ Vosselman).
+ * isohybrid: fix padding of large images (PJ Pandit).
+
Changes in 4.02:
* SYSLINUX: correctly handle the case where the -d option is
specified with a non-absolute path, i.e. "syslinux -d
diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c
index dd4d6410..3b09e74a 100644
--- a/com32/gfxboot/gfxboot.c
+++ b/com32/gfxboot/gfxboot.c
@@ -134,6 +134,7 @@ gfx_menu_t gfx_menu;
menu_t *menu;
menu_t *menu_default;
+static menu_t *menu_ptr, **menu_next;
struct {
uint32_t jmp_table[12];
@@ -161,7 +162,7 @@ char *get_config_file_name(void);
char *skip_spaces(char *s);
char *skip_nonspaces(char *s);
void chop_line(char *s);
-int read_config_file(void);
+int read_config_file(const char *filename);
unsigned magic_ok(unsigned char *buf, unsigned *code_size);
unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len, unsigned *code_size);
int gfx_init(char *file);
@@ -219,7 +220,7 @@ int main(int argc, char **argv)
return 0;
}
- if(read_config_file()) {
+ if(read_config_file("~")) {
printf("Error reading config file\n");
if(argc > 2) show_message(argv[2]);
@@ -313,16 +314,24 @@ void chop_line(char *s)
// return:
// 0: ok, 1: error
//
-int read_config_file(void)
+int read_config_file(const char *filename)
{
FILE *f;
char *s, *t, buf[MAX_CONFIG_LINE_LEN];
- unsigned u, menu_idx = 0, label_size = 0, append_size = 0;
- menu_t *menu_ptr = NULL, **menu_next = &menu;
+ unsigned u, top_level = 0;
- menu_default = calloc(1, sizeof *menu_default);
+ if(!strcmp(filename, "~")) {
+ top_level = 1;
+ filename = syslinux_config_file();
+ gfx_menu.entries = 0;
+ gfx_menu.label_size = 0;
+ gfx_menu.arg_size = 0;
+ menu_ptr = NULL;
+ menu_next = &menu;
+ menu_default = calloc(1, sizeof *menu_default);
+ }
- if(!(f = fopen(syslinux_config_file(), "r"))) return 1;
+ if(!(f = fopen(filename, "r"))) return 1;
while((s = fgets(buf, sizeof buf, f))) {
chop_line(s);
@@ -340,17 +349,17 @@ int read_config_file(void)
if(!strcasecmp(s, "default")) {
menu_default->label = strdup(t);
u = strlen(t);
- if(u > label_size) label_size = u;
+ if(u > gfx_menu.label_size) gfx_menu.label_size = u;
continue;
}
if(!strcasecmp(s, "label")) {
menu_ptr = *menu_next = calloc(1, sizeof **menu_next);
menu_next = &menu_ptr->next;
- menu_idx++;
+ gfx_menu.entries++;
menu_ptr->label = menu_ptr->menu_label = strdup(t);
u = strlen(t);
- if(u > label_size) label_size = u;
+ if(u > gfx_menu.label_size) gfx_menu.label_size = u;
continue;
}
@@ -377,7 +386,7 @@ int read_config_file(void)
if(!strcasecmp(s, "append")) {
(menu_ptr ?: menu_default)->append = strdup(t);
u = strlen(t);
- if(u > append_size) append_size = u;
+ if(u > gfx_menu.arg_size) gfx_menu.arg_size = u;
continue;
}
@@ -395,17 +404,32 @@ int read_config_file(void)
if(!strcasecmp(s, "label")) {
menu_ptr->menu_label = strdup(t);
u = strlen(t);
- if(u > label_size) label_size = u;
+ if(u > gfx_menu.label_size) gfx_menu.label_size = u;
continue;
}
+
+ if(!strcasecmp(s, "include")) {
+ goto do_include;
+ }
+ }
+
+ if (!strcasecmp(s, "include")) {
+do_include:
+ s = t;
+ t = skip_nonspaces(s);
+ if (*t) *t = 0;
+ read_config_file(s);
}
}
fclose(f);
+ if (!top_level)
+ return 0;
+
// final '\0'
- label_size++;
- append_size++;
+ gfx_menu.label_size++;
+ gfx_menu.arg_size++;
// ensure we have a default entry
if(!menu_default->label) menu_default->label = menu->label;
@@ -419,19 +443,16 @@ int read_config_file(void)
}
}
- gfx_menu.entries = menu_idx;
- gfx_menu.label_size = label_size;
- gfx_menu.arg_size = append_size;
gfx_menu.default_entry = menu_default->menu_label;
- gfx_menu.label_list = calloc(menu_idx, label_size);
- gfx_menu.arg_list = calloc(menu_idx, append_size);
+ gfx_menu.label_list = calloc(gfx_menu.entries, gfx_menu.label_size);
+ gfx_menu.arg_list = calloc(gfx_menu.entries, gfx_menu.arg_size);
for(u = 0, menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next, u++) {
if(!menu_ptr->append) menu_ptr->append = menu_default->append;
if(!menu_ptr->ipappend) menu_ptr->ipappend = menu_default->ipappend;
- if(menu_ptr->menu_label) strcpy(gfx_menu.label_list + u * label_size, menu_ptr->menu_label);
- if(menu_ptr->append) strcpy(gfx_menu.arg_list + u * append_size, menu_ptr->append);
+ if(menu_ptr->menu_label) strcpy(gfx_menu.label_list + u * gfx_menu.label_size, menu_ptr->menu_label);
+ if(menu_ptr->append) strcpy(gfx_menu.arg_list + u * gfx_menu.arg_size, menu_ptr->append);
}
return 0;
diff --git a/com32/lib/strspn.c b/com32/lib/strspn.c
index abbbf175..7a248205 100644
--- a/com32/lib/strspn.c
+++ b/com32/lib/strspn.c
@@ -11,12 +11,12 @@
#define LONG_BIT (CHAR_BIT*sizeof(long))
#endif
-static inline void set_bit(unsigned long *bitmap, unsigned int bit)
+static void set_bit(unsigned long *bitmap, unsigned int bit)
{
bitmap[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
}
-static inline int test_bit(unsigned long *bitmap, unsigned int bit)
+static int test_bit(unsigned long *bitmap, unsigned int bit)
{
return (int)(bitmap[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1;
}
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index 6a5b1151..89489d18 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -76,6 +76,10 @@
* equivalent to seg=0x70 file=<loader> sethidden,
* used with DOS' io.sys.
*
+ * drmk=<loader>
+ * Similar to msdos=<loader> but prepares the special options
+ * for the Dell Real Mode Kernel.
+ *
* grub=<loader>
* same as seg=0x800 file=<loader> & jumping to seg 0x820,
* used with GRUB Legacy stage2 files.
@@ -266,23 +270,21 @@ static void *read_sectors(uint64_t lba, uint8_t count)
if (lba)
return NULL; /* Can only read MBR */
- s = 1;
- h = 0;
- c = 0;
+ s = h = c = 0;
} else {
- s = (lba % disk_info.sect) + 1;
+ s = lba % disk_info.sect;
t = lba / disk_info.sect; /* Track = head*cyl */
h = t % disk_info.head;
c = t / disk_info.head;
}
- if (s > 63 || h > 256 || c > 1023)
+ if (s >= 63 || h >= 256 || c >= 1024)
return NULL;
inreg.eax.b[0] = count;
inreg.eax.b[1] = 0x02; /* Read */
- inreg.ecx.b[1] = c & 0xff;
- inreg.ecx.b[0] = s + (c >> 6);
+ inreg.ecx.b[1] = c;
+ inreg.ecx.b[0] = ((c & 0x300) >> 2) | (s+1);
inreg.edx.b[1] = h;
inreg.edx.b[0] = disk_info.disk;
inreg.ebx.w[0] = OFFS(buf);
@@ -327,22 +329,20 @@ static int write_sector(unsigned int lba, const void *data)
if (lba)
return -1; /* Can only write MBR */
- s = 1;
- h = 0;
- c = 0;
+ s = h = c = 0;
} else {
- s = (lba % disk_info.sect) + 1;
+ s = lba % disk_info.sect;
t = lba / disk_info.sect; /* Track = head*cyl */
h = t % disk_info.head;
c = t / disk_info.head;
}
- if (s > 63 || h > 256 || c > 1023)
+ if (s >= 63 || h >= 256 || c >= 1024)
return -1;
inreg.eax.w[0] = 0x0301; /* Write one sector */
- inreg.ecx.b[1] = c & 0xff;
- inreg.ecx.b[0] = s + (c >> 6);
+ inreg.ecx.b[1] = c;
+ inreg.ecx.b[0] = ((c & 0x300) >> 2) | (s+1);
inreg.edx.b[1] = h;
inreg.edx.b[0] = disk_info.disk;
inreg.ebx.w[0] = OFFS(buf);
@@ -1711,16 +1711,31 @@ int main(int argc, char *argv[])
* We only really need 4 new, usable bytes at the end.
*/
int tsize = (data[ndata].size + 19) & 0xfffffff0;
+ const union syslinux_derivative_info *sdi;
+
+ sdi = syslinux_derivative_info();
+ /* We should lookup the Syslinux partition offset and use it */
+ fs_lba = *sdi->disk.partoffset;
+ /*
+ * fs_lba should be verified against the disk as some DRMK
+ * variants will check and fail if it does not match
+ */
+ dprintf(" fs_lba offset is %d\n", fs_lba);
+ /* DRMK only uses a DWORD */
+ if (fs_lba > 0xffffffff) {
+ error("LBA very large; Only using lower 32 bits; DRMK will probably fail\n");
+ }
regs.ss = regs.fs = regs.gs = 0; /* Used before initialized */
if (!realloc(data[ndata].data, tsize)) {
error("Failed to realloc for DRMK\n");
- goto bail;
+ goto bail; /* We'll never make it */
}
data[ndata].size = tsize;
- /* ds:[bp+28] must be 0x0000003f */
+ /* ds:bp is assumed by DRMK to be the boot sector */
+ /* offset 28 is the FAT HiddenSectors value */
regs.ds = (tsize >> 4) + (opt.seg - 2);
/* "Patch" into tail of the new space */
- *(int *)(data[ndata].data + tsize - 4) = 0x0000003f;
+ *(int *)(data[ndata].data + tsize - 4) = (int)(fs_lba & 0xffffffff);
}
ndata++;
diff --git a/doc/extlinux.txt b/doc/extlinux.txt
index 6974a517..9b267018 100644
--- a/doc/extlinux.txt
+++ b/doc/extlinux.txt
@@ -24,6 +24,8 @@ slight modifications.
2. The configuration file is called "extlinux.conf", and is expected
to be found in the same directory as extlinux is installed in.
+ Since 4.00 "syslinux.cfg" is also tried if "extlinux.conf" is not
+ found.
3. Pathnames can be absolute or relative; if absolute (with a leading
diff --git a/doc/syslinux.txt b/doc/syslinux.txt
index 51d1332c..5b27a6eb 100644
--- a/doc/syslinux.txt
+++ b/doc/syslinux.txt
@@ -106,24 +106,25 @@ which requires root privilege.
++++ CONFIGURATION FILE ++++
+All options here apply to PXELINUX, ISOLINUX and EXTLINUX as well as
+SYSLINUX unless otherwise noted. See the respective .txt files.
+
All the configurable defaults in SYSLINUX can be changed by putting a
file called "syslinux.cfg" in the root directory of the boot disk.
-This is a text file in either UNIX or DOS format, containing one or
-more of the following items (case is insensitive for keywords; upper
-case is used here to indicate that a word should be typed verbatim):
-
Starting with version 3.35, the configuration file can also be in
either the /boot/syslinux or /syslinux directories (searched in that
order.) If that is the case, then all filenames are assumed to be
relative to that same directory, unless preceded with a slash or
backslash.
-All options here applies to PXELINUX, ISOLINUX and EXTLINUX as well as
-SYSLINUX unless otherwise noted. See the respective .txt files.
+The configuration file is a text file in either UNIX or DOS format,
+containing one or more of the following items, each on its own line with
+optional leading whitespace. Case is insensitive for keywords; upper
+case is used here to indicate that a word should be typed verbatim.
-# comment
- A comment line. The whitespace after the hash mark is mandatory.
+#comment
+ A comment line.
INCLUDE filename
Inserts the contents of another file at this point in the
diff --git a/utils/isohybrid.c b/utils/isohybrid.c
index 57c1015e..7ee9a7f0 100644
--- a/utils/isohybrid.c
+++ b/utils/isohybrid.c
@@ -543,15 +543,11 @@ main(int argc, char *argv[])
if (padding)
{
- if (!(buf = realloc(buf, padding)))
- err(1, "%s: could not re-size buffer", argv[0]);
+ if (fsync(fileno(fp)))
+ err(1, "%s: could not synchronise", argv[0]);
- if (fseek(fp, isostat.st_size, SEEK_SET))
- err(1, "%s: seek error - 6", argv[0]);
-
- memset(buf, 0, padding);
- if (fwrite(buf, sizeof(char), padding, fp) != (size_t)padding)
- err(1, "%s: write error - 2", argv[0]);
+ if (ftruncate(fileno(fp), isostat.st_size + padding))
+ err(1, "%s: could not add padding bytes", argv[0]);
}
free(buf);