Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 1 | From 758731ce2432ab29a73505bbeb99a960996ab686 Mon Sep 17 00:00:00 2001 |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 2 | From: Robert Yang <liezhi.yang@windriver.com> |
| 3 | Date: Wed, 31 Dec 2014 17:20:43 +0800 |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 4 | Subject: [PATCH] linux/syslinux: implement write_to_ext() and add |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 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 | |
| 12 | Upstream-Status: Submitted |
| 13 | |
| 14 | Signed-off-by: Robert Yang <liezhi.yang@windriver.com> |
| 15 | Tested-by: Du Dolpher <dolpher.du@intel.com> |
| 16 | --- |
| 17 | libinstaller/syslinuxext.c | 7 +++ |
| 18 | libinstaller/syslinuxext.h | 5 ++ |
| 19 | linux/Makefile | 3 +- |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 20 | linux/syslinux.c | 118 +++++++++++++++++++++++++++++++++++++ |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 21 | 4 files changed, 132 insertions(+), 1 deletion(-) |
| 22 | create mode 100644 libinstaller/syslinuxext.c |
| 23 | create mode 100644 libinstaller/syslinuxext.h |
| 24 | |
| 25 | diff --git a/libinstaller/syslinuxext.c b/libinstaller/syslinuxext.c |
| 26 | new file mode 100644 |
| 27 | index 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 | + |
| 38 | diff --git a/libinstaller/syslinuxext.h b/libinstaller/syslinuxext.h |
| 39 | new file mode 100644 |
| 40 | index 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); |
| 49 | diff --git a/linux/Makefile b/linux/Makefile |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 50 | index 67cbbb4..567134c 100644 |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 51 | --- a/linux/Makefile |
| 52 | +++ b/linux/Makefile |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 53 | @@ -31,7 +31,8 @@ SRCS = syslinux.c \ |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 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 |
| 63 | diff --git a/linux/syslinux.c b/linux/syslinux.c |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 64 | index 90b8edd..7a20fe6 100755 |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 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 | |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 75 | @@ -73,6 +74,7 @@ |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 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 */ |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 83 | @@ -420,6 +422,12 @@ int install_bootblock(int fd, const char *device) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 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; |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 96 | @@ -525,6 +533,116 @@ fail: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 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 */ |