diff options
author | Matt Fleming <matt.fleming@intel.com> | 2012-09-14 15:22:29 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2012-09-19 10:46:41 +0100 |
commit | bda54cb680676bffa731394096956f5d10fbcfaf (patch) | |
tree | eccf1b93b239c19ace4ed72a0ec79c382c4cf8ba /dos | |
parent | 040f273035ca84fc963d0d0c0b39794f7a5fc7d4 (diff) | |
download | syslinux-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.ld | 6 | ||||
-rw-r--r-- | dos/ldlinux.S | 14 | ||||
-rw-r--r-- | dos/syslinux.c | 100 |
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"); } /* |