summaryrefslogtreecommitdiff
path: root/dos
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-09-14 15:22:29 +0100
committerMatt Fleming <matt.fleming@intel.com>2012-09-19 10:46:41 +0100
commitbda54cb680676bffa731394096956f5d10fbcfaf (patch)
treeeccf1b93b239c19ace4ed72a0ec79c382c4cf8ba /dos
parent040f273035ca84fc963d0d0c0b39794f7a5fc7d4 (diff)
downloadsyslinux-bda54cb680676bffa731394096956f5d10fbcfaf.tar.gz
installers: Install ldlinux.c32 automaticallysyslinux-5.00-pre8
Because ldlinux.c32 is required for Syslinux to function correctly, we should be installing it automatically much like ldlinux.sys. Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'dos')
-rw-r--r--dos/dosexe.ld6
-rw-r--r--dos/ldlinux.S14
-rw-r--r--dos/syslinux.c100
3 files changed, 73 insertions, 47 deletions
diff --git a/dos/dosexe.ld b/dos/dosexe.ld
index 76bfc758..bd6ad8ba 100644
--- a/dos/dosexe.ld
+++ b/dos/dosexe.ld
@@ -26,7 +26,7 @@ SECTIONS
__header_size = .;
__payload_lma = .;
- . = 0x100000000 - syslinux_ldlinux_size;
+ . = 0x100000000 - syslinux_size;
.payload : AT (__payload_lma) {
__payload_start = .;
*(.payload)
@@ -35,13 +35,13 @@ SECTIONS
__payload_len = ABSOLUTE(__payload_end) - ABSOLUTE(__payload_start);
__payload_dwords = __payload_len >> 2;
- __text_lma = __payload_lma + syslinux_ldlinux_size;
+ __text_lma = __payload_lma + syslinux_size;
__payload_sseg = (__payload_lma - __text_lma) >> 4;
_exe_text_seg = (__text_lma - __header_size) >> 4;
/*
* __assert1 = ASSERT((__payload_len == syslinux_ldlinux_size),
- * "syslinux_ldlinux_size must equal the size of .payload");
+ * "syslinux_size must equal the size of .payload");
*/
. = 0;
.text : AT (__text_lma) {
diff --git a/dos/ldlinux.S b/dos/ldlinux.S
index 17a65830..9145bd7b 100644
--- a/dos/ldlinux.S
+++ b/dos/ldlinux.S
@@ -1,5 +1,5 @@
/*
- * Wrap ldlinux.sys; this needs special handling for DOS.
+ * Wrap ldlinux.sys and ldlinux.c32; this needs special handling for DOS.
*/
.section ".payload","aw"
@@ -10,6 +10,14 @@ syslinux_ldlinux:
.space ((syslinux_ldlinux - .) & 511)
syslinux_ldlinux_size = . - syslinux_ldlinux
.size syslinux_ldlinux, .-syslinux_ldlinux
+ .globl syslinux_ldlinuxc32, syslinux_ldlinuxc32_size
+syslinux_ldlinuxc32:
+ .incbin "../com32/elflink/ldlinux/ldlinux.c32"
+ .space ((syslinux_ldlinuxc32 - .) & 511)
+syslinux_ldlinuxc32_size = . - syslinux_ldlinuxc32
+ .size syslinux_ldlinuxc32, .-syslinux_ldlinuxc32
+ .globl syslinux_size
+syslinux_size = . - syslinux_ldlinux
.section ".rodata","a"
.balign 4
@@ -17,3 +25,7 @@ syslinux_ldlinux_size = . - syslinux_ldlinux
syslinux_ldlinux_len:
.long syslinux_ldlinux_size
.size syslinux_ldlinux_len, .-syslinux_ldlinux_len
+ .globl syslinux_ldlinuxc32_len
+syslinux_ldlinuxc32_len:
+ .long syslinux_ldlinuxc32_size
+ .size syslinux_ldlinuxc32_len, .-syslinux_ldlinuxc32_len
diff --git a/dos/syslinux.c b/dos/syslinux.c
index fa4bf387..eb8bace6 100644
--- a/dos/syslinux.c
+++ b/dos/syslinux.c
@@ -121,15 +121,15 @@ int rename(const char *oldname, const char *newname)
return 0;
}
-ssize_t write_ldlinux(int fd)
+ssize_t write_file_seg(int fd, unsigned char *buf, const unsigned int len)
{
- uint16_t ldlinux_seg = ((size_t)syslinux_ldlinux >> 4) + ds();
+ uint16_t seg = ((size_t)buf >> 4) + ds();
uint32_t offset = 0;
uint16_t rv;
uint8_t err;
- while (offset < syslinux_ldlinux_len) {
- uint32_t chunk = syslinux_ldlinux_len - offset;
+ while (offset < len) {
+ uint32_t chunk = len - offset;
if (chunk > 32768)
chunk = 32768;
asm volatile ("pushw %%ds ; "
@@ -137,7 +137,7 @@ ssize_t write_ldlinux(int fd)
"int $0x21 ; "
"popw %%ds ; " "setc %0":"=bcdm" (err), "=a"(rv)
:"a"(0x4000), "b"(fd), "c"(chunk), "d" (offset & 15),
- "SD" ((uint16_t)(ldlinux_seg + (offset >> 4))));
+ "SD" ((uint16_t)(seg + (offset >> 4))));
if (err || rv == 0)
die("file write error");
offset += rv;
@@ -583,11 +583,53 @@ static void adjust_mbr(int device, int writembr, int set_active)
write_mbr(device, sectbuf);
}
+static void move_file(int dev_fd, char *pathname, char *filename)
+{
+ char new_name[160];
+ char *cp = new_name + 3;
+ const char *sd;
+ int slash = 1;
+
+ new_name[0] = dev_fd | 0x40;
+ new_name[1] = ':';
+ new_name[2] = '\\';
+
+ for (sd = opt.directory; *sd; sd++) {
+ char c = *sd;
+
+ if (c == '/' || c == '\\') {
+ if (slash)
+ continue;
+ c = '\\';
+ slash = 1;
+ } else {
+ slash = 0;
+ }
+
+ *cp++ = c;
+ }
+
+ /* Skip if subdirectory == root */
+ if (cp > new_name + 3) {
+ if (!slash)
+ *cp++ = '\\';
+
+ memcpy(cp, filename, 12);
+
+ set_attributes(pathname, 0);
+ if (rename(pathname, new_name))
+ set_attributes(pathname, 0x07);
+ else
+ set_attributes(new_name, 0x07);
+ }
+}
+
int main(int argc, char *argv[])
{
static unsigned char sectbuf[SECTOR_SIZE];
int dev_fd, fd;
static char ldlinux_name[] = "@:\\ldlinux.sys";
+ static char ldlinuxc32_name[] = "@:\\ldlinux.c32";
struct libfat_filesystem *fs;
libfat_sector_t s, *secp;
libfat_sector_t *sectors;
@@ -647,14 +689,21 @@ int main(int argc, char *argv[])
}
ldlinux_name[0] = dev_fd | 0x40;
+ ldlinuxc32_name[0] = dev_fd | 0x40;
set_attributes(ldlinux_name, 0);
fd = creat(ldlinux_name, 0); /* SYSTEM HIDDEN READONLY */
- write_ldlinux(fd);
+ write_file_seg(fd, syslinux_ldlinux, syslinux_ldlinux_len);
write_file(fd, syslinux_adv, 2 * ADV_SIZE);
close(fd);
set_attributes(ldlinux_name, 0x07); /* SYSTEM HIDDEN READONLY */
+ set_attributes(ldlinuxc32_name, 0);
+ fd = creat(ldlinuxc32_name, 0); /* SYSTEM HIDDEN READONLY */
+ write_file_seg(fd, syslinux_ldlinuxc32, syslinux_ldlinuxc32_len);
+ close(fd);
+ set_attributes(ldlinuxc32_name, 0x07); /* SYSTEM HIDDEN READONLY */
+
/*
* Now, use libfat to create a block map. This probably
* should be changed to use ioctl(...,FIBMAP,...) since
@@ -681,43 +730,8 @@ int main(int argc, char *argv[])
* If requested, move ldlinux.sys
*/
if (opt.directory) {
- char new_ldlinux_name[160];
- char *cp = new_ldlinux_name + 3;
- const char *sd;
- int slash = 1;
-
- new_ldlinux_name[0] = dev_fd | 0x40;
- new_ldlinux_name[1] = ':';
- new_ldlinux_name[2] = '\\';
-
- for (sd = opt.directory; *sd; sd++) {
- char c = *sd;
-
- if (c == '/' || c == '\\') {
- if (slash)
- continue;
- c = '\\';
- slash = 1;
- } else {
- slash = 0;
- }
-
- *cp++ = c;
- }
-
- /* Skip if subdirectory == root */
- if (cp > new_ldlinux_name + 3) {
- if (!slash)
- *cp++ = '\\';
-
- memcpy(cp, "ldlinux.sys", 12);
-
- set_attributes(ldlinux_name, 0);
- if (rename(ldlinux_name, new_ldlinux_name))
- set_attributes(ldlinux_name, 0x07);
- else
- set_attributes(new_ldlinux_name, 0x07);
- }
+ move_file(dev_fd, ldlinux_name, "ldlinux.sys");
+ move_file(dev_fd, ldlinuxc32_name, "ldlinux.c32");
}
/*