diff options
Diffstat (limited to 'meta/recipes-devtools/syslinux/syslinux/0008-libinstaller-syslinuxext-implement-syslinux_patch_bo.patch')
-rw-r--r-- | meta/recipes-devtools/syslinux/syslinux/0008-libinstaller-syslinuxext-implement-syslinux_patch_bo.patch | 427 |
1 files changed, 427 insertions, 0 deletions
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 @@ | |||
1 | From 78d76b87a4b855e6b661ae457283a63f385c04c9 Mon Sep 17 00:00:00 2001 | ||
2 | From: Robert Yang <liezhi.yang@windriver.com> | ||
3 | Date: Fri, 2 Jan 2015 12:26:46 +0800 | ||
4 | Subject: [PATCH 8/9] libinstaller/syslinuxext: implement | ||
5 | syslinux_patch_bootsect() | ||
6 | |||
7 | Move the related from extlinux/main.c to libinstaller/syslinuxext.c, the | ||
8 | syslinux_patch_bootsect() are used by both extlinux/main.c and | ||
9 | linux/syslinux.c. | ||
10 | |||
11 | Upstream-Status: Submitted | ||
12 | |||
13 | Signed-off-by: Robert Yang <liezhi.yang@windriver.com> | ||
14 | Tested-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 | |||
21 | diff --git a/extlinux/Makefile b/extlinux/Makefile | ||
22 | index 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 | ||
35 | diff --git a/extlinux/main.c b/extlinux/main.c | ||
36 | index 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, §s)) | ||
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 | |||
243 | diff --git a/libinstaller/syslinuxext.c b/libinstaller/syslinuxext.c | ||
244 | index 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, §s)) | ||
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 | -- | ||
426 | 1.9.1 | ||
427 | |||