diff options
| author | H. Peter Anvin <hpa@zytor.com> | 2009-07-16 12:11:14 -0400 |
|---|---|---|
| committer | H. Peter Anvin <hpa@zytor.com> | 2009-07-16 12:11:14 -0400 |
| commit | bf9f683dbef47a44dee4da1607d99a25976560e3 (patch) | |
| tree | fc4251832446561df49c3a75ce51917333ea06fc /extlinux | |
| parent | abe63b54e8136ac4c7d97fa138940ae6fd96e67e (diff) | |
| download | syslinux-bf9f683dbef47a44dee4da1607d99a25976560e3.tar.gz | |
extlinux: handle more than one sector of sector pointers
Fix the extlinux installer so we can handle more than one sector of
sector pointers. This code should be merged with the equivalent code
in the syslinux installer.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'extlinux')
| -rw-r--r-- | extlinux/main.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/extlinux/main.c b/extlinux/main.c index d662b56b..476d0063 100644 --- a/extlinux/main.c +++ b/extlinux/main.c @@ -342,8 +342,10 @@ int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo) * Query the device geometry and put it into the boot sector. * Map the file and put the map in the boot sector and file. * Stick the "current directory" inode number into the file. + * + * Returns the number of modified bytes in the boot file. */ -void patch_file_and_bootblock(int fd, int dirfd, int devfd) +int patch_file_and_bootblock(int fd, int dirfd, int devfd) { struct stat dirst; struct hd_geometry geo; @@ -355,6 +357,7 @@ void patch_file_and_bootblock(int fd, int dirfd, int devfd) struct patch_area *patcharea; int i, dw, nptrs; uint32_t csum; + int secptroffset; if (fstat(dirfd, &dirst)) { perror("fstat dirfd"); @@ -427,7 +430,8 @@ void patch_file_and_bootblock(int fd, int dirfd, int devfd) set_32(&patcharea->currentdir, dirst.st_ino); /* Set the sector pointers */ - wp = (uint32_t *) ((char *)boot_image + get_16(&patcharea->secptroffset)); + secptroffset = get_16(&patcharea->secptroffset); + wp = (uint32_t *) ((char *)boot_image + secptroffset); nptrs = get_16(&patcharea->secptrcnt); memset(wp, 0, nptrs * 4); @@ -442,6 +446,8 @@ void patch_file_and_bootblock(int fd, int dirfd, int devfd) csum -= get_32(wp); /* Negative checksum */ set_32(&patcharea->checksum, csum); + + return secptroffset + nptrs*4; } /* @@ -629,6 +635,7 @@ int install_file(const char *path, int devfd, struct stat *rst) char *file; int fd = -1, dirfd = -1, flags; struct stat st; + int modbytes; asprintf(&file, "%s%sextlinux.sys", path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/"); @@ -677,11 +684,11 @@ int 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); + modbytes = patch_file_and_bootblock(fd, dirfd, devfd); - /* Write the first sector again - this relies on the file being + /* Write the patch area again - this relies on the file being overwritten in place! */ - if (xpwrite(fd, boot_image, SECTOR_SIZE, 0) != SECTOR_SIZE) { + if (xpwrite(fd, boot_image, modbytes, 0) != modbytes) { fprintf(stderr, "%s: write failure on %s\n", program, file); goto bail; } |
