1 From 922e56c10e36d876777580c84daef9a66bea6525 Mon Sep 17 00:00:00 2001
2 From: Robert Yang <liezhi.yang@windriver.com>
3 Date: Wed, 31 Dec 2014 17:20:43 +0800
4 Subject: [PATCH 6/9] linux/syslinux: implement write_to_ext() and add
7 * The write_to_ext() write file to the extX device, and handle the boot
9 * The syslinuxext.c is used for placing the code which are used by
10 extlinux and syslinux (which is syslinux_patch_bootsect()).
12 Upstream-Status: Submitted
14 Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
15 Tested-by: Du Dolpher <dolpher.du@intel.com>
17 libinstaller/syslinuxext.c | 7 +++
18 libinstaller/syslinuxext.h | 5 ++
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
25 diff --git a/libinstaller/syslinuxext.c b/libinstaller/syslinuxext.c
27 index 0000000..bb54cef
29 +++ b/libinstaller/syslinuxext.c
33 +/* Patch syslinux_bootsect */
34 +void syslinux_patch_bootsect(int dev_fd)
38 diff --git a/libinstaller/syslinuxext.h b/libinstaller/syslinuxext.h
40 index 0000000..8abd8b9
42 +++ b/libinstaller/syslinuxext.h
44 +#ifndef EXT2_SUPER_OFFSET
45 +#define EXT2_SUPER_OFFSET 1024
48 +void syslinux_patch_bootsect(int dev_fd);
49 diff --git a/linux/Makefile b/linux/Makefile
50 index ac1ac58..3b23867 100644
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)))
62 .SUFFIXES: .c .o .i .s .S
63 diff --git a/linux/syslinux.c b/linux/syslinux.c
64 index de5d272..f0c97a8 100755
65 --- a/linux/syslinux.c
66 +++ b/linux/syslinux.c
68 #include <sys/types.h>
70 #include <sys/mount.h>
73 #include "linuxioctl.h"
78 #include "syslxopt.h" /* unified options */
79 +#include "syslinuxext.h"
80 #include <ext2fs/ext2fs.h>
82 extern const char *program; /* Name of program */
83 @@ -419,6 +421,12 @@ int install_bootblock(int fd, const char *device)
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)
93 static int handle_adv_on_ext(void)
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)
101 + struct ext2_inode inode;
102 + int retval, i, modbytes, nsect;
103 + ext2_file_t e2_file;
106 + /* Remove it if it is already exists */
107 + retval = ext2fs_namei(e2fs, root, cwd, filename, &newino);
109 + retval = ext2fs_unlink(e2fs, cwd, filename, newino, 0);
111 + fprintf(stderr, "%s: failed to unlink: %s\n", program, filename);
116 + /* Create new inode */
117 + retval = ext2fs_new_inode(e2fs, cwd, 010755, 0, &newino);
119 + fprintf(stderr, "%s: ERROR: failed to create inode for: %s\n",
120 + program, filename);
124 + /* Link the inode and the filename */
125 + retval = ext2fs_link(e2fs, cwd, filename, newino, EXT2_FT_REG_FILE);
127 + fprintf(stderr, "%s: ERROR: failed to link inode for: %s.\n",
128 + program, filename);
132 + if (ext2fs_test_inode_bitmap2(e2fs->inode_map, newino))
133 + fprintf(stderr, "%s: warning: inode already set %s.\n",
134 + program, filename);
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
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;
148 + eh = (struct ext3_extent_header *) &inode.i_block[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;
158 + retval = ext2fs_write_new_inode(e2fs, newino, &inode);
160 + fprintf(stderr, "%s: ERROR: while writting inode %d.\n",
165 + retval = ext2fs_file_open(e2fs, newino, EXT2_FILE_WRITE, &e2_file);
167 + fprintf(stderr, "%s: ERROR: failed to open %s.\n",
168 + program, filename);
172 + /* Write to file */
173 + if (ext_file_write(e2_file, str, length, 0) == -1)
176 + if (strcmp(filename, "ldlinux.sys") == 0) {
178 + if (ext_file_write(e2_file, syslinux_adv, 2 * ADV_SIZE,
179 + boot_image_len) == -1)
182 + /* Patch syslinux_bootsect */
183 + syslinux_patch_bootsect(dev_fd);
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);
195 + /* Create the modified image in memory */
196 + modbytes = syslinux_patch(sectors, nsect, opt.stupid_mode,
197 + opt.raid_mode, subdir, NULL);
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,
208 + (void) ext2fs_file_close(e2_file);
212 /* The install func for ext2, ext3 and ext4 */