From a2bfd4b1fb055e63a48d80e7e55a6cff475e06d1 Mon Sep 17 00:00:00 2001 From: Robert Yang Date: Fri, 13 Feb 2015 00:59:08 -0800 Subject: syslinux: support ext2/3/4 device * Support ext2/3/4 deivce. * The open_ext2_fs() checks whether it is an ext2/3/4 device, do the ext2/3/4 installation (install_to_ext2()) if yes, otherwise go on to the fat/ntfs. * The ext2/3/4 support doesn't require root privileges since it doesn't need mount (but write permission is required). Next: * Get rid of fat filesystem from the boot image. These patches have been sent to upstream, we may adjust them (maybe put the extX support to syslinux-mtools), I will go on working with the upstream. (From OE-Core rev: d5af8539c0a1718a7254bcdcfa973e3c887dfbd6) Signed-off-by: Robert Yang Signed-off-by: Ross Burton Signed-off-by: Richard Purdie --- ...01-linux-syslinux-support-ext2-3-4-device.patch | 84 ++++ ...002-linux-syslinux-implement-open_ext2_fs.patch | 141 +++++++ ...-linux-syslinux-implement-install_to_ext2.patch | 116 ++++++ ...inux-add-ext_file_read-and-ext_file_write.patch | 91 +++++ ...inux-syslinux-implement-handle_adv_on_ext.patch | 127 ++++++ ...nux-implement-write_to_ext-and-add-syslin.patch | 215 +++++++++++ ...slinux-implement-ext_construct_sectmap_fs.patch | 84 ++++ ...r-syslinuxext-implement-syslinux_patch_bo.patch | 427 +++++++++++++++++++++ ...inux-syslinux-implement-install_bootblock.patch | 50 +++ meta/recipes-devtools/syslinux/syslinux_6.03.bb | 11 +- 10 files changed, 1345 insertions(+), 1 deletion(-) create mode 100644 meta/recipes-devtools/syslinux/syslinux/0001-linux-syslinux-support-ext2-3-4-device.patch create mode 100644 meta/recipes-devtools/syslinux/syslinux/0002-linux-syslinux-implement-open_ext2_fs.patch create mode 100644 meta/recipes-devtools/syslinux/syslinux/0003-linux-syslinux-implement-install_to_ext2.patch create mode 100644 meta/recipes-devtools/syslinux/syslinux/0004-linux-syslinux-add-ext_file_read-and-ext_file_write.patch create mode 100644 meta/recipes-devtools/syslinux/syslinux/0005-linux-syslinux-implement-handle_adv_on_ext.patch create mode 100644 meta/recipes-devtools/syslinux/syslinux/0006-linux-syslinux-implement-write_to_ext-and-add-syslin.patch create mode 100644 meta/recipes-devtools/syslinux/syslinux/0007-linux-syslinux-implement-ext_construct_sectmap_fs.patch create mode 100644 meta/recipes-devtools/syslinux/syslinux/0008-libinstaller-syslinuxext-implement-syslinux_patch_bo.patch create mode 100644 meta/recipes-devtools/syslinux/syslinux/0009-linux-syslinux-implement-install_bootblock.patch (limited to 'meta/recipes-devtools/syslinux') diff --git a/meta/recipes-devtools/syslinux/syslinux/0001-linux-syslinux-support-ext2-3-4-device.patch b/meta/recipes-devtools/syslinux/syslinux/0001-linux-syslinux-support-ext2-3-4-device.patch new file mode 100644 index 0000000000..3ab7875274 --- /dev/null +++ b/meta/recipes-devtools/syslinux/syslinux/0001-linux-syslinux-support-ext2-3-4-device.patch @@ -0,0 +1,84 @@ +From 60f3833ab2b5899771b4eab654e88f9888b99501 Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Wed, 31 Dec 2014 16:01:55 +0800 +Subject: [PATCH 1/9] linux/syslinux: support ext2/3/4 device + +* Support ext2/3/4 deivce. +* The open_ext2_fs() checks whether it is an ext2/3/4 device, + do the ext2/3/4 installation (install_to_ext2()) if yes, otherwise go + on to the fat/ntfs. +* The ext2/3/4 support doesn't require root privileges since it doesn't need + mount (but write permission is required). + +Upstream-Status: Submitted + +Signed-off-by: Robert Yang +Tested-by: Du Dolpher +--- + linux/syslinux.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/linux/syslinux.c b/linux/syslinux.c +index 912de71..36fc202 100755 +--- a/linux/syslinux.c ++++ b/linux/syslinux.c +@@ -256,6 +256,23 @@ int do_open_file(char *name) + return fd; + } + ++/* ++ * Check whether the device contains an ext2, ext3 or ext4 fs and open it if ++ * true. ++ * return value: ++ * 0: Everything is OK ++ * 1: Not an ext2, ext3 or ext4 ++ * -1: unexpected error ++ */ ++static int open_ext2_fs(const char *device, const char *subdir) ++{ ++} ++ ++/* The install func for ext2, ext3 and ext4 */ ++static int install_to_ext2(const char *device, int dev_fd, const char *subdir) ++{ ++} ++ + int main(int argc, char *argv[]) + { + static unsigned char sectbuf[SECTOR_SIZE]; +@@ -313,6 +330,24 @@ int main(int argc, char *argv[]) + die("can't combine an offset with a block device"); + } + ++ /* ++ * Check if it is an ext2, ext3 or ext4 ++ */ ++ rv = open_ext2_fs(opt.device, subdir); ++ if (rv == 0) { ++ if (install_to_ext2(opt.device, dev_fd, subdir)) { ++ fprintf(stderr, "%s: installation failed\n", opt.device); ++ exit(1); ++ } ++ return 0; ++ /* Unexpected errors */ ++ } else if (rv == -1) { ++ exit(1); ++ } ++ ++ /* Reset rv */ ++ rv = 0; ++ + xpread(dev_fd, sectbuf, SECTOR_SIZE, opt.offset); + fsync(dev_fd); + +@@ -322,6 +357,7 @@ int main(int argc, char *argv[]) + */ + if ((errmsg = syslinux_check_bootsect(sectbuf, &fs_type))) { + fprintf(stderr, "%s: %s\n", opt.device, errmsg); ++ fprintf(stderr, "%s: supported fs: fat/ntfs/ext2/ex3/ext4\n", program); + exit(1); + } + +-- +1.9.1 + diff --git a/meta/recipes-devtools/syslinux/syslinux/0002-linux-syslinux-implement-open_ext2_fs.patch b/meta/recipes-devtools/syslinux/syslinux/0002-linux-syslinux-implement-open_ext2_fs.patch new file mode 100644 index 0000000000..77cf060451 --- /dev/null +++ b/meta/recipes-devtools/syslinux/syslinux/0002-linux-syslinux-implement-open_ext2_fs.patch @@ -0,0 +1,141 @@ +From 07fb737fb60c08eaaa41989d531fc23009523546 Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Wed, 31 Dec 2014 16:09:18 +0800 +Subject: [PATCH 2/9] linux/syslinux: implement open_ext2_fs() + +The open_ext2_fs() checks whether it is an ext2/ext3/ext4 device, and +return: +0: It is an ext2, ext3 or ext4. +1: Not an ext2, ext3 or ext4. +-1: unexpected error. + +Upstream-Status: Submitted + +Signed-off-by: Robert Yang +Tested-by: Du Dolpher +--- + linux/Makefile | 2 +- + linux/syslinux.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 81 insertions(+), 1 deletion(-) + +diff --git a/linux/Makefile b/linux/Makefile +index 11667e1..ac1ac58 100644 +--- a/linux/Makefile ++++ b/linux/Makefile +@@ -51,7 +51,7 @@ spotless: clean + installer: syslinux syslinux-nomtools + + syslinux: $(OBJS) +- $(CC) $(LDFLAGS) -o $@ $^ ++ $(CC) $(LDFLAGS) -o $@ $^ -lext2fs + + syslinux-nomtools: syslinux + ln -f $< $@ +diff --git a/linux/syslinux.c b/linux/syslinux.c +index 36fc202..cc4e7da 100755 +--- a/linux/syslinux.c ++++ b/linux/syslinux.c +@@ -72,6 +72,7 @@ + #include "syslxfs.h" + #include "setadv.h" + #include "syslxopt.h" /* unified options */ ++#include + + extern const char *program; /* Name of program */ + +@@ -82,6 +83,9 @@ char *mntpath = NULL; /* Path on which to mount */ + int loop_fd = -1; /* Loop device */ + #endif + ++ext2_filsys e2fs = NULL; /* Ext2/3/4 filesystem */ ++ext2_ino_t root, cwd; /* The root and cwd of e2fs */ ++ + void __attribute__ ((noreturn)) die(const char *msg) + { + fprintf(stderr, "%s: %s\n", program, msg); +@@ -266,6 +270,82 @@ int do_open_file(char *name) + */ + static int open_ext2_fs(const char *device, const char *subdir) + { ++ int retval; ++ int open_flag = EXT2_FLAG_RW, mount_flags; ++ ext2_ino_t dirino; ++ char opt_string[40]; ++ ++ if (opt.offset) { ++ sprintf(opt_string, "offset=%llu", (unsigned long long)opt.offset); ++ retval = ext2fs_open2(device, opt_string, open_flag, 0, 0, unix_io_manager, &e2fs); ++ } else ++ retval = ext2fs_open(device, open_flag, 0, 0, unix_io_manager, &e2fs); ++ if (retval) { ++ /* It might not be an extN fs, so we need check magic firstly */ ++ if (retval == EXT2_ET_BAD_MAGIC) { ++ /* Do nothing, return silently */ ++ return 1; ++ } else { ++ fprintf(stderr, "%s: error while trying to open: %s\n", ++ program, device); ++ return -1; ++ } ++ } ++ ++ /* Stop if it is mounted */ ++ retval = ext2fs_check_if_mounted(device, &mount_flags); ++ if (retval) { ++ fprintf(stderr, "%s: ext2fs_check_if_mount() error on %s\n", ++ program, device); ++ goto fail; ++ } ++ ++ if (mount_flags & EXT2_MF_MOUNTED) { ++ fprintf(stderr, "%s: %s is mounted\n", program, device); ++ goto fail; ++ } ++ ++ e2fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE; ++ ++ /* Read the inode map */ ++ retval = ext2fs_read_inode_bitmap(e2fs); ++ if (retval) { ++ fprintf(stderr, "%s: while reading inode bitmap: %s\n", ++ program, device); ++ goto fail; ++ } ++ ++ /* Read the block map */ ++ retval = ext2fs_read_block_bitmap(e2fs); ++ if (retval) { ++ fprintf(stderr, "%s: while reading block bitmap: %s\n", ++ program, device); ++ goto fail; ++ } ++ ++ root = cwd = EXT2_ROOT_INO; ++ /* Check the subdir */ ++ if (strcmp(subdir, "/")) { ++ retval = ext2fs_namei(e2fs, root, cwd, subdir, &dirino); ++ if (retval) { ++ fprintf(stderr, "%s: failed to find dir %s on %s\n", ++ program, subdir, device); ++ goto fail; ++ } ++ ++ retval = ext2fs_check_directory(e2fs, dirino); ++ if (retval) { ++ fprintf(stderr, "%s: failed to cd to: %s\n", program, subdir); ++ goto fail; ++ } ++ cwd = dirino; ++ } ++ ++ return 0; ++ ++fail: ++ (void) ext2fs_close(e2fs); ++ return -1; + } + + /* The install func for ext2, ext3 and ext4 */ +-- +1.9.1 + diff --git a/meta/recipes-devtools/syslinux/syslinux/0003-linux-syslinux-implement-install_to_ext2.patch b/meta/recipes-devtools/syslinux/syslinux/0003-linux-syslinux-implement-install_to_ext2.patch new file mode 100644 index 0000000000..84ba10526a --- /dev/null +++ b/meta/recipes-devtools/syslinux/syslinux/0003-linux-syslinux-implement-install_to_ext2.patch @@ -0,0 +1,116 @@ +From 64d856b243812907068776b204a003a3a8fa122a Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Wed, 31 Dec 2014 16:17:42 +0800 +Subject: [PATCH 3/9] linux/syslinux: implement install_to_ext2() + +* The handle_adv_on_ext() checks whether we only need update adv. +* The write_to_ext() installs files (ldlinux.sys or ldlinux.c32) to the + device. +* The install_bootblock() installs the boot block. + +Upstream-Status: Submitted + +Signed-off-by: Robert Yang +Tested-by: Du Dolpher +--- + linux/syslinux.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 79 insertions(+) + +diff --git a/linux/syslinux.c b/linux/syslinux.c +index cc4e7da..45f080d 100755 +--- a/linux/syslinux.c ++++ b/linux/syslinux.c +@@ -346,11 +346,90 @@ static int open_ext2_fs(const char *device, const char *subdir) + fail: + (void) ext2fs_close(e2fs); + return -1; ++ ++} ++ ++/* ++ * Install the boot block on the specified device. ++ * Must be run AFTER file installed. ++ */ ++int install_bootblock(int fd, const char *device) ++{ ++} ++ ++static int handle_adv_on_ext(void) ++{ ++} ++ ++/* Write files, adv, boot sector */ ++static int write_to_ext(const char *filename, const char *str, int length, ++ int i_flags, int dev_fd, const char *subdir) ++{ + } + + /* The install func for ext2, ext3 and ext4 */ + static int install_to_ext2(const char *device, int dev_fd, const char *subdir) + { ++ int retval; ++ ext2_ino_t oldino; ++ ++ const char *file = "ldlinux.sys"; ++ const char *oldfile = "extlinux.sys"; ++ const char *c32file = "ldlinux.c32"; ++ ++ /* Handle the adv */ ++ if (handle_adv_on_ext() < 0) { ++ fprintf(stderr, "%s: error while handling ADV on %s\n", ++ program, device); ++ retval = 1; ++ goto fail; ++ } ++ ++ /* Return if only need update the adv */ ++ if (opt.update_only == -1) { ++ return ext2fs_close(e2fs); ++ } ++ ++ /* Write ldlinux.sys, adv, boot sector */ ++ retval = write_to_ext(file, (const char _force *)boot_image, ++ boot_image_len, EXT2_IMMUTABLE_FL, dev_fd, subdir); ++ if (retval) { ++ fprintf(stderr, "%s: ERROR: while writing: %s.\n", ++ program, file); ++ goto fail; ++ } ++ ++ /* Write ldlinux.c32 */ ++ retval = write_to_ext(c32file, ++ (const char _force *)syslinux_ldlinuxc32, ++ syslinux_ldlinuxc32_len, 0, dev_fd, subdir); ++ if (retval) { ++ fprintf(stderr, "%s: ERROR: while writing: %s.\n", ++ program, c32file); ++ goto fail; ++ } ++ ++ /* Look if we have the extlinux.sys and remove it*/ ++ retval = ext2fs_namei(e2fs, root, cwd, oldfile, &oldino); ++ if (retval == 0) { ++ retval = ext2fs_unlink(e2fs, cwd, oldfile, oldino, 0); ++ if (retval) { ++ fprintf(stderr, "%s: ERROR: failed to unlink: %s\n", ++ program, oldfile); ++ goto fail; ++ } ++ } else { ++ retval = 0; ++ } ++ ++ sync(); ++ retval = install_bootblock(dev_fd, device); ++ close(dev_fd); ++ sync(); ++ ++fail: ++ (void) ext2fs_close(e2fs); ++ return retval; + } + + int main(int argc, char *argv[]) +-- +1.9.1 + diff --git a/meta/recipes-devtools/syslinux/syslinux/0004-linux-syslinux-add-ext_file_read-and-ext_file_write.patch b/meta/recipes-devtools/syslinux/syslinux/0004-linux-syslinux-add-ext_file_read-and-ext_file_write.patch new file mode 100644 index 0000000000..64b56d92e0 --- /dev/null +++ b/meta/recipes-devtools/syslinux/syslinux/0004-linux-syslinux-add-ext_file_read-and-ext_file_write.patch @@ -0,0 +1,91 @@ +From 35d3842cc4b930c5102eed2921e0189b7f4fd069 Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Wed, 31 Dec 2014 16:43:37 +0800 +Subject: [PATCH 4/9] linux/syslinux: add ext_file_read() and ext_file_write() + +Will use them to read and write on the extX device. + +Upstream-Status: Submitted + +Signed-off-by: Robert Yang +Tested-by: Du Dolpher +--- + linux/syslinux.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 62 insertions(+) + +diff --git a/linux/syslinux.c b/linux/syslinux.c +index 45f080d..247c86a 100755 +--- a/linux/syslinux.c ++++ b/linux/syslinux.c +@@ -349,6 +349,68 @@ fail: + + } + ++/* Read from an ext2_file */ ++static int ext_file_read(ext2_file_t e2_file, void *buf, size_t count, ++ off_t offset, const char *msg) ++{ ++ int retval; ++ char *ptr = (char *) buf; ++ unsigned int got = 0; ++ size_t done = 0; ++ ++ /* Always lseek since e2_file is uncontrolled by this func */ ++ if (ext2fs_file_lseek(e2_file, offset, EXT2_SEEK_SET, NULL)) { ++ fprintf(stderr, "%s: ext2fs_file_lseek() failed.\n", ++ program); ++ return -1; ++ } ++ ++ while (1) { ++ retval = ext2fs_file_read(e2_file, ptr, count, &got); ++ if (retval) { ++ fprintf(stderr, "%s: error while reading %s\n", ++ program, msg); ++ return -1; ++ } ++ count -= got; ++ ptr += got; ++ done += got; ++ if (got == 0 || count == 0) ++ break; ++ } ++ ++ return done; ++} ++ ++/* Write to an ext2_file */ ++static int ext_file_write(ext2_file_t e2_file, const void *buf, size_t count, ++ off_t offset) ++{ ++ const char *ptr = (const char *) buf; ++ unsigned int written = 0; ++ size_t done = 0; ++ ++ /* Always lseek since e2_file is uncontrolled by this func */ ++ if (ext2fs_file_lseek(e2_file, offset, EXT2_SEEK_SET, NULL)) { ++ fprintf(stderr, "%s: ext2fs_file_lseek() failed.\n", ++ program); ++ return -1; ++ } ++ ++ while (count > 0) { ++ if (ext2fs_file_write(e2_file, ptr, count, &written)) { ++ fprintf(stderr, "%s: failed to write syslinux adv.\n", ++ program); ++ return -1; ++ } ++ count -= written; ++ ptr += written; ++ done += written; ++ } ++ ++ return done; ++} ++ + /* + * Install the boot block on the specified device. + * Must be run AFTER file installed. +-- +1.9.1 + diff --git a/meta/recipes-devtools/syslinux/syslinux/0005-linux-syslinux-implement-handle_adv_on_ext.patch b/meta/recipes-devtools/syslinux/syslinux/0005-linux-syslinux-implement-handle_adv_on_ext.patch new file mode 100644 index 0000000000..829e7c4ca1 --- /dev/null +++ b/meta/recipes-devtools/syslinux/syslinux/0005-linux-syslinux-implement-handle_adv_on_ext.patch @@ -0,0 +1,127 @@ +From cdb980b37f40dc2c41891434c7736e49da53756e Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Wed, 31 Dec 2014 16:47:52 +0800 +Subject: [PATCH 5/9] linux/syslinux: implement handle_adv_on_ext() + +It reads adv if found on the device, or resets syslinux_adv, or update +the adv if update adv only. + +Upstream-Status: Submitted + +Signed-off-by: Robert Yang +Tested-by: Du Dolpher +--- + linux/syslinux.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 97 insertions(+) + +diff --git a/linux/syslinux.c b/linux/syslinux.c +index 247c86a..de5d272 100755 +--- a/linux/syslinux.c ++++ b/linux/syslinux.c +@@ -421,6 +421,103 @@ int install_bootblock(int fd, const char *device) + + static int handle_adv_on_ext(void) + { ++ int i, retval, found_file; ++ int need_close = 2; /* 2 means no need extra close */ ++ char *filenames[2] = {"ldlinux.sys", "extlinux.sys"}; ++ char *filename; ++ ext2_ino_t newino; ++ ext2_file_t e2_file; ++ struct ext2_inode inode; ++ ++ for (i = 0; i < 2; i++) { ++ filename = filenames[i]; ++ found_file = 0; ++ retval = ext2fs_namei(e2fs, root, cwd, filename, &newino); ++ if (retval == 0) { ++ found_file = 1; ++ } else ++ continue; ++ ++ need_close = i; ++ ++ retval = ext2fs_file_open(e2fs, newino, EXT2_FLAG_RW, &e2_file); ++ if (retval) { ++ fprintf(stderr, "%s: failed to open %s\n", ++ program, filename); ++ goto fail; ++ } ++ ++ retval = ext2fs_read_inode(e2fs, newino, &inode); ++ if (retval) { ++ fprintf(stderr, "%s: error while reading inode: %u, file: %s\n", ++ program, newino, filename); ++ goto fail; ++ } ++ ++ /* Check the size to see if too small to read */ ++ if (inode.i_size < 2 * ADV_SIZE) { ++ if (opt.update_only == -1) { ++ fprintf(stderr, "%s: failed to write auxilliary data\n\ ++ the size of %s is too small (need --update)?\n", ++ program, filename); ++ retval = -1; ++ goto fail; ++ } ++ syslinux_reset_adv(syslinux_adv); ++ found_file = 0; ++ break; ++ } ++ ++ /* Read the adv */ ++ retval = ext_file_read(e2_file, syslinux_adv, 2 * ADV_SIZE, ++ inode.i_size - 2 * ADV_SIZE, "ADV"); ++ if (retval == -1) ++ goto fail; ++ if (retval == 2 * ADV_SIZE) { ++ retval = syslinux_validate_adv(syslinux_adv); ++ /* Read the adv successfully */ ++ if (retval == 0) ++ break; ++ } ++ ++ /* Close the file if reaches here, otherwise we leave the file ++ * open in case we need write it */ ++ need_close = 2; ++ retval = ext2fs_file_close(e2_file); ++ if (retval) { ++ fprintf(stderr, "%s: error while closing %s\n", ++ program, filename); ++ return retval; ++ } ++ } ++ ++ if (!found_file) { ++ if (opt.update_only == -1) { ++ fprintf(stderr, "%s: no ldlinux.sys or extlinux.sys found on the device\n", ++ program); ++ return -1; ++ } ++ syslinux_reset_adv(syslinux_adv); ++ } ++ ++ /* The modify_adv will reset the adv if opt.reset_adv */ ++ if (modify_adv() < 0) { ++ fprintf(stderr, "%s: error while modifying adv\n", program); ++ retval = -1; ++ goto fail; ++ } ++ ++ /* Write adv if update_only == -1 and found file */ ++ if (opt.update_only == -1 && found_file) { ++ if (ext_file_write(e2_file, syslinux_adv, 2 * ADV_SIZE , ++ inode.i_size - 2 * ADV_SIZE) == -1) ++ goto fail; ++ } ++ ++fail: ++ if (need_close != 2) ++ (void) ext2fs_file_close(e2_file); ++ return retval; + } + + /* Write files, adv, boot sector */ +-- +1.9.1 + diff --git a/meta/recipes-devtools/syslinux/syslinux/0006-linux-syslinux-implement-write_to_ext-and-add-syslin.patch b/meta/recipes-devtools/syslinux/syslinux/0006-linux-syslinux-implement-write_to_ext-and-add-syslin.patch new file mode 100644 index 0000000000..cba87252a5 --- /dev/null +++ b/meta/recipes-devtools/syslinux/syslinux/0006-linux-syslinux-implement-write_to_ext-and-add-syslin.patch @@ -0,0 +1,215 @@ +From 922e56c10e36d876777580c84daef9a66bea6525 Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Wed, 31 Dec 2014 17:20:43 +0800 +Subject: [PATCH 6/9] linux/syslinux: implement write_to_ext() and add + syslinuxext.c + +* The write_to_ext() write file to the extX device, and handle the boot + sector. +* The syslinuxext.c is used for placing the code which are used by + extlinux and syslinux (which is syslinux_patch_bootsect()). + +Upstream-Status: Submitted + +Signed-off-by: Robert Yang +Tested-by: Du Dolpher +--- + libinstaller/syslinuxext.c | 7 +++ + libinstaller/syslinuxext.h | 5 ++ + linux/Makefile | 3 +- + linux/syslinux.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 132 insertions(+), 1 deletion(-) + create mode 100644 libinstaller/syslinuxext.c + create mode 100644 libinstaller/syslinuxext.h + +diff --git a/libinstaller/syslinuxext.c b/libinstaller/syslinuxext.c +new file mode 100644 +index 0000000..bb54cef +--- /dev/null ++++ b/libinstaller/syslinuxext.c +@@ -0,0 +1,7 @@ ++#define _GNU_SOURCE ++ ++/* Patch syslinux_bootsect */ ++void syslinux_patch_bootsect(int dev_fd) ++{ ++} ++ +diff --git a/libinstaller/syslinuxext.h b/libinstaller/syslinuxext.h +new file mode 100644 +index 0000000..8abd8b9 +--- /dev/null ++++ b/libinstaller/syslinuxext.h +@@ -0,0 +1,5 @@ ++#ifndef EXT2_SUPER_OFFSET ++#define EXT2_SUPER_OFFSET 1024 ++#endif ++ ++void syslinux_patch_bootsect(int dev_fd); +diff --git a/linux/Makefile b/linux/Makefile +index ac1ac58..3b23867 100644 +--- a/linux/Makefile ++++ b/linux/Makefile +@@ -30,7 +30,8 @@ SRCS = syslinux.c \ + ../libinstaller/syslxmod.c \ + ../libinstaller/bootsect_bin.c \ + ../libinstaller/ldlinuxc32_bin.c \ +- ../libinstaller/ldlinux_bin.c ++ ../libinstaller/ldlinux_bin.c \ ++ ../libinstaller/syslinuxext.c + OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) + + .SUFFIXES: .c .o .i .s .S +diff --git a/linux/syslinux.c b/linux/syslinux.c +index de5d272..f0c97a8 100755 +--- a/linux/syslinux.c ++++ b/linux/syslinux.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + + #include "linuxioctl.h" + +@@ -72,6 +73,7 @@ + #include "syslxfs.h" + #include "setadv.h" + #include "syslxopt.h" /* unified options */ ++#include "syslinuxext.h" + #include + + extern const char *program; /* Name of program */ +@@ -419,6 +421,12 @@ int install_bootblock(int fd, const char *device) + { + } + ++/* Construct the boot file map */ ++int ext_construct_sectmap_fs(ext2_filsys fs, ext2_ino_t newino, ++ sector_t *sectors, int nsect) ++{ ++} ++ + static int handle_adv_on_ext(void) + { + int i, retval, found_file; +@@ -524,6 +532,116 @@ fail: + static int write_to_ext(const char *filename, const char *str, int length, + int i_flags, int dev_fd, const char *subdir) + { ++ ext2_ino_t newino; ++ struct ext2_inode inode; ++ int retval, i, modbytes, nsect; ++ ext2_file_t e2_file; ++ sector_t *sectors; ++ ++ /* Remove it if it is already exists */ ++ retval = ext2fs_namei(e2fs, root, cwd, filename, &newino); ++ if (retval == 0) { ++ retval = ext2fs_unlink(e2fs, cwd, filename, newino, 0); ++ if (retval) { ++ fprintf(stderr, "%s: failed to unlink: %s\n", program, filename); ++ return retval; ++ } ++ } ++ ++ /* Create new inode */ ++ retval = ext2fs_new_inode(e2fs, cwd, 010755, 0, &newino); ++ if (retval) { ++ fprintf(stderr, "%s: ERROR: failed to create inode for: %s\n", ++ program, filename); ++ return retval; ++ } ++ ++ /* Link the inode and the filename */ ++ retval = ext2fs_link(e2fs, cwd, filename, newino, EXT2_FT_REG_FILE); ++ if (retval) { ++ fprintf(stderr, "%s: ERROR: failed to link inode for: %s.\n", ++ program, filename); ++ return retval; ++ } ++ ++ if (ext2fs_test_inode_bitmap2(e2fs->inode_map, newino)) ++ fprintf(stderr, "%s: warning: inode already set %s.\n", ++ program, filename); ++ ++ ext2fs_inode_alloc_stats2(e2fs, newino, +1, 0); ++ memset(&inode, 0, sizeof(inode)); ++ inode.i_mode = LINUX_S_IFREG | LINUX_S_IRUSR | LINUX_S_IRGRP ++ | LINUX_S_IROTH; ++ inode.i_flags |= i_flags; ++ inode.i_atime = inode.i_ctime = inode.i_mtime = ++ e2fs->now ? e2fs->now : time(0); ++ inode.i_links_count = 1; ++ if (e2fs->super->s_feature_incompat & ++ EXT3_FEATURE_INCOMPAT_EXTENTS) { ++ struct ext3_extent_header *eh; ++ ++ eh = (struct ext3_extent_header *) &inode.i_block[0]; ++ eh->eh_depth = 0; ++ eh->eh_entries = 0; ++ eh->eh_magic = ext2fs_cpu_to_le16(EXT3_EXT_MAGIC); ++ i = (sizeof(inode.i_block) - sizeof(*eh)) / ++ sizeof(struct ext3_extent); ++ eh->eh_max = ext2fs_cpu_to_le16(i); ++ inode.i_flags |= EXT4_EXTENTS_FL; ++ } ++ ++ retval = ext2fs_write_new_inode(e2fs, newino, &inode); ++ if (retval) { ++ fprintf(stderr, "%s: ERROR: while writting inode %d.\n", ++ program, newino); ++ return 1; ++ } ++ ++ retval = ext2fs_file_open(e2fs, newino, EXT2_FILE_WRITE, &e2_file); ++ if (retval) { ++ fprintf(stderr, "%s: ERROR: failed to open %s.\n", ++ program, filename); ++ return 1; ++ } ++ ++ /* Write to file */ ++ if (ext_file_write(e2_file, str, length, 0) == -1) ++ goto fail; ++ ++ if (strcmp(filename, "ldlinux.sys") == 0) { ++ /* Write ADV */ ++ if (ext_file_write(e2_file, syslinux_adv, 2 * ADV_SIZE, ++ boot_image_len) == -1) ++ goto fail; ++ ++ /* Patch syslinux_bootsect */ ++ syslinux_patch_bootsect(dev_fd); ++ ++ /* Patch ldlinux.sys */ ++ nsect = (boot_image_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT; ++ nsect += 2; /* Two sectors for the ADV */ ++ sectors = alloca(sizeof(sector_t) * nsect); ++ memset(sectors, 0, nsect * sizeof *sectors); ++ /* The sectors will be modified and used by syslinux_patch() */ ++ retval = ext_construct_sectmap_fs(e2fs, newino, sectors, nsect); ++ if (retval) ++ goto fail; ++ ++ /* Create the modified image in memory */ ++ modbytes = syslinux_patch(sectors, nsect, opt.stupid_mode, ++ opt.raid_mode, subdir, NULL); ++ ++ /* Rewrite the first modbytes of ldlinux.sys */ ++ if (ext_file_write(e2_file, str, modbytes, 0) == -1) { ++ fprintf(stderr, "%s: ERROR: failed to patch %s.\n", program, ++ filename); ++ goto fail; ++ } ++ } ++ ++fail: ++ (void) ext2fs_file_close(e2_file); ++ return retval; + } + + /* The install func for ext2, ext3 and ext4 */ +-- +1.9.1 + diff --git a/meta/recipes-devtools/syslinux/syslinux/0007-linux-syslinux-implement-ext_construct_sectmap_fs.patch b/meta/recipes-devtools/syslinux/syslinux/0007-linux-syslinux-implement-ext_construct_sectmap_fs.patch new file mode 100644 index 0000000000..3913811917 --- /dev/null +++ b/meta/recipes-devtools/syslinux/syslinux/0007-linux-syslinux-implement-ext_construct_sectmap_fs.patch @@ -0,0 +1,84 @@ +From a95b831e18dd123f859bc5e6c4cecdcc0184ee37 Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Fri, 2 Jan 2015 12:18:02 +0800 +Subject: [PATCH 7/9] linux/syslinux: implement ext_construct_sectmap_fs() + +The ext_construct_sectmap_fs() constucts the sector according to the +bmap. + +Upstream-Status: Submitted + +Signed-off-by: Robert Yang +Tested-by: Du Dolpher +--- + linux/syslinux.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/linux/syslinux.c b/linux/syslinux.c +index f0c97a8..c741750 100755 +--- a/linux/syslinux.c ++++ b/linux/syslinux.c +@@ -421,10 +421,60 @@ int install_bootblock(int fd, const char *device) + { + } + ++/* The file's block count */ ++int block_count = 0; ++static int get_block_count(ext2_filsys fs EXT2FS_ATTR((unused)), ++ blk64_t *blocknr EXT2FS_ATTR((unused)), ++ e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), ++ blk64_t ref_block EXT2FS_ATTR((unused)), ++ int ref_offset EXT2FS_ATTR((unused)), ++ void *private EXT2FS_ATTR((unused))) ++{ ++ block_count++; ++ return 0; ++} ++ + /* Construct the boot file map */ + int ext_construct_sectmap_fs(ext2_filsys fs, ext2_ino_t newino, + sector_t *sectors, int nsect) + { ++ blk64_t pblk, blksize, blk = 0; ++ sector_t sec; ++ unsigned int i; ++ int retval; ++ ++ blksize = fs->blocksize; ++ blksize >>= SECTOR_SHIFT; ++ ++ /* Get the total blocks no. */ ++ retval = ext2fs_block_iterate3(fs, newino, BLOCK_FLAG_READ_ONLY, ++ NULL, get_block_count, NULL); ++ if (retval) { ++ fprintf(stderr, "%s: ERROR: ext2fs_block_iterate3() failed.\n", program); ++ return -1; ++ } ++ ++ while (nsect) { ++ if (block_count-- == 0) ++ break; ++ ++ /* Get the physical block no. (bmap) */ ++ retval = ext2fs_bmap2(fs, newino, 0, 0, 0, blk, 0, &pblk); ++ if (retval) { ++ fprintf(stderr, "%s: ERROR: ext2fs_bmap2() failed.\n", program); ++ return -1; ++ } ++ ++ blk++; ++ sec = (sector_t)pblk * blksize; ++ for (i = 0; i < blksize; i++) { ++ *sectors++ = sec++; ++ if (! --nsect) ++ break; ++ } ++ } ++ ++ return 0; + } + + static int handle_adv_on_ext(void) +-- +1.9.1 + diff --git a/meta/recipes-devtools/syslinux/syslinux/0008-libinstaller-syslinuxext-implement-syslinux_patch_bo.patch b/meta/recipes-devtools/syslinux/syslinux/0008-libinstaller-syslinuxext-implement-syslinux_patch_bo.patch new file mode 100644 index 0000000000..2400c98d6a --- /dev/null +++ b/meta/recipes-devtools/syslinux/syslinux/0008-libinstaller-syslinuxext-implement-syslinux_patch_bo.patch @@ -0,0 +1,427 @@ +From 78d76b87a4b855e6b661ae457283a63f385c04c9 Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Fri, 2 Jan 2015 12:26:46 +0800 +Subject: [PATCH 8/9] libinstaller/syslinuxext: implement + syslinux_patch_bootsect() + +Move the related from extlinux/main.c to libinstaller/syslinuxext.c, the +syslinux_patch_bootsect() are used by both extlinux/main.c and +linux/syslinux.c. + +Upstream-Status: Submitted + +Signed-off-by: Robert Yang +Tested-by: Du Dolpher +--- + extlinux/Makefile | 3 +- + extlinux/main.c | 167 +------------------------------------------- + libinstaller/syslinuxext.c | 170 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 175 insertions(+), 165 deletions(-) + +diff --git a/extlinux/Makefile b/extlinux/Makefile +index 02d1db5..90dd92f 100644 +--- a/extlinux/Makefile ++++ b/extlinux/Makefile +@@ -31,7 +31,8 @@ SRCS = main.c \ + ../libinstaller/advio.c \ + ../libinstaller/bootsect_bin.c \ + ../libinstaller/ldlinuxc32_bin.c \ +- ../libinstaller/ldlinux_bin.c ++ ../libinstaller/ldlinux_bin.c \ ++ ../libinstaller/syslinuxext.c + OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) + + .SUFFIXES: .c .o .i .s .S +diff --git a/extlinux/main.c b/extlinux/main.c +index 09740bd..6fe026e 100644 +--- a/extlinux/main.c ++++ b/extlinux/main.c +@@ -60,6 +60,7 @@ + #include "setadv.h" + #include "syslxopt.h" /* unified options */ + #include "mountinfo.h" ++#include "syslinuxext.h" + + #ifdef DEBUG + # define dprintf printf +@@ -67,10 +68,6 @@ + # define dprintf(...) ((void)0) + #endif + +-#ifndef EXT2_SUPER_OFFSET +-#define EXT2_SUPER_OFFSET 1024 +-#endif +- + /* Since we have unused 2048 bytes in the primary AG of an XFS partition, + * we will use the first 0~512 bytes starting from 2048 for the Syslinux + * boot sector. +@@ -92,136 +89,6 @@ static char subvol[BTRFS_SUBVOL_MAX]; + - 2*ADV_SIZE) + + /* +- * Get the size of a block device +- */ +-static uint64_t get_size(int devfd) +-{ +- uint64_t bytes; +- uint32_t sects; +- struct stat st; +- +-#ifdef BLKGETSIZE64 +- if (!ioctl(devfd, BLKGETSIZE64, &bytes)) +- return bytes; +-#endif +- if (!ioctl(devfd, BLKGETSIZE, §s)) +- return (uint64_t) sects << 9; +- else if (!fstat(devfd, &st) && st.st_size) +- return st.st_size; +- else +- return 0; +-} +- +-/* +- * Get device geometry and partition offset +- */ +-struct geometry_table { +- uint64_t bytes; +- struct hd_geometry g; +-}; +- +-static int sysfs_get_offset(int devfd, unsigned long *start) +-{ +- struct stat st; +- char sysfs_name[128]; +- FILE *f; +- int rv; +- +- if (fstat(devfd, &st)) +- return -1; +- +- if ((size_t)snprintf(sysfs_name, sizeof sysfs_name, +- "/sys/dev/block/%u:%u/start", +- major(st.st_rdev), minor(st.st_rdev)) +- >= sizeof sysfs_name) +- return -1; +- +- f = fopen(sysfs_name, "r"); +- if (!f) +- return -1; +- +- rv = fscanf(f, "%lu", start); +- fclose(f); +- +- return (rv == 1) ? 0 : -1; +-} +- +-/* Standard floppy disk geometries, plus LS-120. Zipdisk geometry +- (x/64/32) is the final fallback. I don't know what LS-240 has +- as its geometry, since I don't have one and don't know anyone that does, +- and Google wasn't helpful... */ +-static const struct geometry_table standard_geometries[] = { +- {360 * 1024, {2, 9, 40, 0}}, +- {720 * 1024, {2, 9, 80, 0}}, +- {1200 * 1024, {2, 15, 80, 0}}, +- {1440 * 1024, {2, 18, 80, 0}}, +- {1680 * 1024, {2, 21, 80, 0}}, +- {1722 * 1024, {2, 21, 80, 0}}, +- {2880 * 1024, {2, 36, 80, 0}}, +- {3840 * 1024, {2, 48, 80, 0}}, +- {123264 * 1024, {8, 32, 963, 0}}, /* LS120 */ +- {0, {0, 0, 0, 0}} +-}; +- +-int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo) +-{ +- struct floppy_struct fd_str; +- struct loop_info li; +- struct loop_info64 li64; +- const struct geometry_table *gp; +- int rv = 0; +- +- memset(geo, 0, sizeof *geo); +- +- if (!ioctl(devfd, HDIO_GETGEO, geo)) { +- goto ok; +- } else if (!ioctl(devfd, FDGETPRM, &fd_str)) { +- geo->heads = fd_str.head; +- geo->sectors = fd_str.sect; +- geo->cylinders = fd_str.track; +- geo->start = 0; +- goto ok; +- } +- +- /* Didn't work. Let's see if this is one of the standard geometries */ +- for (gp = standard_geometries; gp->bytes; gp++) { +- if (gp->bytes == totalbytes) { +- memcpy(geo, &gp->g, sizeof *geo); +- goto ok; +- } +- } +- +- /* Didn't work either... assign a geometry of 64 heads, 32 sectors; this is +- what zipdisks use, so this would help if someone has a USB key that +- they're booting in USB-ZIP mode. */ +- +- geo->heads = opt.heads ? : 64; +- geo->sectors = opt.sectors ? : 32; +- geo->cylinders = totalbytes / (geo->heads * geo->sectors << SECTOR_SHIFT); +- geo->start = 0; +- +- if (!opt.sectors && !opt.heads) { +- fprintf(stderr, +- "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n" +- " (on hard disks, this is usually harmless.)\n", +- geo->heads, geo->sectors); +- rv = 1; /* Suboptimal result */ +- } +- +-ok: +- /* If this is a loopback device, try to set the start */ +- if (!ioctl(devfd, LOOP_GET_STATUS64, &li64)) +- geo->start = li64.lo_offset >> SECTOR_SHIFT; +- else if (!ioctl(devfd, LOOP_GET_STATUS, &li)) +- geo->start = (unsigned int)li.lo_offset >> SECTOR_SHIFT; +- else if (!sysfs_get_offset(devfd, &geo->start)) { +- /* OK */ +- } +- +- return rv; +-} +- +-/* + * 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. +@@ -231,11 +98,8 @@ ok: + static int patch_file_and_bootblock(int fd, const char *dir, int devfd) + { + struct stat dirst, xdst; +- struct hd_geometry geo; + sector_t *sectp; +- uint64_t totalbytes, totalsectors; + int nsect; +- struct fat_boot_sector *sbs; + char *dirpath, *subpath, *xdirpath; + int rv; + +@@ -279,33 +143,8 @@ static int patch_file_and_bootblock(int fd, const char *dir, int devfd) + /* Now subpath should contain the path relative to the fs base */ + dprintf("subpath = %s\n", subpath); + +- totalbytes = get_size(devfd); +- get_geometry(devfd, totalbytes, &geo); +- +- if (opt.heads) +- geo.heads = opt.heads; +- if (opt.sectors) +- geo.sectors = opt.sectors; +- +- /* Patch this into a fake FAT superblock. This isn't because +- FAT is a good format in any way, it's because it lets the +- early bootstrap share code with the FAT version. */ +- dprintf("heads = %u, sect = %u\n", geo.heads, geo.sectors); +- +- sbs = (struct fat_boot_sector *)syslinux_bootsect; +- +- totalsectors = totalbytes >> SECTOR_SHIFT; +- if (totalsectors >= 65536) { +- set_16(&sbs->bsSectors, 0); +- } else { +- set_16(&sbs->bsSectors, totalsectors); +- } +- set_32(&sbs->bsHugeSectors, totalsectors); +- +- set_16(&sbs->bsBytesPerSec, SECTOR_SIZE); +- set_16(&sbs->bsSecPerTrack, geo.sectors); +- set_16(&sbs->bsHeads, geo.heads); +- set_32(&sbs->bsHiddenSecs, geo.start); ++ /* Patch syslinux_bootsect */ ++ syslinux_patch_bootsect(devfd); + + /* Construct the boot file map */ + +diff --git a/libinstaller/syslinuxext.c b/libinstaller/syslinuxext.c +index bb54cef..5a4423b 100644 +--- a/libinstaller/syslinuxext.c ++++ b/libinstaller/syslinuxext.c +@@ -1,7 +1,177 @@ + #define _GNU_SOURCE + ++#include ++#include ++#include ++#include ++ ++#include "linuxioctl.h" ++#include "syslinux.h" ++#include "syslxint.h" ++#include "syslxopt.h" ++ ++/* ++ * Get the size of a block device ++ */ ++static uint64_t get_size(int dev_fd) ++{ ++ uint64_t bytes; ++ uint32_t sects; ++ struct stat st; ++ ++#ifdef BLKGETSIZE64 ++ if (!ioctl(dev_fd, BLKGETSIZE64, &bytes)) ++ return bytes; ++#endif ++ if (!ioctl(dev_fd, BLKGETSIZE, §s)) ++ return (uint64_t) sects << 9; ++ else if (!fstat(dev_fd, &st) && st.st_size) ++ return st.st_size; ++ else ++ return 0; ++} ++ ++/* ++ * Get device geometry and partition offset ++ */ ++static struct geometry_table { ++ uint64_t bytes; ++ struct hd_geometry g; ++}; ++ ++static int sysfs_get_offset(int dev_fd, unsigned long *start) ++{ ++ struct stat st; ++ char sysfs_name[128]; ++ FILE *f; ++ int rv; ++ ++ if (fstat(dev_fd, &st)) ++ return -1; ++ ++ if ((size_t)snprintf(sysfs_name, sizeof sysfs_name, ++ "/sys/dev/block/%u:%u/start", ++ major(st.st_rdev), minor(st.st_rdev)) ++ >= sizeof sysfs_name) ++ return -1; ++ ++ f = fopen(sysfs_name, "r"); ++ if (!f) ++ return -1; ++ ++ rv = fscanf(f, "%lu", start); ++ fclose(f); ++ ++ return (rv == 1) ? 0 : -1; ++} ++ ++/* Standard floppy disk geometries, plus LS-120. Zipdisk geometry ++ (x/64/32) is the final fallback. I don't know what LS-240 has ++ as its geometry, since I don't have one and don't know anyone that does, ++ and Google wasn't helpful... */ ++static const struct geometry_table standard_geometries[] = { ++ {360 * 1024, {2, 9, 40, 0}}, ++ {720 * 1024, {2, 9, 80, 0}}, ++ {1200 * 1024, {2, 15, 80, 0}}, ++ {1440 * 1024, {2, 18, 80, 0}}, ++ {1680 * 1024, {2, 21, 80, 0}}, ++ {1722 * 1024, {2, 21, 80, 0}}, ++ {2880 * 1024, {2, 36, 80, 0}}, ++ {3840 * 1024, {2, 48, 80, 0}}, ++ {123264 * 1024, {8, 32, 963, 0}}, /* LS120 */ ++ {0, {0, 0, 0, 0}} ++}; ++ ++static int get_geometry(int dev_fd, uint64_t totalbytes, struct hd_geometry *geo) ++{ ++ struct floppy_struct fd_str; ++ struct loop_info li; ++ struct loop_info64 li64; ++ const struct geometry_table *gp; ++ int rv = 0; ++ ++ memset(geo, 0, sizeof *geo); ++ ++ if (!ioctl(dev_fd, HDIO_GETGEO, geo)) { ++ goto ok; ++ } else if (!ioctl(dev_fd, FDGETPRM, &fd_str)) { ++ geo->heads = fd_str.head; ++ geo->sectors = fd_str.sect; ++ geo->cylinders = fd_str.track; ++ geo->start = 0; ++ goto ok; ++ } ++ ++ /* Didn't work. Let's see if this is one of the standard geometries */ ++ for (gp = standard_geometries; gp->bytes; gp++) { ++ if (gp->bytes == totalbytes) { ++ memcpy(geo, &gp->g, sizeof *geo); ++ goto ok; ++ } ++ } ++ ++ /* Didn't work either... assign a geometry of 64 heads, 32 sectors; this is ++ what zipdisks use, so this would help if someone has a USB key that ++ they're booting in USB-ZIP mode. */ ++ ++ geo->heads = opt.heads ? : 64; ++ geo->sectors = opt.sectors ? : 32; ++ geo->cylinders = totalbytes / (geo->heads * geo->sectors << SECTOR_SHIFT); ++ geo->start = 0; ++ ++ if (!opt.sectors && !opt.heads) { ++ fprintf(stderr, ++ "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n" ++ " (on hard disks, this is usually harmless.)\n", ++ geo->heads, geo->sectors); ++ rv = 1; /* Suboptimal result */ ++ } ++ ++ok: ++ /* If this is a loopback device, try to set the start */ ++ if (!ioctl(dev_fd, LOOP_GET_STATUS64, &li64)) ++ geo->start = li64.lo_offset >> SECTOR_SHIFT; ++ else if (!ioctl(dev_fd, LOOP_GET_STATUS, &li)) ++ geo->start = (unsigned int)li.lo_offset >> SECTOR_SHIFT; ++ else if (!sysfs_get_offset(dev_fd, &geo->start)) { ++ /* OK */ ++ } ++ ++ return rv; ++} ++ ++ + /* Patch syslinux_bootsect */ + void syslinux_patch_bootsect(int dev_fd) + { ++ uint64_t totalbytes, totalsectors; ++ struct hd_geometry geo; ++ struct fat_boot_sector *sbs; ++ ++ totalbytes = get_size(dev_fd); ++ get_geometry(dev_fd, totalbytes, &geo); ++ ++ if (opt.heads) ++ geo.heads = opt.heads; ++ if (opt.sectors) ++ geo.sectors = opt.sectors; ++ ++ /* Patch this into a fake FAT superblock. This isn't because ++ FAT is a good format in any way, it's because it lets the ++ early bootstrap share code with the FAT version. */ ++ sbs = (struct fat_boot_sector *)syslinux_bootsect; ++ ++ totalsectors = totalbytes >> SECTOR_SHIFT; ++ if (totalsectors >= 65536) { ++ set_16(&sbs->bsSectors, 0); ++ } else { ++ set_16(&sbs->bsSectors, totalsectors); ++ } ++ set_32(&sbs->bsHugeSectors, totalsectors); ++ ++ set_16(&sbs->bsBytesPerSec, SECTOR_SIZE); ++ set_16(&sbs->bsSecPerTrack, geo.sectors); ++ set_16(&sbs->bsHeads, geo.heads); ++ set_32(&sbs->bsHiddenSecs, geo.start); + } + +-- +1.9.1 + diff --git a/meta/recipes-devtools/syslinux/syslinux/0009-linux-syslinux-implement-install_bootblock.patch b/meta/recipes-devtools/syslinux/syslinux/0009-linux-syslinux-implement-install_bootblock.patch new file mode 100644 index 0000000000..cd89d92485 --- /dev/null +++ b/meta/recipes-devtools/syslinux/syslinux/0009-linux-syslinux-implement-install_bootblock.patch @@ -0,0 +1,50 @@ +From 76c465e87312dbc6cffd05427f1f4d2ebdee4f13 Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Fri, 2 Jan 2015 12:28:35 +0800 +Subject: [PATCH 9/9] linux/syslinux: implement install_bootblock() + +Refer to the install_bootblock() in extlinux/main.c to make +linux/syslinux.c's install_bootblock() which only supports ext2/3/4. + +Upstream-Status: Submitted + +Signed-off-by: Robert Yang +Tested-by: Du Dolpher +--- + linux/syslinux.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/linux/syslinux.c b/linux/syslinux.c +index c741750..917f83a 100755 +--- a/linux/syslinux.c ++++ b/linux/syslinux.c +@@ -419,6 +419,26 @@ static int ext_file_write(ext2_file_t e2_file, const void *buf, size_t count, + */ + int install_bootblock(int fd, const char *device) + { ++ struct ext2_super_block sb; ++ ++ if (xpread(fd, &sb, sizeof sb, EXT2_SUPER_OFFSET + opt.offset) != sizeof sb) { ++ perror("reading superblock"); ++ return 1; ++ } ++ ++ if (sb.s_magic != EXT2_SUPER_MAGIC) { ++ fprintf(stderr, ++ "no ext2/3/4 superblock found on %s\n", device); ++ return 1; ++ } ++ ++ if (xpwrite(fd, syslinux_bootsect, syslinux_bootsect_len, 0) ++ != (signed)syslinux_bootsect_len) { ++ perror("writing bootblock"); ++ return 1; ++ } ++ ++ return 0; + } + + /* The file's block count */ +-- +1.9.1 + diff --git a/meta/recipes-devtools/syslinux/syslinux_6.03.bb b/meta/recipes-devtools/syslinux/syslinux_6.03.bb index 7e3176e84e..33dd776f1b 100644 --- a/meta/recipes-devtools/syslinux/syslinux_6.03.bb +++ b/meta/recipes-devtools/syslinux/syslinux_6.03.bb @@ -6,12 +6,21 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=0636e73ff0215e8d672dc4c32c317bb3 \ # If you really want to run syslinux, you need mtools. We just want the # ldlinux.* stuff for now, so skip mtools-native -DEPENDS = "nasm-native util-linux" +DEPENDS = "nasm-native util-linux e2fsprogs" SRC_URI = "${KERNELORG_MIRROR}/linux/utils/boot/syslinux/6.xx/syslinux-${PV}.tar.xz \ file://syslinux-fix-parallel-building-issue.patch \ file://syslinux-libupload-depend-lib.patch \ file://syslinux-remove-clean-script.patch \ + file://0001-linux-syslinux-support-ext2-3-4-device.patch \ + file://0002-linux-syslinux-implement-open_ext2_fs.patch \ + file://0003-linux-syslinux-implement-install_to_ext2.patch \ + file://0004-linux-syslinux-add-ext_file_read-and-ext_file_write.patch \ + file://0005-linux-syslinux-implement-handle_adv_on_ext.patch \ + file://0006-linux-syslinux-implement-write_to_ext-and-add-syslin.patch \ + file://0007-linux-syslinux-implement-ext_construct_sectmap_fs.patch \ + file://0008-libinstaller-syslinuxext-implement-syslinux_patch_bo.patch \ + file://0009-linux-syslinux-implement-install_bootblock.patch \ " SRC_URI[md5sum] = "92a253df9211e9c20172796ecf388f13" -- cgit v1.2.3-54-g00ecf