]> code.ossystems Code Review - openembedded-core.git/blob
2400c98d6a54db1306e278015245c0baf47c259b
[openembedded-core.git] /
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, &sects))
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, &sects))
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