summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Yang <liezhi.yang@windriver.com>2015-02-13 00:59:08 -0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-02-15 21:58:29 +0000
commita2bfd4b1fb055e63a48d80e7e55a6cff475e06d1 (patch)
tree104a6937a3153b4dbf78e6111c36be6cd213be13
parent06ff3c420ca3b4237271879571d9933bbe6463ec (diff)
downloadpoky-a2bfd4b1fb055e63a48d80e7e55a6cff475e06d1.tar.gz
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 <liezhi.yang@windriver.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/syslinux/syslinux/0001-linux-syslinux-support-ext2-3-4-device.patch84
-rw-r--r--meta/recipes-devtools/syslinux/syslinux/0002-linux-syslinux-implement-open_ext2_fs.patch141
-rw-r--r--meta/recipes-devtools/syslinux/syslinux/0003-linux-syslinux-implement-install_to_ext2.patch116
-rw-r--r--meta/recipes-devtools/syslinux/syslinux/0004-linux-syslinux-add-ext_file_read-and-ext_file_write.patch91
-rw-r--r--meta/recipes-devtools/syslinux/syslinux/0005-linux-syslinux-implement-handle_adv_on_ext.patch127
-rw-r--r--meta/recipes-devtools/syslinux/syslinux/0006-linux-syslinux-implement-write_to_ext-and-add-syslin.patch215
-rw-r--r--meta/recipes-devtools/syslinux/syslinux/0007-linux-syslinux-implement-ext_construct_sectmap_fs.patch84
-rw-r--r--meta/recipes-devtools/syslinux/syslinux/0008-libinstaller-syslinuxext-implement-syslinux_patch_bo.patch427
-rw-r--r--meta/recipes-devtools/syslinux/syslinux/0009-linux-syslinux-implement-install_bootblock.patch50
-rw-r--r--meta/recipes-devtools/syslinux/syslinux_6.03.bb11
10 files changed, 1345 insertions, 1 deletions
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 @@
1From 60f3833ab2b5899771b4eab654e88f9888b99501 Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Wed, 31 Dec 2014 16:01:55 +0800
4Subject: [PATCH 1/9] linux/syslinux: support ext2/3/4 device
5
6* Support ext2/3/4 deivce.
7* The open_ext2_fs() checks whether it is an ext2/3/4 device,
8 do the ext2/3/4 installation (install_to_ext2()) if yes, otherwise go
9 on to the fat/ntfs.
10* The ext2/3/4 support doesn't require root privileges since it doesn't need
11 mount (but write permission is required).
12
13Upstream-Status: Submitted
14
15Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
16Tested-by: Du Dolpher <dolpher.du@intel.com>
17---
18 linux/syslinux.c | 36 ++++++++++++++++++++++++++++++++++++
19 1 file changed, 36 insertions(+)
20
21diff --git a/linux/syslinux.c b/linux/syslinux.c
22index 912de71..36fc202 100755
23--- a/linux/syslinux.c
24+++ b/linux/syslinux.c
25@@ -256,6 +256,23 @@ int do_open_file(char *name)
26 return fd;
27 }
28
29+/*
30+ * Check whether the device contains an ext2, ext3 or ext4 fs and open it if
31+ * true.
32+ * return value:
33+ * 0: Everything is OK
34+ * 1: Not an ext2, ext3 or ext4
35+ * -1: unexpected error
36+ */
37+static int open_ext2_fs(const char *device, const char *subdir)
38+{
39+}
40+
41+/* The install func for ext2, ext3 and ext4 */
42+static int install_to_ext2(const char *device, int dev_fd, const char *subdir)
43+{
44+}
45+
46 int main(int argc, char *argv[])
47 {
48 static unsigned char sectbuf[SECTOR_SIZE];
49@@ -313,6 +330,24 @@ int main(int argc, char *argv[])
50 die("can't combine an offset with a block device");
51 }
52
53+ /*
54+ * Check if it is an ext2, ext3 or ext4
55+ */
56+ rv = open_ext2_fs(opt.device, subdir);
57+ if (rv == 0) {
58+ if (install_to_ext2(opt.device, dev_fd, subdir)) {
59+ fprintf(stderr, "%s: installation failed\n", opt.device);
60+ exit(1);
61+ }
62+ return 0;
63+ /* Unexpected errors */
64+ } else if (rv == -1) {
65+ exit(1);
66+ }
67+
68+ /* Reset rv */
69+ rv = 0;
70+
71 xpread(dev_fd, sectbuf, SECTOR_SIZE, opt.offset);
72 fsync(dev_fd);
73
74@@ -322,6 +357,7 @@ int main(int argc, char *argv[])
75 */
76 if ((errmsg = syslinux_check_bootsect(sectbuf, &fs_type))) {
77 fprintf(stderr, "%s: %s\n", opt.device, errmsg);
78+ fprintf(stderr, "%s: supported fs: fat/ntfs/ext2/ex3/ext4\n", program);
79 exit(1);
80 }
81
82--
831.9.1
84
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 @@
1From 07fb737fb60c08eaaa41989d531fc23009523546 Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Wed, 31 Dec 2014 16:09:18 +0800
4Subject: [PATCH 2/9] linux/syslinux: implement open_ext2_fs()
5
6The open_ext2_fs() checks whether it is an ext2/ext3/ext4 device, and
7return:
80: It is an ext2, ext3 or ext4.
91: Not an ext2, ext3 or ext4.
10-1: unexpected error.
11
12Upstream-Status: Submitted
13
14Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
15Tested-by: Du Dolpher <dolpher.du@intel.com>
16---
17 linux/Makefile | 2 +-
18 linux/syslinux.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19 2 files changed, 81 insertions(+), 1 deletion(-)
20
21diff --git a/linux/Makefile b/linux/Makefile
22index 11667e1..ac1ac58 100644
23--- a/linux/Makefile
24+++ b/linux/Makefile
25@@ -51,7 +51,7 @@ spotless: clean
26 installer: syslinux syslinux-nomtools
27
28 syslinux: $(OBJS)
29- $(CC) $(LDFLAGS) -o $@ $^
30+ $(CC) $(LDFLAGS) -o $@ $^ -lext2fs
31
32 syslinux-nomtools: syslinux
33 ln -f $< $@
34diff --git a/linux/syslinux.c b/linux/syslinux.c
35index 36fc202..cc4e7da 100755
36--- a/linux/syslinux.c
37+++ b/linux/syslinux.c
38@@ -72,6 +72,7 @@
39 #include "syslxfs.h"
40 #include "setadv.h"
41 #include "syslxopt.h" /* unified options */
42+#include <ext2fs/ext2fs.h>
43
44 extern const char *program; /* Name of program */
45
46@@ -82,6 +83,9 @@ char *mntpath = NULL; /* Path on which to mount */
47 int loop_fd = -1; /* Loop device */
48 #endif
49
50+ext2_filsys e2fs = NULL; /* Ext2/3/4 filesystem */
51+ext2_ino_t root, cwd; /* The root and cwd of e2fs */
52+
53 void __attribute__ ((noreturn)) die(const char *msg)
54 {
55 fprintf(stderr, "%s: %s\n", program, msg);
56@@ -266,6 +270,82 @@ int do_open_file(char *name)
57 */
58 static int open_ext2_fs(const char *device, const char *subdir)
59 {
60+ int retval;
61+ int open_flag = EXT2_FLAG_RW, mount_flags;
62+ ext2_ino_t dirino;
63+ char opt_string[40];
64+
65+ if (opt.offset) {
66+ sprintf(opt_string, "offset=%llu", (unsigned long long)opt.offset);
67+ retval = ext2fs_open2(device, opt_string, open_flag, 0, 0, unix_io_manager, &e2fs);
68+ } else
69+ retval = ext2fs_open(device, open_flag, 0, 0, unix_io_manager, &e2fs);
70+ if (retval) {
71+ /* It might not be an extN fs, so we need check magic firstly */
72+ if (retval == EXT2_ET_BAD_MAGIC) {
73+ /* Do nothing, return silently */
74+ return 1;
75+ } else {
76+ fprintf(stderr, "%s: error while trying to open: %s\n",
77+ program, device);
78+ return -1;
79+ }
80+ }
81+
82+ /* Stop if it is mounted */
83+ retval = ext2fs_check_if_mounted(device, &mount_flags);
84+ if (retval) {
85+ fprintf(stderr, "%s: ext2fs_check_if_mount() error on %s\n",
86+ program, device);
87+ goto fail;
88+ }
89+
90+ if (mount_flags & EXT2_MF_MOUNTED) {
91+ fprintf(stderr, "%s: %s is mounted\n", program, device);
92+ goto fail;
93+ }
94+
95+ e2fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;
96+
97+ /* Read the inode map */
98+ retval = ext2fs_read_inode_bitmap(e2fs);
99+ if (retval) {
100+ fprintf(stderr, "%s: while reading inode bitmap: %s\n",
101+ program, device);
102+ goto fail;
103+ }
104+
105+ /* Read the block map */
106+ retval = ext2fs_read_block_bitmap(e2fs);
107+ if (retval) {
108+ fprintf(stderr, "%s: while reading block bitmap: %s\n",
109+ program, device);
110+ goto fail;
111+ }
112+
113+ root = cwd = EXT2_ROOT_INO;
114+ /* Check the subdir */
115+ if (strcmp(subdir, "/")) {
116+ retval = ext2fs_namei(e2fs, root, cwd, subdir, &dirino);
117+ if (retval) {
118+ fprintf(stderr, "%s: failed to find dir %s on %s\n",
119+ program, subdir, device);
120+ goto fail;
121+ }
122+
123+ retval = ext2fs_check_directory(e2fs, dirino);
124+ if (retval) {
125+ fprintf(stderr, "%s: failed to cd to: %s\n", program, subdir);
126+ goto fail;
127+ }
128+ cwd = dirino;
129+ }
130+
131+ return 0;
132+
133+fail:
134+ (void) ext2fs_close(e2fs);
135+ return -1;
136 }
137
138 /* The install func for ext2, ext3 and ext4 */
139--
1401.9.1
141
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 @@
1From 64d856b243812907068776b204a003a3a8fa122a Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Wed, 31 Dec 2014 16:17:42 +0800
4Subject: [PATCH 3/9] linux/syslinux: implement install_to_ext2()
5
6* The handle_adv_on_ext() checks whether we only need update adv.
7* The write_to_ext() installs files (ldlinux.sys or ldlinux.c32) to the
8 device.
9* The install_bootblock() installs the boot block.
10
11Upstream-Status: Submitted
12
13Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
14Tested-by: Du Dolpher <dolpher.du@intel.com>
15---
16 linux/syslinux.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
17 1 file changed, 79 insertions(+)
18
19diff --git a/linux/syslinux.c b/linux/syslinux.c
20index cc4e7da..45f080d 100755
21--- a/linux/syslinux.c
22+++ b/linux/syslinux.c
23@@ -346,11 +346,90 @@ static int open_ext2_fs(const char *device, const char *subdir)
24 fail:
25 (void) ext2fs_close(e2fs);
26 return -1;
27+
28+}
29+
30+/*
31+ * Install the boot block on the specified device.
32+ * Must be run AFTER file installed.
33+ */
34+int install_bootblock(int fd, const char *device)
35+{
36+}
37+
38+static int handle_adv_on_ext(void)
39+{
40+}
41+
42+/* Write files, adv, boot sector */
43+static int write_to_ext(const char *filename, const char *str, int length,
44+ int i_flags, int dev_fd, const char *subdir)
45+{
46 }
47
48 /* The install func for ext2, ext3 and ext4 */
49 static int install_to_ext2(const char *device, int dev_fd, const char *subdir)
50 {
51+ int retval;
52+ ext2_ino_t oldino;
53+
54+ const char *file = "ldlinux.sys";
55+ const char *oldfile = "extlinux.sys";
56+ const char *c32file = "ldlinux.c32";
57+
58+ /* Handle the adv */
59+ if (handle_adv_on_ext() < 0) {
60+ fprintf(stderr, "%s: error while handling ADV on %s\n",
61+ program, device);
62+ retval = 1;
63+ goto fail;
64+ }
65+
66+ /* Return if only need update the adv */
67+ if (opt.update_only == -1) {
68+ return ext2fs_close(e2fs);
69+ }
70+
71+ /* Write ldlinux.sys, adv, boot sector */
72+ retval = write_to_ext(file, (const char _force *)boot_image,
73+ boot_image_len, EXT2_IMMUTABLE_FL, dev_fd, subdir);
74+ if (retval) {
75+ fprintf(stderr, "%s: ERROR: while writing: %s.\n",
76+ program, file);
77+ goto fail;
78+ }
79+
80+ /* Write ldlinux.c32 */
81+ retval = write_to_ext(c32file,
82+ (const char _force *)syslinux_ldlinuxc32,
83+ syslinux_ldlinuxc32_len, 0, dev_fd, subdir);
84+ if (retval) {
85+ fprintf(stderr, "%s: ERROR: while writing: %s.\n",
86+ program, c32file);
87+ goto fail;
88+ }
89+
90+ /* Look if we have the extlinux.sys and remove it*/
91+ retval = ext2fs_namei(e2fs, root, cwd, oldfile, &oldino);
92+ if (retval == 0) {
93+ retval = ext2fs_unlink(e2fs, cwd, oldfile, oldino, 0);
94+ if (retval) {
95+ fprintf(stderr, "%s: ERROR: failed to unlink: %s\n",
96+ program, oldfile);
97+ goto fail;
98+ }
99+ } else {
100+ retval = 0;
101+ }
102+
103+ sync();
104+ retval = install_bootblock(dev_fd, device);
105+ close(dev_fd);
106+ sync();
107+
108+fail:
109+ (void) ext2fs_close(e2fs);
110+ return retval;
111 }
112
113 int main(int argc, char *argv[])
114--
1151.9.1
116
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 @@
1From 35d3842cc4b930c5102eed2921e0189b7f4fd069 Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Wed, 31 Dec 2014 16:43:37 +0800
4Subject: [PATCH 4/9] linux/syslinux: add ext_file_read() and ext_file_write()
5
6Will use them to read and write on the extX device.
7
8Upstream-Status: Submitted
9
10Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
11Tested-by: Du Dolpher <dolpher.du@intel.com>
12---
13 linux/syslinux.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14 1 file changed, 62 insertions(+)
15
16diff --git a/linux/syslinux.c b/linux/syslinux.c
17index 45f080d..247c86a 100755
18--- a/linux/syslinux.c
19+++ b/linux/syslinux.c
20@@ -349,6 +349,68 @@ fail:
21
22 }
23
24+/* Read from an ext2_file */
25+static int ext_file_read(ext2_file_t e2_file, void *buf, size_t count,
26+ off_t offset, const char *msg)
27+{
28+ int retval;
29+ char *ptr = (char *) buf;
30+ unsigned int got = 0;
31+ size_t done = 0;
32+
33+ /* Always lseek since e2_file is uncontrolled by this func */
34+ if (ext2fs_file_lseek(e2_file, offset, EXT2_SEEK_SET, NULL)) {
35+ fprintf(stderr, "%s: ext2fs_file_lseek() failed.\n",
36+ program);
37+ return -1;
38+ }
39+
40+ while (1) {
41+ retval = ext2fs_file_read(e2_file, ptr, count, &got);
42+ if (retval) {
43+ fprintf(stderr, "%s: error while reading %s\n",
44+ program, msg);
45+ return -1;
46+ }
47+ count -= got;
48+ ptr += got;
49+ done += got;
50+ if (got == 0 || count == 0)
51+ break;
52+ }
53+
54+ return done;
55+}
56+
57+/* Write to an ext2_file */
58+static int ext_file_write(ext2_file_t e2_file, const void *buf, size_t count,
59+ off_t offset)
60+{
61+ const char *ptr = (const char *) buf;
62+ unsigned int written = 0;
63+ size_t done = 0;
64+
65+ /* Always lseek since e2_file is uncontrolled by this func */
66+ if (ext2fs_file_lseek(e2_file, offset, EXT2_SEEK_SET, NULL)) {
67+ fprintf(stderr, "%s: ext2fs_file_lseek() failed.\n",
68+ program);
69+ return -1;
70+ }
71+
72+ while (count > 0) {
73+ if (ext2fs_file_write(e2_file, ptr, count, &written)) {
74+ fprintf(stderr, "%s: failed to write syslinux adv.\n",
75+ program);
76+ return -1;
77+ }
78+ count -= written;
79+ ptr += written;
80+ done += written;
81+ }
82+
83+ return done;
84+}
85+
86 /*
87 * Install the boot block on the specified device.
88 * Must be run AFTER file installed.
89--
901.9.1
91
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 @@
1From cdb980b37f40dc2c41891434c7736e49da53756e Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Wed, 31 Dec 2014 16:47:52 +0800
4Subject: [PATCH 5/9] linux/syslinux: implement handle_adv_on_ext()
5
6It reads adv if found on the device, or resets syslinux_adv, or update
7the adv if update adv only.
8
9Upstream-Status: Submitted
10
11Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
12Tested-by: Du Dolpher <dolpher.du@intel.com>
13---
14 linux/syslinux.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15 1 file changed, 97 insertions(+)
16
17diff --git a/linux/syslinux.c b/linux/syslinux.c
18index 247c86a..de5d272 100755
19--- a/linux/syslinux.c
20+++ b/linux/syslinux.c
21@@ -421,6 +421,103 @@ int install_bootblock(int fd, const char *device)
22
23 static int handle_adv_on_ext(void)
24 {
25+ int i, retval, found_file;
26+ int need_close = 2; /* 2 means no need extra close */
27+ char *filenames[2] = {"ldlinux.sys", "extlinux.sys"};
28+ char *filename;
29+ ext2_ino_t newino;
30+ ext2_file_t e2_file;
31+ struct ext2_inode inode;
32+
33+ for (i = 0; i < 2; i++) {
34+ filename = filenames[i];
35+ found_file = 0;
36+ retval = ext2fs_namei(e2fs, root, cwd, filename, &newino);
37+ if (retval == 0) {
38+ found_file = 1;
39+ } else
40+ continue;
41+
42+ need_close = i;
43+
44+ retval = ext2fs_file_open(e2fs, newino, EXT2_FLAG_RW, &e2_file);
45+ if (retval) {
46+ fprintf(stderr, "%s: failed to open %s\n",
47+ program, filename);
48+ goto fail;
49+ }
50+
51+ retval = ext2fs_read_inode(e2fs, newino, &inode);
52+ if (retval) {
53+ fprintf(stderr, "%s: error while reading inode: %u, file: %s\n",
54+ program, newino, filename);
55+ goto fail;
56+ }
57+
58+ /* Check the size to see if too small to read */
59+ if (inode.i_size < 2 * ADV_SIZE) {
60+ if (opt.update_only == -1) {
61+ fprintf(stderr, "%s: failed to write auxilliary data\n\
62+ the size of %s is too small (need --update)?\n",
63+ program, filename);
64+ retval = -1;
65+ goto fail;
66+ }
67+ syslinux_reset_adv(syslinux_adv);
68+ found_file = 0;
69+ break;
70+ }
71+
72+ /* Read the adv */
73+ retval = ext_file_read(e2_file, syslinux_adv, 2 * ADV_SIZE,
74+ inode.i_size - 2 * ADV_SIZE, "ADV");
75+ if (retval == -1)
76+ goto fail;
77+ if (retval == 2 * ADV_SIZE) {
78+ retval = syslinux_validate_adv(syslinux_adv);
79+ /* Read the adv successfully */
80+ if (retval == 0)
81+ break;
82+ }
83+
84+ /* Close the file if reaches here, otherwise we leave the file
85+ * open in case we need write it */
86+ need_close = 2;
87+ retval = ext2fs_file_close(e2_file);
88+ if (retval) {
89+ fprintf(stderr, "%s: error while closing %s\n",
90+ program, filename);
91+ return retval;
92+ }
93+ }
94+
95+ if (!found_file) {
96+ if (opt.update_only == -1) {
97+ fprintf(stderr, "%s: no ldlinux.sys or extlinux.sys found on the device\n",
98+ program);
99+ return -1;
100+ }
101+ syslinux_reset_adv(syslinux_adv);
102+ }
103+
104+ /* The modify_adv will reset the adv if opt.reset_adv */
105+ if (modify_adv() < 0) {
106+ fprintf(stderr, "%s: error while modifying adv\n", program);
107+ retval = -1;
108+ goto fail;
109+ }
110+
111+ /* Write adv if update_only == -1 and found file */
112+ if (opt.update_only == -1 && found_file) {
113+ if (ext_file_write(e2_file, syslinux_adv, 2 * ADV_SIZE ,
114+ inode.i_size - 2 * ADV_SIZE) == -1)
115+ goto fail;
116+ }
117+
118+fail:
119+ if (need_close != 2)
120+ (void) ext2fs_file_close(e2_file);
121+ return retval;
122 }
123
124 /* Write files, adv, boot sector */
125--
1261.9.1
127
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 @@
1From 922e56c10e36d876777580c84daef9a66bea6525 Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Wed, 31 Dec 2014 17:20:43 +0800
4Subject: [PATCH 6/9] linux/syslinux: implement write_to_ext() and add
5 syslinuxext.c
6
7* The write_to_ext() write file to the extX device, and handle the boot
8 sector.
9* The syslinuxext.c is used for placing the code which are used by
10 extlinux and syslinux (which is syslinux_patch_bootsect()).
11
12Upstream-Status: Submitted
13
14Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
15Tested-by: Du Dolpher <dolpher.du@intel.com>
16---
17 libinstaller/syslinuxext.c | 7 +++
18 libinstaller/syslinuxext.h | 5 ++
19 linux/Makefile | 3 +-
20 linux/syslinux.c | 118 +++++++++++++++++++++++++++++++++++++++++++++
21 4 files changed, 132 insertions(+), 1 deletion(-)
22 create mode 100644 libinstaller/syslinuxext.c
23 create mode 100644 libinstaller/syslinuxext.h
24
25diff --git a/libinstaller/syslinuxext.c b/libinstaller/syslinuxext.c
26new file mode 100644
27index 0000000..bb54cef
28--- /dev/null
29+++ b/libinstaller/syslinuxext.c
30@@ -0,0 +1,7 @@
31+#define _GNU_SOURCE
32+
33+/* Patch syslinux_bootsect */
34+void syslinux_patch_bootsect(int dev_fd)
35+{
36+}
37+
38diff --git a/libinstaller/syslinuxext.h b/libinstaller/syslinuxext.h
39new file mode 100644
40index 0000000..8abd8b9
41--- /dev/null
42+++ b/libinstaller/syslinuxext.h
43@@ -0,0 +1,5 @@
44+#ifndef EXT2_SUPER_OFFSET
45+#define EXT2_SUPER_OFFSET 1024
46+#endif
47+
48+void syslinux_patch_bootsect(int dev_fd);
49diff --git a/linux/Makefile b/linux/Makefile
50index ac1ac58..3b23867 100644
51--- a/linux/Makefile
52+++ b/linux/Makefile
53@@ -30,7 +30,8 @@ SRCS = syslinux.c \
54 ../libinstaller/syslxmod.c \
55 ../libinstaller/bootsect_bin.c \
56 ../libinstaller/ldlinuxc32_bin.c \
57- ../libinstaller/ldlinux_bin.c
58+ ../libinstaller/ldlinux_bin.c \
59+ ../libinstaller/syslinuxext.c
60 OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
61
62 .SUFFIXES: .c .o .i .s .S
63diff --git a/linux/syslinux.c b/linux/syslinux.c
64index de5d272..f0c97a8 100755
65--- a/linux/syslinux.c
66+++ b/linux/syslinux.c
67@@ -46,6 +46,7 @@
68 #include <sys/types.h>
69 #include <sys/wait.h>
70 #include <sys/mount.h>
71+#include <time.h>
72
73 #include "linuxioctl.h"
74
75@@ -72,6 +73,7 @@
76 #include "syslxfs.h"
77 #include "setadv.h"
78 #include "syslxopt.h" /* unified options */
79+#include "syslinuxext.h"
80 #include <ext2fs/ext2fs.h>
81
82 extern const char *program; /* Name of program */
83@@ -419,6 +421,12 @@ int install_bootblock(int fd, const char *device)
84 {
85 }
86
87+/* Construct the boot file map */
88+int ext_construct_sectmap_fs(ext2_filsys fs, ext2_ino_t newino,
89+ sector_t *sectors, int nsect)
90+{
91+}
92+
93 static int handle_adv_on_ext(void)
94 {
95 int i, retval, found_file;
96@@ -524,6 +532,116 @@ fail:
97 static int write_to_ext(const char *filename, const char *str, int length,
98 int i_flags, int dev_fd, const char *subdir)
99 {
100+ ext2_ino_t newino;
101+ struct ext2_inode inode;
102+ int retval, i, modbytes, nsect;
103+ ext2_file_t e2_file;
104+ sector_t *sectors;
105+
106+ /* Remove it if it is already exists */
107+ retval = ext2fs_namei(e2fs, root, cwd, filename, &newino);
108+ if (retval == 0) {
109+ retval = ext2fs_unlink(e2fs, cwd, filename, newino, 0);
110+ if (retval) {
111+ fprintf(stderr, "%s: failed to unlink: %s\n", program, filename);
112+ return retval;
113+ }
114+ }
115+
116+ /* Create new inode */
117+ retval = ext2fs_new_inode(e2fs, cwd, 010755, 0, &newino);
118+ if (retval) {
119+ fprintf(stderr, "%s: ERROR: failed to create inode for: %s\n",
120+ program, filename);
121+ return retval;
122+ }
123+
124+ /* Link the inode and the filename */
125+ retval = ext2fs_link(e2fs, cwd, filename, newino, EXT2_FT_REG_FILE);
126+ if (retval) {
127+ fprintf(stderr, "%s: ERROR: failed to link inode for: %s.\n",
128+ program, filename);
129+ return retval;
130+ }
131+
132+ if (ext2fs_test_inode_bitmap2(e2fs->inode_map, newino))
133+ fprintf(stderr, "%s: warning: inode already set %s.\n",
134+ program, filename);
135+
136+ ext2fs_inode_alloc_stats2(e2fs, newino, +1, 0);
137+ memset(&inode, 0, sizeof(inode));
138+ inode.i_mode = LINUX_S_IFREG | LINUX_S_IRUSR | LINUX_S_IRGRP
139+ | LINUX_S_IROTH;
140+ inode.i_flags |= i_flags;
141+ inode.i_atime = inode.i_ctime = inode.i_mtime =
142+ e2fs->now ? e2fs->now : time(0);
143+ inode.i_links_count = 1;
144+ if (e2fs->super->s_feature_incompat &
145+ EXT3_FEATURE_INCOMPAT_EXTENTS) {
146+ struct ext3_extent_header *eh;
147+
148+ eh = (struct ext3_extent_header *) &inode.i_block[0];
149+ eh->eh_depth = 0;
150+ eh->eh_entries = 0;
151+ eh->eh_magic = ext2fs_cpu_to_le16(EXT3_EXT_MAGIC);
152+ i = (sizeof(inode.i_block) - sizeof(*eh)) /
153+ sizeof(struct ext3_extent);
154+ eh->eh_max = ext2fs_cpu_to_le16(i);
155+ inode.i_flags |= EXT4_EXTENTS_FL;
156+ }
157+
158+ retval = ext2fs_write_new_inode(e2fs, newino, &inode);
159+ if (retval) {
160+ fprintf(stderr, "%s: ERROR: while writting inode %d.\n",
161+ program, newino);
162+ return 1;
163+ }
164+
165+ retval = ext2fs_file_open(e2fs, newino, EXT2_FILE_WRITE, &e2_file);
166+ if (retval) {
167+ fprintf(stderr, "%s: ERROR: failed to open %s.\n",
168+ program, filename);
169+ return 1;
170+ }
171+
172+ /* Write to file */
173+ if (ext_file_write(e2_file, str, length, 0) == -1)
174+ goto fail;
175+
176+ if (strcmp(filename, "ldlinux.sys") == 0) {
177+ /* Write ADV */
178+ if (ext_file_write(e2_file, syslinux_adv, 2 * ADV_SIZE,
179+ boot_image_len) == -1)
180+ goto fail;
181+
182+ /* Patch syslinux_bootsect */
183+ syslinux_patch_bootsect(dev_fd);
184+
185+ /* Patch ldlinux.sys */
186+ nsect = (boot_image_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
187+ nsect += 2; /* Two sectors for the ADV */
188+ sectors = alloca(sizeof(sector_t) * nsect);
189+ memset(sectors, 0, nsect * sizeof *sectors);
190+ /* The sectors will be modified and used by syslinux_patch() */
191+ retval = ext_construct_sectmap_fs(e2fs, newino, sectors, nsect);
192+ if (retval)
193+ goto fail;
194+
195+ /* Create the modified image in memory */
196+ modbytes = syslinux_patch(sectors, nsect, opt.stupid_mode,
197+ opt.raid_mode, subdir, NULL);
198+
199+ /* Rewrite the first modbytes of ldlinux.sys */
200+ if (ext_file_write(e2_file, str, modbytes, 0) == -1) {
201+ fprintf(stderr, "%s: ERROR: failed to patch %s.\n", program,
202+ filename);
203+ goto fail;
204+ }
205+ }
206+
207+fail:
208+ (void) ext2fs_file_close(e2_file);
209+ return retval;
210 }
211
212 /* The install func for ext2, ext3 and ext4 */
213--
2141.9.1
215
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 @@
1From a95b831e18dd123f859bc5e6c4cecdcc0184ee37 Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Fri, 2 Jan 2015 12:18:02 +0800
4Subject: [PATCH 7/9] linux/syslinux: implement ext_construct_sectmap_fs()
5
6The ext_construct_sectmap_fs() constucts the sector according to the
7bmap.
8
9Upstream-Status: Submitted
10
11Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
12Tested-by: Du Dolpher <dolpher.du@intel.com>
13---
14 linux/syslinux.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
15 1 file changed, 50 insertions(+)
16
17diff --git a/linux/syslinux.c b/linux/syslinux.c
18index f0c97a8..c741750 100755
19--- a/linux/syslinux.c
20+++ b/linux/syslinux.c
21@@ -421,10 +421,60 @@ int install_bootblock(int fd, const char *device)
22 {
23 }
24
25+/* The file's block count */
26+int block_count = 0;
27+static int get_block_count(ext2_filsys fs EXT2FS_ATTR((unused)),
28+ blk64_t *blocknr EXT2FS_ATTR((unused)),
29+ e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
30+ blk64_t ref_block EXT2FS_ATTR((unused)),
31+ int ref_offset EXT2FS_ATTR((unused)),
32+ void *private EXT2FS_ATTR((unused)))
33+{
34+ block_count++;
35+ return 0;
36+}
37+
38 /* Construct the boot file map */
39 int ext_construct_sectmap_fs(ext2_filsys fs, ext2_ino_t newino,
40 sector_t *sectors, int nsect)
41 {
42+ blk64_t pblk, blksize, blk = 0;
43+ sector_t sec;
44+ unsigned int i;
45+ int retval;
46+
47+ blksize = fs->blocksize;
48+ blksize >>= SECTOR_SHIFT;
49+
50+ /* Get the total blocks no. */
51+ retval = ext2fs_block_iterate3(fs, newino, BLOCK_FLAG_READ_ONLY,
52+ NULL, get_block_count, NULL);
53+ if (retval) {
54+ fprintf(stderr, "%s: ERROR: ext2fs_block_iterate3() failed.\n", program);
55+ return -1;
56+ }
57+
58+ while (nsect) {
59+ if (block_count-- == 0)
60+ break;
61+
62+ /* Get the physical block no. (bmap) */
63+ retval = ext2fs_bmap2(fs, newino, 0, 0, 0, blk, 0, &pblk);
64+ if (retval) {
65+ fprintf(stderr, "%s: ERROR: ext2fs_bmap2() failed.\n", program);
66+ return -1;
67+ }
68+
69+ blk++;
70+ sec = (sector_t)pblk * blksize;
71+ for (i = 0; i < blksize; i++) {
72+ *sectors++ = sec++;
73+ if (! --nsect)
74+ break;
75+ }
76+ }
77+
78+ return 0;
79 }
80
81 static int handle_adv_on_ext(void)
82--
831.9.1
84
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 @@
1From 78d76b87a4b855e6b661ae457283a63f385c04c9 Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Fri, 2 Jan 2015 12:26:46 +0800
4Subject: [PATCH 8/9] libinstaller/syslinuxext: implement
5 syslinux_patch_bootsect()
6
7Move the related from extlinux/main.c to libinstaller/syslinuxext.c, the
8syslinux_patch_bootsect() are used by both extlinux/main.c and
9linux/syslinux.c.
10
11Upstream-Status: Submitted
12
13Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
14Tested-by: Du Dolpher <dolpher.du@intel.com>
15---
16 extlinux/Makefile | 3 +-
17 extlinux/main.c | 167 +-------------------------------------------
18 libinstaller/syslinuxext.c | 170 +++++++++++++++++++++++++++++++++++++++++++++
19 3 files changed, 175 insertions(+), 165 deletions(-)
20
21diff --git a/extlinux/Makefile b/extlinux/Makefile
22index 02d1db5..90dd92f 100644
23--- a/extlinux/Makefile
24+++ b/extlinux/Makefile
25@@ -31,7 +31,8 @@ SRCS = main.c \
26 ../libinstaller/advio.c \
27 ../libinstaller/bootsect_bin.c \
28 ../libinstaller/ldlinuxc32_bin.c \
29- ../libinstaller/ldlinux_bin.c
30+ ../libinstaller/ldlinux_bin.c \
31+ ../libinstaller/syslinuxext.c
32 OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
33
34 .SUFFIXES: .c .o .i .s .S
35diff --git a/extlinux/main.c b/extlinux/main.c
36index 09740bd..6fe026e 100644
37--- a/extlinux/main.c
38+++ b/extlinux/main.c
39@@ -60,6 +60,7 @@
40 #include "setadv.h"
41 #include "syslxopt.h" /* unified options */
42 #include "mountinfo.h"
43+#include "syslinuxext.h"
44
45 #ifdef DEBUG
46 # define dprintf printf
47@@ -67,10 +68,6 @@
48 # define dprintf(...) ((void)0)
49 #endif
50
51-#ifndef EXT2_SUPER_OFFSET
52-#define EXT2_SUPER_OFFSET 1024
53-#endif
54-
55 /* Since we have unused 2048 bytes in the primary AG of an XFS partition,
56 * we will use the first 0~512 bytes starting from 2048 for the Syslinux
57 * boot sector.
58@@ -92,136 +89,6 @@ static char subvol[BTRFS_SUBVOL_MAX];
59 - 2*ADV_SIZE)
60
61 /*
62- * Get the size of a block device
63- */
64-static uint64_t get_size(int devfd)
65-{
66- uint64_t bytes;
67- uint32_t sects;
68- struct stat st;
69-
70-#ifdef BLKGETSIZE64
71- if (!ioctl(devfd, BLKGETSIZE64, &bytes))
72- return bytes;
73-#endif
74- if (!ioctl(devfd, BLKGETSIZE, &sects))
75- return (uint64_t) sects << 9;
76- else if (!fstat(devfd, &st) && st.st_size)
77- return st.st_size;
78- else
79- return 0;
80-}
81-
82-/*
83- * Get device geometry and partition offset
84- */
85-struct geometry_table {
86- uint64_t bytes;
87- struct hd_geometry g;
88-};
89-
90-static int sysfs_get_offset(int devfd, unsigned long *start)
91-{
92- struct stat st;
93- char sysfs_name[128];
94- FILE *f;
95- int rv;
96-
97- if (fstat(devfd, &st))
98- return -1;
99-
100- if ((size_t)snprintf(sysfs_name, sizeof sysfs_name,
101- "/sys/dev/block/%u:%u/start",
102- major(st.st_rdev), minor(st.st_rdev))
103- >= sizeof sysfs_name)
104- return -1;
105-
106- f = fopen(sysfs_name, "r");
107- if (!f)
108- return -1;
109-
110- rv = fscanf(f, "%lu", start);
111- fclose(f);
112-
113- return (rv == 1) ? 0 : -1;
114-}
115-
116-/* Standard floppy disk geometries, plus LS-120. Zipdisk geometry
117- (x/64/32) is the final fallback. I don't know what LS-240 has
118- as its geometry, since I don't have one and don't know anyone that does,
119- and Google wasn't helpful... */
120-static const struct geometry_table standard_geometries[] = {
121- {360 * 1024, {2, 9, 40, 0}},
122- {720 * 1024, {2, 9, 80, 0}},
123- {1200 * 1024, {2, 15, 80, 0}},
124- {1440 * 1024, {2, 18, 80, 0}},
125- {1680 * 1024, {2, 21, 80, 0}},
126- {1722 * 1024, {2, 21, 80, 0}},
127- {2880 * 1024, {2, 36, 80, 0}},
128- {3840 * 1024, {2, 48, 80, 0}},
129- {123264 * 1024, {8, 32, 963, 0}}, /* LS120 */
130- {0, {0, 0, 0, 0}}
131-};
132-
133-int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
134-{
135- struct floppy_struct fd_str;
136- struct loop_info li;
137- struct loop_info64 li64;
138- const struct geometry_table *gp;
139- int rv = 0;
140-
141- memset(geo, 0, sizeof *geo);
142-
143- if (!ioctl(devfd, HDIO_GETGEO, geo)) {
144- goto ok;
145- } else if (!ioctl(devfd, FDGETPRM, &fd_str)) {
146- geo->heads = fd_str.head;
147- geo->sectors = fd_str.sect;
148- geo->cylinders = fd_str.track;
149- geo->start = 0;
150- goto ok;
151- }
152-
153- /* Didn't work. Let's see if this is one of the standard geometries */
154- for (gp = standard_geometries; gp->bytes; gp++) {
155- if (gp->bytes == totalbytes) {
156- memcpy(geo, &gp->g, sizeof *geo);
157- goto ok;
158- }
159- }
160-
161- /* Didn't work either... assign a geometry of 64 heads, 32 sectors; this is
162- what zipdisks use, so this would help if someone has a USB key that
163- they're booting in USB-ZIP mode. */
164-
165- geo->heads = opt.heads ? : 64;
166- geo->sectors = opt.sectors ? : 32;
167- geo->cylinders = totalbytes / (geo->heads * geo->sectors << SECTOR_SHIFT);
168- geo->start = 0;
169-
170- if (!opt.sectors && !opt.heads) {
171- fprintf(stderr,
172- "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n"
173- " (on hard disks, this is usually harmless.)\n",
174- geo->heads, geo->sectors);
175- rv = 1; /* Suboptimal result */
176- }
177-
178-ok:
179- /* If this is a loopback device, try to set the start */
180- if (!ioctl(devfd, LOOP_GET_STATUS64, &li64))
181- geo->start = li64.lo_offset >> SECTOR_SHIFT;
182- else if (!ioctl(devfd, LOOP_GET_STATUS, &li))
183- geo->start = (unsigned int)li.lo_offset >> SECTOR_SHIFT;
184- else if (!sysfs_get_offset(devfd, &geo->start)) {
185- /* OK */
186- }
187-
188- return rv;
189-}
190-
191-/*
192 * Query the device geometry and put it into the boot sector.
193 * Map the file and put the map in the boot sector and file.
194 * Stick the "current directory" inode number into the file.
195@@ -231,11 +98,8 @@ ok:
196 static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
197 {
198 struct stat dirst, xdst;
199- struct hd_geometry geo;
200 sector_t *sectp;
201- uint64_t totalbytes, totalsectors;
202 int nsect;
203- struct fat_boot_sector *sbs;
204 char *dirpath, *subpath, *xdirpath;
205 int rv;
206
207@@ -279,33 +143,8 @@ static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
208 /* Now subpath should contain the path relative to the fs base */
209 dprintf("subpath = %s\n", subpath);
210
211- totalbytes = get_size(devfd);
212- get_geometry(devfd, totalbytes, &geo);
213-
214- if (opt.heads)
215- geo.heads = opt.heads;
216- if (opt.sectors)
217- geo.sectors = opt.sectors;
218-
219- /* Patch this into a fake FAT superblock. This isn't because
220- FAT is a good format in any way, it's because it lets the
221- early bootstrap share code with the FAT version. */
222- dprintf("heads = %u, sect = %u\n", geo.heads, geo.sectors);
223-
224- sbs = (struct fat_boot_sector *)syslinux_bootsect;
225-
226- totalsectors = totalbytes >> SECTOR_SHIFT;
227- if (totalsectors >= 65536) {
228- set_16(&sbs->bsSectors, 0);
229- } else {
230- set_16(&sbs->bsSectors, totalsectors);
231- }
232- set_32(&sbs->bsHugeSectors, totalsectors);
233-
234- set_16(&sbs->bsBytesPerSec, SECTOR_SIZE);
235- set_16(&sbs->bsSecPerTrack, geo.sectors);
236- set_16(&sbs->bsHeads, geo.heads);
237- set_32(&sbs->bsHiddenSecs, geo.start);
238+ /* Patch syslinux_bootsect */
239+ syslinux_patch_bootsect(devfd);
240
241 /* Construct the boot file map */
242
243diff --git a/libinstaller/syslinuxext.c b/libinstaller/syslinuxext.c
244index bb54cef..5a4423b 100644
245--- a/libinstaller/syslinuxext.c
246+++ b/libinstaller/syslinuxext.c
247@@ -1,7 +1,177 @@
248 #define _GNU_SOURCE
249
250+#include <sys/stat.h>
251+#include <sys/types.h>
252+#include <getopt.h>
253+#include <ext2fs/ext2fs.h>
254+
255+#include "linuxioctl.h"
256+#include "syslinux.h"
257+#include "syslxint.h"
258+#include "syslxopt.h"
259+
260+/*
261+ * Get the size of a block device
262+ */
263+static uint64_t get_size(int dev_fd)
264+{
265+ uint64_t bytes;
266+ uint32_t sects;
267+ struct stat st;
268+
269+#ifdef BLKGETSIZE64
270+ if (!ioctl(dev_fd, BLKGETSIZE64, &bytes))
271+ return bytes;
272+#endif
273+ if (!ioctl(dev_fd, BLKGETSIZE, &sects))
274+ return (uint64_t) sects << 9;
275+ else if (!fstat(dev_fd, &st) && st.st_size)
276+ return st.st_size;
277+ else
278+ return 0;
279+}
280+
281+/*
282+ * Get device geometry and partition offset
283+ */
284+static struct geometry_table {
285+ uint64_t bytes;
286+ struct hd_geometry g;
287+};
288+
289+static int sysfs_get_offset(int dev_fd, unsigned long *start)
290+{
291+ struct stat st;
292+ char sysfs_name[128];
293+ FILE *f;
294+ int rv;
295+
296+ if (fstat(dev_fd, &st))
297+ return -1;
298+
299+ if ((size_t)snprintf(sysfs_name, sizeof sysfs_name,
300+ "/sys/dev/block/%u:%u/start",
301+ major(st.st_rdev), minor(st.st_rdev))
302+ >= sizeof sysfs_name)
303+ return -1;
304+
305+ f = fopen(sysfs_name, "r");
306+ if (!f)
307+ return -1;
308+
309+ rv = fscanf(f, "%lu", start);
310+ fclose(f);
311+
312+ return (rv == 1) ? 0 : -1;
313+}
314+
315+/* Standard floppy disk geometries, plus LS-120. Zipdisk geometry
316+ (x/64/32) is the final fallback. I don't know what LS-240 has
317+ as its geometry, since I don't have one and don't know anyone that does,
318+ and Google wasn't helpful... */
319+static const struct geometry_table standard_geometries[] = {
320+ {360 * 1024, {2, 9, 40, 0}},
321+ {720 * 1024, {2, 9, 80, 0}},
322+ {1200 * 1024, {2, 15, 80, 0}},
323+ {1440 * 1024, {2, 18, 80, 0}},
324+ {1680 * 1024, {2, 21, 80, 0}},
325+ {1722 * 1024, {2, 21, 80, 0}},
326+ {2880 * 1024, {2, 36, 80, 0}},
327+ {3840 * 1024, {2, 48, 80, 0}},
328+ {123264 * 1024, {8, 32, 963, 0}}, /* LS120 */
329+ {0, {0, 0, 0, 0}}
330+};
331+
332+static int get_geometry(int dev_fd, uint64_t totalbytes, struct hd_geometry *geo)
333+{
334+ struct floppy_struct fd_str;
335+ struct loop_info li;
336+ struct loop_info64 li64;
337+ const struct geometry_table *gp;
338+ int rv = 0;
339+
340+ memset(geo, 0, sizeof *geo);
341+
342+ if (!ioctl(dev_fd, HDIO_GETGEO, geo)) {
343+ goto ok;
344+ } else if (!ioctl(dev_fd, FDGETPRM, &fd_str)) {
345+ geo->heads = fd_str.head;
346+ geo->sectors = fd_str.sect;
347+ geo->cylinders = fd_str.track;
348+ geo->start = 0;
349+ goto ok;
350+ }
351+
352+ /* Didn't work. Let's see if this is one of the standard geometries */
353+ for (gp = standard_geometries; gp->bytes; gp++) {
354+ if (gp->bytes == totalbytes) {
355+ memcpy(geo, &gp->g, sizeof *geo);
356+ goto ok;
357+ }
358+ }
359+
360+ /* Didn't work either... assign a geometry of 64 heads, 32 sectors; this is
361+ what zipdisks use, so this would help if someone has a USB key that
362+ they're booting in USB-ZIP mode. */
363+
364+ geo->heads = opt.heads ? : 64;
365+ geo->sectors = opt.sectors ? : 32;
366+ geo->cylinders = totalbytes / (geo->heads * geo->sectors << SECTOR_SHIFT);
367+ geo->start = 0;
368+
369+ if (!opt.sectors && !opt.heads) {
370+ fprintf(stderr,
371+ "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n"
372+ " (on hard disks, this is usually harmless.)\n",
373+ geo->heads, geo->sectors);
374+ rv = 1; /* Suboptimal result */
375+ }
376+
377+ok:
378+ /* If this is a loopback device, try to set the start */
379+ if (!ioctl(dev_fd, LOOP_GET_STATUS64, &li64))
380+ geo->start = li64.lo_offset >> SECTOR_SHIFT;
381+ else if (!ioctl(dev_fd, LOOP_GET_STATUS, &li))
382+ geo->start = (unsigned int)li.lo_offset >> SECTOR_SHIFT;
383+ else if (!sysfs_get_offset(dev_fd, &geo->start)) {
384+ /* OK */
385+ }
386+
387+ return rv;
388+}
389+
390+
391 /* Patch syslinux_bootsect */
392 void syslinux_patch_bootsect(int dev_fd)
393 {
394+ uint64_t totalbytes, totalsectors;
395+ struct hd_geometry geo;
396+ struct fat_boot_sector *sbs;
397+
398+ totalbytes = get_size(dev_fd);
399+ get_geometry(dev_fd, totalbytes, &geo);
400+
401+ if (opt.heads)
402+ geo.heads = opt.heads;
403+ if (opt.sectors)
404+ geo.sectors = opt.sectors;
405+
406+ /* Patch this into a fake FAT superblock. This isn't because
407+ FAT is a good format in any way, it's because it lets the
408+ early bootstrap share code with the FAT version. */
409+ sbs = (struct fat_boot_sector *)syslinux_bootsect;
410+
411+ totalsectors = totalbytes >> SECTOR_SHIFT;
412+ if (totalsectors >= 65536) {
413+ set_16(&sbs->bsSectors, 0);
414+ } else {
415+ set_16(&sbs->bsSectors, totalsectors);
416+ }
417+ set_32(&sbs->bsHugeSectors, totalsectors);
418+
419+ set_16(&sbs->bsBytesPerSec, SECTOR_SIZE);
420+ set_16(&sbs->bsSecPerTrack, geo.sectors);
421+ set_16(&sbs->bsHeads, geo.heads);
422+ set_32(&sbs->bsHiddenSecs, geo.start);
423 }
424
425--
4261.9.1
427
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 @@
1From 76c465e87312dbc6cffd05427f1f4d2ebdee4f13 Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Fri, 2 Jan 2015 12:28:35 +0800
4Subject: [PATCH 9/9] linux/syslinux: implement install_bootblock()
5
6Refer to the install_bootblock() in extlinux/main.c to make
7linux/syslinux.c's install_bootblock() which only supports ext2/3/4.
8
9Upstream-Status: Submitted
10
11Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
12Tested-by: Du Dolpher <dolpher.du@intel.com>
13---
14 linux/syslinux.c | 20 ++++++++++++++++++++
15 1 file changed, 20 insertions(+)
16
17diff --git a/linux/syslinux.c b/linux/syslinux.c
18index c741750..917f83a 100755
19--- a/linux/syslinux.c
20+++ b/linux/syslinux.c
21@@ -419,6 +419,26 @@ static int ext_file_write(ext2_file_t e2_file, const void *buf, size_t count,
22 */
23 int install_bootblock(int fd, const char *device)
24 {
25+ struct ext2_super_block sb;
26+
27+ if (xpread(fd, &sb, sizeof sb, EXT2_SUPER_OFFSET + opt.offset) != sizeof sb) {
28+ perror("reading superblock");
29+ return 1;
30+ }
31+
32+ if (sb.s_magic != EXT2_SUPER_MAGIC) {
33+ fprintf(stderr,
34+ "no ext2/3/4 superblock found on %s\n", device);
35+ return 1;
36+ }
37+
38+ if (xpwrite(fd, syslinux_bootsect, syslinux_bootsect_len, 0)
39+ != (signed)syslinux_bootsect_len) {
40+ perror("writing bootblock");
41+ return 1;
42+ }
43+
44+ return 0;
45 }
46
47 /* The file's block count */
48--
491.9.1
50
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 \
6 6
7# If you really want to run syslinux, you need mtools. We just want the 7# If you really want to run syslinux, you need mtools. We just want the
8# ldlinux.* stuff for now, so skip mtools-native 8# ldlinux.* stuff for now, so skip mtools-native
9DEPENDS = "nasm-native util-linux" 9DEPENDS = "nasm-native util-linux e2fsprogs"
10 10
11SRC_URI = "${KERNELORG_MIRROR}/linux/utils/boot/syslinux/6.xx/syslinux-${PV}.tar.xz \ 11SRC_URI = "${KERNELORG_MIRROR}/linux/utils/boot/syslinux/6.xx/syslinux-${PV}.tar.xz \
12 file://syslinux-fix-parallel-building-issue.patch \ 12 file://syslinux-fix-parallel-building-issue.patch \
13 file://syslinux-libupload-depend-lib.patch \ 13 file://syslinux-libupload-depend-lib.patch \
14 file://syslinux-remove-clean-script.patch \ 14 file://syslinux-remove-clean-script.patch \
15 file://0001-linux-syslinux-support-ext2-3-4-device.patch \
16 file://0002-linux-syslinux-implement-open_ext2_fs.patch \
17 file://0003-linux-syslinux-implement-install_to_ext2.patch \
18 file://0004-linux-syslinux-add-ext_file_read-and-ext_file_write.patch \
19 file://0005-linux-syslinux-implement-handle_adv_on_ext.patch \
20 file://0006-linux-syslinux-implement-write_to_ext-and-add-syslin.patch \
21 file://0007-linux-syslinux-implement-ext_construct_sectmap_fs.patch \
22 file://0008-libinstaller-syslinuxext-implement-syslinux_patch_bo.patch \
23 file://0009-linux-syslinux-implement-install_bootblock.patch \
15 " 24 "
16 25
17SRC_URI[md5sum] = "92a253df9211e9c20172796ecf388f13" 26SRC_URI[md5sum] = "92a253df9211e9c20172796ecf388f13"