aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-multimedia/cdrkit/files/0001-add-new-option-eltorito-platform.patch
blob: dac3328a4260c09014db6303b8e74f1795b032c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
From 5a2d571f3687910260c45841725f2deb84c8f12e Mon Sep 17 00:00:00 2001
From: Hongxu Jia <hongxu.jia@windriver.com>
Date: Mon, 25 Apr 2022 18:18:00 +0800
Subject: [PATCH] add new option -eltorito-platform

Mkisofs now correctly supports El Torito multi boot entries by introducing
a Boot Dection Header before a list of alternate boot entries.

New option -eltorito-platform allows to set the El Torito platform id
for a boot entry or for a list of boot entries. Supported values for
the parameter are:
-   x86 the standard value vor x86 based PCs
-   PPC the Power PC platform
-   Mac The Apple Mac platform
-   efi EFI based boot for PCs
-   #   an arbitrary numerical value

Upstream-Status: Inappropriate [port from cdrtools]
https://github.com/jobermayr/cdrtools/commit/a50804fd61d75eb689a515dbfca6968ca2296fd7

Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
---
 genisoimage/eltorito.c    | 73 +++++++++++++++++++++++++++++++++++++--
 genisoimage/genisoimage.c | 47 +++++++++++++++++++++++++
 genisoimage/genisoimage.h |  8 +++++
 genisoimage/iso9660.h     | 33 ++++++++++++++++--
 4 files changed, 157 insertions(+), 4 deletions(-)

diff --git a/genisoimage/eltorito.c b/genisoimage/eltorito.c
index d52e17e..a804988 100644
--- a/genisoimage/eltorito.c
+++ b/genisoimage/eltorito.c
@@ -56,6 +56,7 @@ static unsigned int bcat_de_flags;
 void	init_boot_catalog(const char *path);
 void	insert_boot_cat(void);
 static	void	get_torito_desc(struct eltorito_boot_descriptor *boot_desc);
+static	void	fill_boot_shdr(struct eltorito_sectionheader_entry *boot_shdr_entry, int arch);
 static	void	fill_boot_desc(struct eltorito_defaultboot_entry *boot_desc_entry,
 										struct eltorito_boot_entry_info *boot_entry);
 void	get_boot_entry(void);
@@ -282,7 +283,14 @@ get_torito_desc(struct eltorito_boot_descriptor *boot_desc)
 	struct directory_entry	*de2;	/* Boot catalog */
 	int			i;
 	int			offset;
+	int			arch = 0;
+	int			nentries = 0;
 	struct eltorito_defaultboot_entry boot_desc_record;
+	struct eltorito_sectionheader_entry boot_shdr_record;
+#ifdef __needed__
+	struct eltorito_section_entry boot_section_record;
+#endif
+	struct eltorito_sectionheader_entry *last_section_header = 0;
 
 	memset(boot_desc, 0, sizeof (*boot_desc));
 	boot_desc->type[0] = 0;
@@ -311,13 +319,22 @@ get_torito_desc(struct eltorito_boot_descriptor *boot_desc)
 	set_731(boot_desc->bootcat_ptr,
 		(unsigned int) get_733(de2->isorec.extent));
 
+	/*
+	 * If the platform id for the first (default) boot entry has not been
+	 * explicitly set, we default to EL_TORITO_ARCH_x86
+	 */
+	if ((first_boot_entry->type & ELTORITO_BOOT_ID) == 0) {
+		first_boot_entry->boot_platform = EL_TORITO_ARCH_x86;
+	}
+	arch = first_boot_entry->boot_platform;
+
 	/*
 	 * we have the boot image, so write boot catalog information
 	 * Next we write out the primary descriptor for the disc
 	 */
 	memset(&valid_desc, 0, sizeof (valid_desc));
 	valid_desc.headerid[0] = 1;
-	valid_desc.arch[0] = EL_TORITO_ARCH_x86;
+	valid_desc.arch[0] = arch;  /* Platform id for the default boot */
 
 	/*
 	 * we'll shove start of publisher id into id field,
@@ -351,8 +368,17 @@ get_torito_desc(struct eltorito_boot_descriptor *boot_desc)
 		current_boot_entry != NULL;
 		current_boot_entry = current_boot_entry->next,
 		offset += sizeof (boot_desc_record)) {
+		int newarch = arch;
 
-		if (offset >= SECTOR_SIZE) {
+		if (current_boot_entry->type & ELTORITO_BOOT_ID)
+			newarch = current_boot_entry->boot_platform;
+		else
+			current_boot_entry->boot_platform = arch;
+ 
+		/*
+		 * El Torito has no such limitation but we currently have...
+		 */
+		if (offset >= (SECTOR_SIZE - sizeof (boot_desc_record))) {
 #ifdef	USE_LIBSCHILY
 			comerrno(EX_BAD,
 			"Too many El Torito boot entries\n");
@@ -362,12 +388,53 @@ get_torito_desc(struct eltorito_boot_descriptor *boot_desc)
 			exit(1);
 #endif
 		}
+
+		if (current_boot_entry == first_boot_entry) {
+			;
+			/* EMPTY */
+		} else if ((current_boot_entry == first_boot_entry->next) ||
+			    (arch != newarch) ||
+			    (current_boot_entry->type & ELTORITO_SECTION_HEADER)) {
+			if (last_section_header)
+				set_721(&last_section_header->entry_count, nentries);
+			nentries = 1;
+			last_section_header = (struct eltorito_sectionheader_entry *)
+							(de2->table + offset);
+			fill_boot_shdr(&boot_shdr_record, newarch);
+			memcpy(de2->table + offset, &boot_shdr_record,
+						sizeof (boot_shdr_record));
+			offset += sizeof (boot_desc_record);
+		} else {
+			nentries++; /* Add entry to this section header */
+		}
+		/*
+		 * This works because a section entry has the same essential
+		 * layout as a default entry (and we do not populate the
+		 * selection criteria fields).
+		 */
+
 		fill_boot_desc(&boot_desc_record, current_boot_entry);
 		memcpy(de2->table + offset, &boot_desc_record,
 					sizeof (boot_desc_record));
 	}
+
+	if (last_section_header) {
+		set_721(&last_section_header->entry_count, nentries);
+		last_section_header->header_id[0] = EL_TORITO_SHDR_ID_LAST_SHDR;
+	}
+
 }/* get_torito_desc(... */
 
+static void
+fill_boot_shdr(boot_shdr_entry, arch)
+	struct eltorito_sectionheader_entry *boot_shdr_entry;
+	int                 arch;
+{
+	memset(boot_shdr_entry, 0, sizeof(struct eltorito_sectionheader_entry));
+	boot_shdr_entry->header_id[0] = EL_TORITO_SHDR_ID_SHDR;
+	boot_shdr_entry->platform_id[0] = arch;
+}
+
 static void
 fill_boot_desc(struct eltorito_defaultboot_entry *boot_desc_entry, 
 					struct eltorito_boot_entry_info *boot_entry)
@@ -678,7 +745,9 @@ get_boot_entry()
 	if (!first_boot_entry) {
 		first_boot_entry = current_boot_entry;
 		last_boot_entry = current_boot_entry;
+		current_boot_entry->boot_platform = EL_TORITO_ARCH_x86;
 	} else {
+		current_boot_entry->boot_platform = last_boot_entry->boot_platform;
 		last_boot_entry->next = current_boot_entry;
 		last_boot_entry = current_boot_entry;
 	}
diff --git a/genisoimage/genisoimage.c b/genisoimage/genisoimage.c
index 9089081..84ac3c2 100644
--- a/genisoimage/genisoimage.c
+++ b/genisoimage/genisoimage.c
@@ -271,6 +271,8 @@ struct rcopts {
 	char		**variable;
 };
 
+static int get_boot_platid(char *opt_arg);
+
 struct rcopts rcopt[] = {
 	{"PREP", &preparer},
 	{"PUBL", &publisher},
@@ -404,6 +406,7 @@ struct ld_option {
 
 #define	OPTION_ALLOW_LEADING_DOTS	1070
 #define	OPTION_PUBLISHER		1071
+#define	OPTION_PLATFORM			1072
 
 #ifdef		JIGDO_TEMPLATE
 #define	OPTION_JTT_OUTPUT		1101
@@ -528,6 +531,8 @@ static const struct ld_option ld_options[] =
 	'b', "FILE", "Set El Torito boot image name", ONE_DASH},
 	{{"eltorito-alt-boot", no_argument, NULL, OPTION_ALT_BOOT},
 	'\0', NULL, "Start specifying alternative El Torito boot parameters", ONE_DASH},
+	{{"eltorito-platform", required_argument, NULL, OPTION_PLATFORM},
+	'\0', "ID", "Set El Torito platform id for the next boot entry", ONE_DASH},
 	{{"sparc-boot", required_argument, NULL, 'B'},
 	'B', "FILES", "Set sparc boot image names", ONE_DASH},
 	{{"sunx86-boot", required_argument, NULL, OPTION_SUNX86BOOT},
@@ -1558,6 +1563,9 @@ int main(int argc, char *argv[])
 			 */
 			new_boot_entry();
 			break;
+		case OPTION_PLATFORM:
+			get_boot_platid(optarg);
+			break;
 		case OPTION_BOOTALPHA:
 			use_alphaboot++;
 			/* list of pathnames of boot images */
@@ -3829,3 +3837,42 @@ e_malloc(size_t size)
      memset(pt, 0, size);
 	return (pt);
 }
+
+static int
+get_boot_platid(char *opt_arg)
+{
+	long    val;
+	char    *ptr;
+
+	use_eltorito++;
+	if (streql(opt_arg, "x86")) {
+		val = EL_TORITO_ARCH_x86;
+	} else if (streql(opt_arg, "PPC")) {
+		val = EL_TORITO_ARCH_PPC;
+	} else if (streql(opt_arg, "Mac")) {
+		val = EL_TORITO_ARCH_PPC;
+	} else if (streql(opt_arg, "efi")) {
+		val = EL_TORITO_ARCH_EFI;
+	} else {
+		val = strtol(opt_arg, &ptr, 0);
+		if (*ptr || val < 0 || val >= 0x100) {
+			comerrno(EX_BAD, "Bad boot system ID.\n");
+		}
+	}
+
+	/*
+	 * If there is already a boot entry and the boot file name has been set
+	 * for this boot entry and the new platform id differs from the
+	 * previous value, we start a new boot section.
+	 */
+	if (current_boot_entry &&
+	    current_boot_entry->boot_image != NULL &&
+	    current_boot_entry->boot_platform != val) {
+	    new_boot_entry();
+	}
+	get_boot_entry();
+	current_boot_entry->type |= ELTORITO_BOOT_ID;
+	current_boot_entry->boot_platform = val;
+	return (1);
+}
+
diff --git a/genisoimage/genisoimage.h b/genisoimage/genisoimage.h
index 82c859b..1170d89 100644
--- a/genisoimage/genisoimage.h
+++ b/genisoimage/genisoimage.h
@@ -299,6 +299,14 @@ struct eltorito_boot_entry_info {
 	int		boot_info_table;
 	int		load_size;
 	int		load_addr;
+
+#define	ELTORITO_BOOT_ID    1
+#define	ELTORITO_SECTION_HEADER 2
+	int     type;
+	/*
+	 * Valid if (type & ELTORITO_BOOT_ID) != 0
+	 */
+	int     boot_platform;
 };
 
 extern int	goof;
diff --git a/genisoimage/iso9660.h b/genisoimage/iso9660.h
index c74c2a9..61b6fc0 100644
--- a/genisoimage/iso9660.h
+++ b/genisoimage/iso9660.h
@@ -62,6 +62,7 @@ struct iso_volume_descriptor {
 #define	EL_TORITO_ARCH_x86	0
 #define	EL_TORITO_ARCH_PPC	1
 #define	EL_TORITO_ARCH_MAC	2
+#define	EL_TORITO_ARCH_EFI	0xEF
 
 #define	EL_TORITO_BOOTABLE	0x88
 #define	EL_TORITO_NOT_BOOTABLE	0
@@ -159,10 +160,15 @@ struct eltorito_boot_descriptor {
 };
 
 /* Validation entry for El Torito */
+/*
+ * headerid must be 1
+ * id is the manufacturer ID
+ * cksum to make the sum of all shorts in this record 0
+ */
 struct eltorito_validation_entry {
 	char headerid			[ISODCL(1,    1)]; /* 711 */
 	char arch			[ISODCL(2,    2)];
-	char pad1			[ISODCL(3,    4)]; /* 711 */
+	char pad1			[ISODCL(3,    4)]; /* 721 */
 	char id				[ISODCL(5,   28)]; /* CD devel/man*/
 	char cksum			[ISODCL(29,  30)];
 	char key1			[ISODCL(31,  31)];
@@ -173,7 +179,7 @@ struct eltorito_validation_entry {
 struct eltorito_defaultboot_entry {
 	char boot_id			[ISODCL(1,    1)]; /* 711 */
 	char boot_media			[ISODCL(2,    2)];
-	char loadseg			[ISODCL(3,    4)]; /* 711 */
+	char loadseg			[ISODCL(3,    4)]; /* 721 */
 	char sys_type			[ISODCL(5,    5)];
 	char pad1			[ISODCL(6,    6)];
 	char nsect			[ISODCL(7,    8)];
@@ -181,6 +187,29 @@ struct eltorito_defaultboot_entry {
 	char pad2			[ISODCL(13,  32)];
 };
 
+/* El Torito section header entry in boot catalog */
+struct eltorito_sectionheader_entry {
+#define    EL_TORITO_SHDR_ID_SHDR      0x90
+#define    EL_TORITO_SHDR_ID_LAST_SHDR 0x91
+	char header_id          [ISODCL(1,    1)]; /* 711 */
+	char platform_id        [ISODCL(2,    2)];
+	char entry_count        [ISODCL(3,    4)]; /* 721 */
+	char id             [ISODCL(5,   32)];
+};
+
+/* El Torito section entry in boot catalog */
+struct eltorito_section_entry {
+	char boot_id            [ISODCL(1,    1)]; /* 711 */
+	char boot_media         [ISODCL(2,    2)];
+	char loadseg            [ISODCL(3,    4)]; /* 721 */
+	char sys_type           [ISODCL(5,    5)];
+	char pad1           [ISODCL(6,    6)];
+	char nsect          [ISODCL(7,    8)];
+	char bootoff            [ISODCL(9,   12)];
+	char sel_criteria       [ISODCL(13,  13)];
+	char vendor_sel_criteria    [ISODCL(14,  32)];
+};
+
 /*
  * XXX JS: The next two structures have odd lengths!
  * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length.
-- 
2.27.0