blob: ba6d29d3bbae03e19a718fe6ac863f439c5f1eb9 [file] [log] [blame]
Patrick Williams92b42cb2022-09-03 06:53:57 -05001From 758731ce2432ab29a73505bbeb99a960996ab686 Mon Sep 17 00:00:00 2001
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002From: Robert Yang <liezhi.yang@windriver.com>
3Date: Wed, 31 Dec 2014 17:20:43 +0800
Patrick Williams92b42cb2022-09-03 06:53:57 -05004Subject: [PATCH] linux/syslinux: implement write_to_ext() and add
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005 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 +-
Patrick Williams92b42cb2022-09-03 06:53:57 -050020 linux/syslinux.c | 118 +++++++++++++++++++++++++++++++++++++
Patrick Williamsc124f4f2015-09-15 14:41:29 -050021 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
Patrick Williams92b42cb2022-09-03 06:53:57 -050050index 67cbbb4..567134c 100644
Patrick Williamsc124f4f2015-09-15 14:41:29 -050051--- a/linux/Makefile
52+++ b/linux/Makefile
Patrick Williams92b42cb2022-09-03 06:53:57 -050053@@ -31,7 +31,8 @@ SRCS = syslinux.c \
Patrick Williamsc124f4f2015-09-15 14:41:29 -050054 ../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
Patrick Williams92b42cb2022-09-03 06:53:57 -050064index 90b8edd..7a20fe6 100755
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065--- 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 Williams92b42cb2022-09-03 06:53:57 -050075@@ -73,6 +74,7 @@
Patrick Williamsc124f4f2015-09-15 14:41:29 -050076 #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 Williams92b42cb2022-09-03 06:53:57 -050083@@ -420,6 +422,12 @@ int install_bootblock(int fd, const char *device)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050084 {
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 Williams92b42cb2022-09-03 06:53:57 -050096@@ -525,6 +533,116 @@ fail:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097 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 */