Annotation of /trunk/mkinitrd-magellan/busybox/util-linux/fdisk_osf.c
Parent Directory | Revision Log
Revision 984 -
(hide annotations)
(download)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 30142 byte(s)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 30142 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 | niro | 532 | /* |
2 | * Copyright (c) 1987, 1988 Regents of the University of California. | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * 2. Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * 3. All advertising materials mentioning features or use of this software | ||
14 | * must display the following acknowledgment: | ||
15 | * This product includes software developed by the University of | ||
16 | * California, Berkeley and its contributors. | ||
17 | * 4. Neither the name of the University nor the names of its contributors | ||
18 | * may be used to endorse or promote products derived from this software | ||
19 | * without specific prior written permission. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
31 | * SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | niro | 984 | #if ENABLE_FEATURE_OSF_LABEL |
35 | niro | 532 | |
36 | #ifndef BSD_DISKMAGIC | ||
37 | #define BSD_DISKMAGIC ((uint32_t) 0x82564557) | ||
38 | #endif | ||
39 | |||
40 | #ifndef BSD_MAXPARTITIONS | ||
41 | #define BSD_MAXPARTITIONS 16 | ||
42 | #endif | ||
43 | |||
44 | #define BSD_LINUX_BOOTDIR "/usr/ucb/mdec" | ||
45 | |||
46 | #if defined(i386) || defined(__sparc__) || defined(__arm__) \ | ||
47 | || defined(__m68k__) || defined(__mips__) || defined(__s390__) \ | ||
48 | niro | 984 | || defined(__s390__) || defined(__s390x__) \ |
49 | || defined(__sh__) || defined(__x86_64__) || defined(__avr32__) | ||
50 | # define BSD_LABELSECTOR 1 | ||
51 | # define BSD_LABELOFFSET 0 | ||
52 | niro | 532 | #elif defined(__alpha__) || defined(__powerpc__) || defined(__ia64__) \ |
53 | || defined(__hppa__) | ||
54 | niro | 984 | # define BSD_LABELSECTOR 0 |
55 | # define BSD_LABELOFFSET 64 | ||
56 | niro | 532 | #else |
57 | niro | 984 | # error unknown architecture |
58 | niro | 532 | #endif |
59 | |||
60 | #define BSD_BBSIZE 8192 /* size of boot area, with label */ | ||
61 | #define BSD_SBSIZE 8192 /* max size of fs superblock */ | ||
62 | |||
63 | struct xbsd_disklabel { | ||
64 | uint32_t d_magic; /* the magic number */ | ||
65 | int16_t d_type; /* drive type */ | ||
66 | int16_t d_subtype; /* controller/d_type specific */ | ||
67 | char d_typename[16]; /* type name, e.g. "eagle" */ | ||
68 | niro | 984 | char d_packname[16]; /* pack identifier */ |
69 | /* disk geometry: */ | ||
70 | niro | 532 | uint32_t d_secsize; /* # of bytes per sector */ |
71 | uint32_t d_nsectors; /* # of data sectors per track */ | ||
72 | uint32_t d_ntracks; /* # of tracks per cylinder */ | ||
73 | uint32_t d_ncylinders; /* # of data cylinders per unit */ | ||
74 | uint32_t d_secpercyl; /* # of data sectors per cylinder */ | ||
75 | uint32_t d_secperunit; /* # of data sectors per unit */ | ||
76 | /* | ||
77 | * Spares (bad sector replacements) below | ||
78 | * are not counted in d_nsectors or d_secpercyl. | ||
79 | * Spare sectors are assumed to be physical sectors | ||
80 | * which occupy space at the end of each track and/or cylinder. | ||
81 | */ | ||
82 | uint16_t d_sparespertrack; /* # of spare sectors per track */ | ||
83 | uint16_t d_sparespercyl; /* # of spare sectors per cylinder */ | ||
84 | /* | ||
85 | * Alternate cylinders include maintenance, replacement, | ||
86 | * configuration description areas, etc. | ||
87 | */ | ||
88 | uint32_t d_acylinders; /* # of alt. cylinders per unit */ | ||
89 | |||
90 | niro | 984 | /* hardware characteristics: */ |
91 | niro | 532 | /* |
92 | * d_interleave, d_trackskew and d_cylskew describe perturbations | ||
93 | * in the media format used to compensate for a slow controller. | ||
94 | * Interleave is physical sector interleave, set up by the formatter | ||
95 | * or controller when formatting. When interleaving is in use, | ||
96 | * logically adjacent sectors are not physically contiguous, | ||
97 | * but instead are separated by some number of sectors. | ||
98 | * It is specified as the ratio of physical sectors traversed | ||
99 | * per logical sector. Thus an interleave of 1:1 implies contiguous | ||
100 | * layout, while 2:1 implies that logical sector 0 is separated | ||
101 | * by one sector from logical sector 1. | ||
102 | * d_trackskew is the offset of sector 0 on track N | ||
103 | * relative to sector 0 on track N-1 on the same cylinder. | ||
104 | * Finally, d_cylskew is the offset of sector 0 on cylinder N | ||
105 | * relative to sector 0 on cylinder N-1. | ||
106 | */ | ||
107 | uint16_t d_rpm; /* rotational speed */ | ||
108 | uint16_t d_interleave; /* hardware sector interleave */ | ||
109 | uint16_t d_trackskew; /* sector 0 skew, per track */ | ||
110 | uint16_t d_cylskew; /* sector 0 skew, per cylinder */ | ||
111 | uint32_t d_headswitch; /* head switch time, usec */ | ||
112 | uint32_t d_trkseek; /* track-to-track seek, usec */ | ||
113 | uint32_t d_flags; /* generic flags */ | ||
114 | #define NDDATA 5 | ||
115 | uint32_t d_drivedata[NDDATA]; /* drive-type specific information */ | ||
116 | #define NSPARE 5 | ||
117 | uint32_t d_spare[NSPARE]; /* reserved for future use */ | ||
118 | uint32_t d_magic2; /* the magic number (again) */ | ||
119 | uint16_t d_checksum; /* xor of data incl. partitions */ | ||
120 | niro | 984 | /* filesystem and partition information: */ |
121 | niro | 532 | uint16_t d_npartitions; /* number of partitions in following */ |
122 | uint32_t d_bbsize; /* size of boot area at sn0, bytes */ | ||
123 | uint32_t d_sbsize; /* max size of fs superblock, bytes */ | ||
124 | niro | 984 | struct xbsd_partition { /* the partition table */ |
125 | niro | 532 | uint32_t p_size; /* number of sectors in partition */ |
126 | uint32_t p_offset; /* starting sector */ | ||
127 | uint32_t p_fsize; /* filesystem basic fragment size */ | ||
128 | uint8_t p_fstype; /* filesystem type, see below */ | ||
129 | uint8_t p_frag; /* filesystem fragments per block */ | ||
130 | uint16_t p_cpg; /* filesystem cylinders per group */ | ||
131 | } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ | ||
132 | }; | ||
133 | |||
134 | /* d_type values: */ | ||
135 | #define BSD_DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */ | ||
136 | #define BSD_DTYPE_MSCP 2 /* MSCP */ | ||
137 | #define BSD_DTYPE_DEC 3 /* other DEC (rk, rl) */ | ||
138 | #define BSD_DTYPE_SCSI 4 /* SCSI */ | ||
139 | #define BSD_DTYPE_ESDI 5 /* ESDI interface */ | ||
140 | #define BSD_DTYPE_ST506 6 /* ST506 etc. */ | ||
141 | #define BSD_DTYPE_HPIB 7 /* CS/80 on HP-IB */ | ||
142 | #define BSD_DTYPE_HPFL 8 /* HP Fiber-link */ | ||
143 | #define BSD_DTYPE_FLOPPY 10 /* floppy */ | ||
144 | |||
145 | /* d_subtype values: */ | ||
146 | #define BSD_DSTYPE_INDOSPART 0x8 /* is inside dos partition */ | ||
147 | #define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */ | ||
148 | #define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */ | ||
149 | |||
150 | niro | 816 | static const char *const xbsd_dktypenames[] = { |
151 | niro | 532 | "unknown", |
152 | "SMD", | ||
153 | "MSCP", | ||
154 | "old DEC", | ||
155 | "SCSI", | ||
156 | "ESDI", | ||
157 | "ST506", | ||
158 | "HP-IB", | ||
159 | "HP-FL", | ||
160 | "type 9", | ||
161 | "floppy", | ||
162 | 0 | ||
163 | }; | ||
164 | |||
165 | niro | 816 | |
166 | niro | 532 | /* |
167 | * Filesystem type and version. | ||
168 | * Used to interpret other filesystem-specific | ||
169 | * per-partition information. | ||
170 | */ | ||
171 | #define BSD_FS_UNUSED 0 /* unused */ | ||
172 | #define BSD_FS_SWAP 1 /* swap */ | ||
173 | #define BSD_FS_V6 2 /* Sixth Edition */ | ||
174 | #define BSD_FS_V7 3 /* Seventh Edition */ | ||
175 | #define BSD_FS_SYSV 4 /* System V */ | ||
176 | #define BSD_FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ | ||
177 | #define BSD_FS_V8 6 /* Eighth Edition, 4K blocks */ | ||
178 | #define BSD_FS_BSDFFS 7 /* 4.2BSD fast file system */ | ||
179 | #define BSD_FS_BSDLFS 9 /* 4.4BSD log-structured file system */ | ||
180 | #define BSD_FS_OTHER 10 /* in use, but unknown/unsupported */ | ||
181 | #define BSD_FS_HPFS 11 /* OS/2 high-performance file system */ | ||
182 | #define BSD_FS_ISO9660 12 /* ISO-9660 filesystem (cdrom) */ | ||
183 | #define BSD_FS_ISOFS BSD_FS_ISO9660 | ||
184 | #define BSD_FS_BOOT 13 /* partition contains bootstrap */ | ||
185 | #define BSD_FS_ADOS 14 /* AmigaDOS fast file system */ | ||
186 | #define BSD_FS_HFS 15 /* Macintosh HFS */ | ||
187 | #define BSD_FS_ADVFS 16 /* Digital Unix AdvFS */ | ||
188 | |||
189 | /* this is annoying, but it's also the way it is :-( */ | ||
190 | #ifdef __alpha__ | ||
191 | #define BSD_FS_EXT2 8 /* ext2 file system */ | ||
192 | #else | ||
193 | #define BSD_FS_MSDOS 8 /* MS-DOS file system */ | ||
194 | #endif | ||
195 | |||
196 | niro | 816 | static const char *const xbsd_fstypes[] = { |
197 | "\x00" "unused", /* BSD_FS_UNUSED */ | ||
198 | "\x01" "swap", /* BSD_FS_SWAP */ | ||
199 | "\x02" "Version 6", /* BSD_FS_V6 */ | ||
200 | "\x03" "Version 7", /* BSD_FS_V7 */ | ||
201 | "\x04" "System V", /* BSD_FS_SYSV */ | ||
202 | "\x05" "4.1BSD", /* BSD_FS_V71K */ | ||
203 | "\x06" "Eighth Edition", /* BSD_FS_V8 */ | ||
204 | "\x07" "4.2BSD", /* BSD_FS_BSDFFS */ | ||
205 | niro | 532 | #ifdef __alpha__ |
206 | niro | 816 | "\x08" "ext2", /* BSD_FS_EXT2 */ |
207 | niro | 532 | #else |
208 | niro | 816 | "\x08" "MS-DOS", /* BSD_FS_MSDOS */ |
209 | niro | 532 | #endif |
210 | niro | 816 | "\x09" "4.4LFS", /* BSD_FS_BSDLFS */ |
211 | "\x0a" "unknown", /* BSD_FS_OTHER */ | ||
212 | "\x0b" "HPFS", /* BSD_FS_HPFS */ | ||
213 | "\x0c" "ISO-9660", /* BSD_FS_ISO9660 */ | ||
214 | "\x0d" "boot", /* BSD_FS_BOOT */ | ||
215 | "\x0e" "ADOS", /* BSD_FS_ADOS */ | ||
216 | "\x0f" "HFS", /* BSD_FS_HFS */ | ||
217 | "\x10" "AdvFS", /* BSD_FS_ADVFS */ | ||
218 | NULL | ||
219 | niro | 532 | }; |
220 | |||
221 | |||
222 | /* | ||
223 | * flags shared by various drives: | ||
224 | */ | ||
225 | #define BSD_D_REMOVABLE 0x01 /* removable media */ | ||
226 | #define BSD_D_ECC 0x02 /* supports ECC */ | ||
227 | #define BSD_D_BADSECT 0x04 /* supports bad sector forw. */ | ||
228 | #define BSD_D_RAMDISK 0x08 /* disk emulator */ | ||
229 | #define BSD_D_CHAIN 0x10 /* can do back-back transfers */ | ||
230 | #define BSD_D_DOSPART 0x20 /* within MSDOS partition */ | ||
231 | |||
232 | /* | ||
233 | Changes: | ||
234 | 19990319 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> - i18n/nls | ||
235 | |||
236 | 20000101 - David Huggins-Daines <dhuggins@linuxcare.com> - Better | ||
237 | support for OSF/1 disklabels on Alpha. | ||
238 | Also fixed unaligned accesses in alpha_bootblock_checksum() | ||
239 | */ | ||
240 | |||
241 | #define FREEBSD_PARTITION 0xa5 | ||
242 | #define NETBSD_PARTITION 0xa9 | ||
243 | |||
244 | static void xbsd_delete_part(void); | ||
245 | static void xbsd_new_part(void); | ||
246 | static void xbsd_write_disklabel(void); | ||
247 | static int xbsd_create_disklabel(void); | ||
248 | static void xbsd_edit_disklabel(void); | ||
249 | static void xbsd_write_bootstrap(void); | ||
250 | static void xbsd_change_fstype(void); | ||
251 | static int xbsd_get_part_index(int max); | ||
252 | static int xbsd_check_new_partition(int *i); | ||
253 | static void xbsd_list_types(void); | ||
254 | static uint16_t xbsd_dkcksum(struct xbsd_disklabel *lp); | ||
255 | niro | 816 | static int xbsd_initlabel(struct partition *p); |
256 | static int xbsd_readlabel(struct partition *p); | ||
257 | static int xbsd_writelabel(struct partition *p); | ||
258 | niro | 532 | |
259 | #if defined(__alpha__) | ||
260 | static void alpha_bootblock_checksum(char *boot); | ||
261 | #endif | ||
262 | |||
263 | #if !defined(__alpha__) | ||
264 | static int xbsd_translate_fstype(int linux_type); | ||
265 | static void xbsd_link_part(void); | ||
266 | static struct partition *xbsd_part; | ||
267 | static int xbsd_part_index; | ||
268 | #endif | ||
269 | |||
270 | niro | 816 | |
271 | /* Group big globals data and allocate it in one go */ | ||
272 | struct bsd_globals { | ||
273 | niro | 532 | /* We access this through a uint64_t * when checksumming */ |
274 | /* hopefully xmalloc gives us required alignment */ | ||
275 | niro | 816 | char disklabelbuffer[BSD_BBSIZE]; |
276 | struct xbsd_disklabel xbsd_dlabel; | ||
277 | }; | ||
278 | niro | 532 | |
279 | niro | 816 | static struct bsd_globals *bsd_globals_ptr; |
280 | niro | 532 | |
281 | niro | 816 | #define disklabelbuffer (bsd_globals_ptr->disklabelbuffer) |
282 | #define xbsd_dlabel (bsd_globals_ptr->xbsd_dlabel) | ||
283 | |||
284 | |||
285 | /* Code */ | ||
286 | |||
287 | niro | 532 | #define bsd_cround(n) \ |
288 | (display_in_cyl_units ? ((n)/xbsd_dlabel.d_secpercyl) + 1 : (n)) | ||
289 | |||
290 | /* | ||
291 | * Test whether the whole disk has BSD disk label magic. | ||
292 | * | ||
293 | * Note: often reformatting with DOS-type label leaves the BSD magic, | ||
294 | * so this does not mean that there is a BSD disk label. | ||
295 | */ | ||
296 | static int | ||
297 | check_osf_label(void) | ||
298 | { | ||
299 | niro | 816 | if (xbsd_readlabel(NULL) == 0) |
300 | niro | 532 | return 0; |
301 | return 1; | ||
302 | } | ||
303 | |||
304 | static int | ||
305 | bsd_trydev(const char * dev) | ||
306 | { | ||
307 | niro | 816 | if (xbsd_readlabel(NULL) == 0) |
308 | niro | 532 | return -1; |
309 | niro | 816 | printf("\nBSD label for device: %s\n", dev); |
310 | niro | 532 | xbsd_print_disklabel(0); |
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static void | ||
315 | bsd_menu(void) | ||
316 | { | ||
317 | niro | 816 | puts("Command Action"); |
318 | puts("d\tdelete a BSD partition"); | ||
319 | puts("e\tedit drive data"); | ||
320 | puts("i\tinstall bootstrap"); | ||
321 | puts("l\tlist known filesystem types"); | ||
322 | puts("n\tadd a new BSD partition"); | ||
323 | puts("p\tprint BSD partition table"); | ||
324 | puts("q\tquit without saving changes"); | ||
325 | puts("r\treturn to main menu"); | ||
326 | puts("s\tshow complete disklabel"); | ||
327 | puts("t\tchange a partition's filesystem id"); | ||
328 | puts("u\tchange units (cylinders/sectors)"); | ||
329 | puts("w\twrite disklabel to disk"); | ||
330 | niro | 532 | #if !defined(__alpha__) |
331 | niro | 816 | puts("x\tlink BSD partition to non-BSD partition"); |
332 | niro | 532 | #endif |
333 | } | ||
334 | |||
335 | #if !defined(__alpha__) | ||
336 | static int | ||
337 | hidden(int type) | ||
338 | { | ||
339 | return type ^ 0x10; | ||
340 | } | ||
341 | |||
342 | static int | ||
343 | is_bsd_partition_type(int type) | ||
344 | { | ||
345 | return (type == FREEBSD_PARTITION || | ||
346 | type == hidden(FREEBSD_PARTITION) || | ||
347 | type == NETBSD_PARTITION || | ||
348 | type == hidden(NETBSD_PARTITION)); | ||
349 | } | ||
350 | #endif | ||
351 | |||
352 | static void | ||
353 | bsd_select(void) | ||
354 | { | ||
355 | #if !defined(__alpha__) | ||
356 | int t, ss; | ||
357 | struct partition *p; | ||
358 | |||
359 | for (t = 0; t < 4; t++) { | ||
360 | p = get_part_table(t); | ||
361 | if (p && is_bsd_partition_type(p->sys_ind)) { | ||
362 | xbsd_part = p; | ||
363 | xbsd_part_index = t; | ||
364 | ss = get_start_sect(xbsd_part); | ||
365 | if (ss == 0) { | ||
366 | niro | 816 | printf("Partition %s has invalid starting sector 0\n", |
367 | niro | 532 | partname(disk_device, t+1, 0)); |
368 | return; | ||
369 | } | ||
370 | niro | 984 | printf("Reading disklabel of %s at sector %u\n", |
371 | niro | 532 | partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR); |
372 | niro | 816 | if (xbsd_readlabel(xbsd_part) == 0) |
373 | niro | 532 | if (xbsd_create_disklabel() == 0) |
374 | return; | ||
375 | break; | ||
376 | } | ||
377 | } | ||
378 | |||
379 | if (t == 4) { | ||
380 | niro | 816 | printf("There is no *BSD partition on %s\n", disk_device); |
381 | niro | 532 | return; |
382 | } | ||
383 | |||
384 | #elif defined(__alpha__) | ||
385 | |||
386 | niro | 816 | if (xbsd_readlabel(NULL) == 0) |
387 | niro | 532 | if (xbsd_create_disklabel() == 0) |
388 | exit(EXIT_SUCCESS); | ||
389 | |||
390 | #endif | ||
391 | |||
392 | while (1) { | ||
393 | niro | 816 | bb_putchar('\n'); |
394 | switch (tolower(read_nonempty("BSD disklabel command (m for help): "))) { | ||
395 | niro | 532 | case 'd': |
396 | xbsd_delete_part(); | ||
397 | break; | ||
398 | case 'e': | ||
399 | xbsd_edit_disklabel(); | ||
400 | break; | ||
401 | case 'i': | ||
402 | xbsd_write_bootstrap(); | ||
403 | break; | ||
404 | case 'l': | ||
405 | xbsd_list_types(); | ||
406 | break; | ||
407 | case 'n': | ||
408 | xbsd_new_part(); | ||
409 | break; | ||
410 | case 'p': | ||
411 | xbsd_print_disklabel(0); | ||
412 | break; | ||
413 | case 'q': | ||
414 | niro | 816 | if (ENABLE_FEATURE_CLEAN_UP) |
415 | close_dev_fd(); | ||
416 | niro | 532 | exit(EXIT_SUCCESS); |
417 | case 'r': | ||
418 | return; | ||
419 | case 's': | ||
420 | xbsd_print_disklabel(1); | ||
421 | break; | ||
422 | case 't': | ||
423 | xbsd_change_fstype(); | ||
424 | break; | ||
425 | case 'u': | ||
426 | change_units(); | ||
427 | break; | ||
428 | case 'w': | ||
429 | xbsd_write_disklabel(); | ||
430 | break; | ||
431 | #if !defined(__alpha__) | ||
432 | case 'x': | ||
433 | xbsd_link_part(); | ||
434 | break; | ||
435 | #endif | ||
436 | default: | ||
437 | bsd_menu(); | ||
438 | break; | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | |||
443 | static void | ||
444 | xbsd_delete_part(void) | ||
445 | { | ||
446 | int i; | ||
447 | |||
448 | i = xbsd_get_part_index(xbsd_dlabel.d_npartitions); | ||
449 | xbsd_dlabel.d_partitions[i].p_size = 0; | ||
450 | xbsd_dlabel.d_partitions[i].p_offset = 0; | ||
451 | xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; | ||
452 | if (xbsd_dlabel.d_npartitions == i + 1) | ||
453 | while (xbsd_dlabel.d_partitions[xbsd_dlabel.d_npartitions-1].p_size == 0) | ||
454 | xbsd_dlabel.d_npartitions--; | ||
455 | } | ||
456 | |||
457 | static void | ||
458 | xbsd_new_part(void) | ||
459 | { | ||
460 | off_t begin, end; | ||
461 | char mesg[256]; | ||
462 | int i; | ||
463 | |||
464 | if (!xbsd_check_new_partition(&i)) | ||
465 | return; | ||
466 | |||
467 | #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__hppa__) | ||
468 | begin = get_start_sect(xbsd_part); | ||
469 | end = begin + get_nr_sects(xbsd_part) - 1; | ||
470 | #else | ||
471 | begin = 0; | ||
472 | end = xbsd_dlabel.d_secperunit - 1; | ||
473 | #endif | ||
474 | |||
475 | niro | 816 | snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR)); |
476 | niro | 532 | begin = read_int(bsd_cround(begin), bsd_cround(begin), bsd_cround(end), |
477 | 0, mesg); | ||
478 | |||
479 | if (display_in_cyl_units) | ||
480 | begin = (begin - 1) * xbsd_dlabel.d_secpercyl; | ||
481 | |||
482 | niro | 816 | snprintf(mesg, sizeof(mesg), "Last %s or +size or +sizeM or +sizeK", |
483 | niro | 532 | str_units(SINGULAR)); |
484 | end = read_int(bsd_cround(begin), bsd_cround(end), bsd_cround(end), | ||
485 | bsd_cround(begin), mesg); | ||
486 | |||
487 | if (display_in_cyl_units) | ||
488 | end = end * xbsd_dlabel.d_secpercyl - 1; | ||
489 | |||
490 | xbsd_dlabel.d_partitions[i].p_size = end - begin + 1; | ||
491 | xbsd_dlabel.d_partitions[i].p_offset = begin; | ||
492 | xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; | ||
493 | } | ||
494 | |||
495 | static void | ||
496 | xbsd_print_disklabel(int show_all) | ||
497 | { | ||
498 | struct xbsd_disklabel *lp = &xbsd_dlabel; | ||
499 | struct xbsd_partition *pp; | ||
500 | int i, j; | ||
501 | |||
502 | if (show_all) { | ||
503 | niro | 816 | static const int d_masks[] = { BSD_D_REMOVABLE, BSD_D_ECC, BSD_D_BADSECT }; |
504 | |||
505 | niro | 532 | #if defined(__alpha__) |
506 | printf("# %s:\n", disk_device); | ||
507 | #else | ||
508 | printf("# %s:\n", partname(disk_device, xbsd_part_index+1, 0)); | ||
509 | #endif | ||
510 | niro | 816 | if ((unsigned) lp->d_type < ARRAY_SIZE(xbsd_dktypenames)-1) |
511 | printf("type: %s\n", xbsd_dktypenames[lp->d_type]); | ||
512 | niro | 532 | else |
513 | niro | 984 | printf("type: %u\n", lp->d_type); |
514 | niro | 816 | printf("disk: %.*s\n", (int) sizeof(lp->d_typename), lp->d_typename); |
515 | printf("label: %.*s\n", (int) sizeof(lp->d_packname), lp->d_packname); | ||
516 | printf("flags: "); | ||
517 | print_flags_separated(d_masks, "removable\0""ecc\0""badsect\0", lp->d_flags, " "); | ||
518 | bb_putchar('\n'); | ||
519 | niro | 532 | /* On various machines the fields of *lp are short/int/long */ |
520 | /* In order to avoid problems, we cast them all to long. */ | ||
521 | niro | 984 | printf("bytes/sector: %lu\n", (long) lp->d_secsize); |
522 | printf("sectors/track: %lu\n", (long) lp->d_nsectors); | ||
523 | printf("tracks/cylinder: %lu\n", (long) lp->d_ntracks); | ||
524 | printf("sectors/cylinder: %lu\n", (long) lp->d_secpercyl); | ||
525 | printf("cylinders: %lu\n", (long) lp->d_ncylinders); | ||
526 | printf("rpm: %u\n", lp->d_rpm); | ||
527 | printf("interleave: %u\n", lp->d_interleave); | ||
528 | printf("trackskew: %u\n", lp->d_trackskew); | ||
529 | printf("cylinderskew: %u\n", lp->d_cylskew); | ||
530 | printf("headswitch: %lu\t\t# milliseconds\n", | ||
531 | niro | 532 | (long) lp->d_headswitch); |
532 | niro | 984 | printf("track-to-track seek: %lu\t# milliseconds\n", |
533 | niro | 532 | (long) lp->d_trkseek); |
534 | niro | 816 | printf("drivedata: "); |
535 | niro | 532 | for (i = NDDATA - 1; i >= 0; i--) |
536 | if (lp->d_drivedata[i]) | ||
537 | break; | ||
538 | if (i < 0) | ||
539 | i = 0; | ||
540 | for (j = 0; j <= i; j++) | ||
541 | niro | 984 | printf("%lu ", (long) lp->d_drivedata[j]); |
542 | niro | 532 | } |
543 | niro | 984 | printf("\n%u partitions:\n", lp->d_npartitions); |
544 | niro | 816 | printf("# start end size fstype [fsize bsize cpg]\n"); |
545 | niro | 532 | pp = lp->d_partitions; |
546 | for (i = 0; i < lp->d_npartitions; i++, pp++) { | ||
547 | if (pp->p_size) { | ||
548 | if (display_in_cyl_units && lp->d_secpercyl) { | ||
549 | niro | 984 | printf(" %c: %8lu%c %8lu%c %8lu%c ", |
550 | niro | 532 | 'a' + i, |
551 | niro | 984 | (unsigned long) pp->p_offset / lp->d_secpercyl + 1, |
552 | niro | 532 | (pp->p_offset % lp->d_secpercyl) ? '*' : ' ', |
553 | niro | 984 | (unsigned long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl, |
554 | niro | 532 | ((pp->p_offset + pp->p_size) % lp->d_secpercyl) ? '*' : ' ', |
555 | (long) pp->p_size / lp->d_secpercyl, | ||
556 | (pp->p_size % lp->d_secpercyl) ? '*' : ' ' | ||
557 | ); | ||
558 | } else { | ||
559 | niro | 984 | printf(" %c: %8lu %8lu %8lu ", |
560 | niro | 532 | 'a' + i, |
561 | (long) pp->p_offset, | ||
562 | (long) pp->p_offset + pp->p_size - 1, | ||
563 | (long) pp->p_size | ||
564 | ); | ||
565 | } | ||
566 | |||
567 | niro | 816 | if ((unsigned) pp->p_fstype < ARRAY_SIZE(xbsd_fstypes)-1) |
568 | printf("%8.8s", xbsd_fstypes[pp->p_fstype]); | ||
569 | niro | 532 | else |
570 | printf("%8x", pp->p_fstype); | ||
571 | |||
572 | switch (pp->p_fstype) { | ||
573 | case BSD_FS_UNUSED: | ||
574 | niro | 984 | printf(" %5lu %5lu %5.5s ", |
575 | niro | 532 | (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, ""); |
576 | break; | ||
577 | case BSD_FS_BSDFFS: | ||
578 | niro | 984 | printf(" %5lu %5lu %5u ", |
579 | niro | 532 | (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, pp->p_cpg); |
580 | break; | ||
581 | default: | ||
582 | printf("%22.22s", ""); | ||
583 | break; | ||
584 | } | ||
585 | niro | 816 | bb_putchar('\n'); |
586 | niro | 532 | } |
587 | } | ||
588 | } | ||
589 | |||
590 | static void | ||
591 | xbsd_write_disklabel(void) | ||
592 | { | ||
593 | #if defined(__alpha__) | ||
594 | niro | 816 | printf("Writing disklabel to %s\n", disk_device); |
595 | xbsd_writelabel(NULL); | ||
596 | niro | 532 | #else |
597 | niro | 816 | printf("Writing disklabel to %s\n", |
598 | niro | 532 | partname(disk_device, xbsd_part_index + 1, 0)); |
599 | niro | 816 | xbsd_writelabel(xbsd_part); |
600 | niro | 532 | #endif |
601 | reread_partition_table(0); /* no exit yet */ | ||
602 | } | ||
603 | |||
604 | static int | ||
605 | xbsd_create_disklabel(void) | ||
606 | { | ||
607 | char c; | ||
608 | |||
609 | #if defined(__alpha__) | ||
610 | niro | 816 | printf("%s contains no disklabel\n", disk_device); |
611 | niro | 532 | #else |
612 | niro | 816 | printf("%s contains no disklabel\n", |
613 | niro | 532 | partname(disk_device, xbsd_part_index + 1, 0)); |
614 | #endif | ||
615 | |||
616 | while (1) { | ||
617 | niro | 816 | c = read_nonempty("Do you want to create a disklabel? (y/n) "); |
618 | niro | 984 | if ((c|0x20) == 'y') { |
619 | niro | 532 | if (xbsd_initlabel( |
620 | #if defined(__alpha__) || defined(__powerpc__) || defined(__hppa__) || \ | ||
621 | defined(__s390__) || defined(__s390x__) | ||
622 | niro | 816 | NULL |
623 | niro | 532 | #else |
624 | niro | 816 | xbsd_part |
625 | niro | 532 | #endif |
626 | niro | 816 | ) == 1) { |
627 | niro | 532 | xbsd_print_disklabel(1); |
628 | return 1; | ||
629 | niro | 816 | } |
630 | niro | 532 | return 0; |
631 | niro | 816 | } |
632 | niro | 984 | if ((c|0x20) == 'n') |
633 | niro | 816 | return 0; |
634 | niro | 532 | } |
635 | } | ||
636 | |||
637 | static int | ||
638 | niro | 816 | edit_int(int def, const char *mesg) |
639 | niro | 532 | { |
640 | niro | 984 | mesg = xasprintf("%s (%u): ", mesg, def); |
641 | niro | 532 | do { |
642 | niro | 816 | if (!read_line(mesg)) |
643 | goto ret; | ||
644 | niro | 532 | } while (!isdigit(*line_ptr)); |
645 | niro | 816 | def = atoi(line_ptr); |
646 | ret: | ||
647 | free((char*)mesg); | ||
648 | return def; | ||
649 | niro | 532 | } |
650 | |||
651 | static void | ||
652 | xbsd_edit_disklabel(void) | ||
653 | { | ||
654 | struct xbsd_disklabel *d; | ||
655 | |||
656 | d = &xbsd_dlabel; | ||
657 | |||
658 | #if defined(__alpha__) || defined(__ia64__) | ||
659 | niro | 816 | d->d_secsize = edit_int(d->d_secsize , "bytes/sector"); |
660 | d->d_nsectors = edit_int(d->d_nsectors , "sectors/track"); | ||
661 | d->d_ntracks = edit_int(d->d_ntracks , "tracks/cylinder"); | ||
662 | d->d_ncylinders = edit_int(d->d_ncylinders , "cylinders"); | ||
663 | niro | 532 | #endif |
664 | |||
665 | /* d->d_secpercyl can be != d->d_nsectors * d->d_ntracks */ | ||
666 | while (1) { | ||
667 | d->d_secpercyl = edit_int(d->d_nsectors * d->d_ntracks, | ||
668 | niro | 816 | "sectors/cylinder"); |
669 | niro | 532 | if (d->d_secpercyl <= d->d_nsectors * d->d_ntracks) |
670 | break; | ||
671 | |||
672 | niro | 816 | printf("Must be <= sectors/track * tracks/cylinder (default)\n"); |
673 | niro | 532 | } |
674 | niro | 816 | d->d_rpm = edit_int(d->d_rpm , "rpm"); |
675 | d->d_interleave = edit_int(d->d_interleave, "interleave"); | ||
676 | d->d_trackskew = edit_int(d->d_trackskew , "trackskew"); | ||
677 | d->d_cylskew = edit_int(d->d_cylskew , "cylinderskew"); | ||
678 | d->d_headswitch = edit_int(d->d_headswitch, "headswitch"); | ||
679 | d->d_trkseek = edit_int(d->d_trkseek , "track-to-track seek"); | ||
680 | niro | 532 | |
681 | d->d_secperunit = d->d_secpercyl * d->d_ncylinders; | ||
682 | } | ||
683 | |||
684 | static int | ||
685 | xbsd_get_bootstrap(char *path, void *ptr, int size) | ||
686 | { | ||
687 | int fdb; | ||
688 | |||
689 | niro | 816 | fdb = open_or_warn(path, O_RDONLY); |
690 | niro | 532 | if (fdb < 0) { |
691 | return 0; | ||
692 | } | ||
693 | niro | 816 | if (full_read(fdb, ptr, size) < 0) { |
694 | bb_simple_perror_msg(path); | ||
695 | niro | 532 | close(fdb); |
696 | return 0; | ||
697 | } | ||
698 | printf(" ... %s\n", path); | ||
699 | close(fdb); | ||
700 | return 1; | ||
701 | } | ||
702 | |||
703 | static void | ||
704 | sync_disks(void) | ||
705 | { | ||
706 | niro | 816 | printf("Syncing disks\n"); |
707 | niro | 532 | sync(); |
708 | niro | 816 | /* sleep(4); What? */ |
709 | niro | 532 | } |
710 | |||
711 | static void | ||
712 | xbsd_write_bootstrap(void) | ||
713 | { | ||
714 | char path[MAXPATHLEN]; | ||
715 | niro | 816 | const char *bootdir = BSD_LINUX_BOOTDIR; |
716 | const char *dkbasename; | ||
717 | niro | 532 | struct xbsd_disklabel dl; |
718 | char *d, *p, *e; | ||
719 | int sector; | ||
720 | |||
721 | if (xbsd_dlabel.d_type == BSD_DTYPE_SCSI) | ||
722 | dkbasename = "sd"; | ||
723 | else | ||
724 | dkbasename = "wd"; | ||
725 | |||
726 | niro | 816 | snprintf(path, sizeof(path), "Bootstrap: %sboot -> boot%s (%s): ", |
727 | niro | 532 | dkbasename, dkbasename, dkbasename); |
728 | niro | 816 | if (read_line(path)) { |
729 | niro | 532 | dkbasename = line_ptr; |
730 | } | ||
731 | snprintf(path, sizeof(path), "%s/%sboot", bootdir, dkbasename); | ||
732 | if (!xbsd_get_bootstrap(path, disklabelbuffer, (int) xbsd_dlabel.d_secsize)) | ||
733 | return; | ||
734 | |||
735 | /* We need a backup of the disklabel (xbsd_dlabel might have changed). */ | ||
736 | d = &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE]; | ||
737 | memmove(&dl, d, sizeof(struct xbsd_disklabel)); | ||
738 | |||
739 | /* The disklabel will be overwritten by 0's from bootxx anyway */ | ||
740 | memset(d, 0, sizeof(struct xbsd_disklabel)); | ||
741 | |||
742 | snprintf(path, sizeof(path), "%s/boot%s", bootdir, dkbasename); | ||
743 | if (!xbsd_get_bootstrap(path, &disklabelbuffer[xbsd_dlabel.d_secsize], | ||
744 | (int) xbsd_dlabel.d_bbsize - xbsd_dlabel.d_secsize)) | ||
745 | return; | ||
746 | |||
747 | e = d + sizeof(struct xbsd_disklabel); | ||
748 | for (p = d; p < e; p++) | ||
749 | if (*p) { | ||
750 | niro | 816 | printf("Bootstrap overlaps with disk label!\n"); |
751 | niro | 532 | exit(EXIT_FAILURE); |
752 | } | ||
753 | |||
754 | memmove(d, &dl, sizeof(struct xbsd_disklabel)); | ||
755 | |||
756 | #if defined(__powerpc__) || defined(__hppa__) | ||
757 | sector = 0; | ||
758 | #elif defined(__alpha__) | ||
759 | sector = 0; | ||
760 | alpha_bootblock_checksum(disklabelbuffer); | ||
761 | #else | ||
762 | sector = get_start_sect(xbsd_part); | ||
763 | #endif | ||
764 | |||
765 | niro | 816 | seek_sector(sector); |
766 | xwrite(dev_fd, disklabelbuffer, BSD_BBSIZE); | ||
767 | niro | 532 | |
768 | #if defined(__alpha__) | ||
769 | niro | 816 | printf("Bootstrap installed on %s\n", disk_device); |
770 | niro | 532 | #else |
771 | niro | 816 | printf("Bootstrap installed on %s\n", |
772 | niro | 532 | partname(disk_device, xbsd_part_index+1, 0)); |
773 | #endif | ||
774 | |||
775 | sync_disks(); | ||
776 | } | ||
777 | |||
778 | static void | ||
779 | xbsd_change_fstype(void) | ||
780 | { | ||
781 | int i; | ||
782 | |||
783 | i = xbsd_get_part_index(xbsd_dlabel.d_npartitions); | ||
784 | xbsd_dlabel.d_partitions[i].p_fstype = read_hex(xbsd_fstypes); | ||
785 | } | ||
786 | |||
787 | static int | ||
788 | xbsd_get_part_index(int max) | ||
789 | { | ||
790 | niro | 816 | char prompt[sizeof("Partition (a-%c): ") + 16]; |
791 | niro | 532 | char l; |
792 | |||
793 | niro | 816 | snprintf(prompt, sizeof(prompt), "Partition (a-%c): ", 'a' + max - 1); |
794 | niro | 532 | do |
795 | l = tolower(read_nonempty(prompt)); | ||
796 | while (l < 'a' || l > 'a' + max - 1); | ||
797 | return l - 'a'; | ||
798 | } | ||
799 | |||
800 | static int | ||
801 | xbsd_check_new_partition(int *i) | ||
802 | { | ||
803 | /* room for more? various BSD flavours have different maxima */ | ||
804 | if (xbsd_dlabel.d_npartitions == BSD_MAXPARTITIONS) { | ||
805 | int t; | ||
806 | |||
807 | for (t = 0; t < BSD_MAXPARTITIONS; t++) | ||
808 | if (xbsd_dlabel.d_partitions[t].p_size == 0) | ||
809 | break; | ||
810 | |||
811 | if (t == BSD_MAXPARTITIONS) { | ||
812 | niro | 816 | printf("The maximum number of partitions has been created\n"); |
813 | niro | 532 | return 0; |
814 | } | ||
815 | } | ||
816 | |||
817 | *i = xbsd_get_part_index(BSD_MAXPARTITIONS); | ||
818 | |||
819 | if (*i >= xbsd_dlabel.d_npartitions) | ||
820 | xbsd_dlabel.d_npartitions = (*i) + 1; | ||
821 | |||
822 | if (xbsd_dlabel.d_partitions[*i].p_size != 0) { | ||
823 | niro | 816 | printf("This partition already exists\n"); |
824 | niro | 532 | return 0; |
825 | } | ||
826 | |||
827 | return 1; | ||
828 | } | ||
829 | |||
830 | static void | ||
831 | xbsd_list_types(void) | ||
832 | { | ||
833 | list_types(xbsd_fstypes); | ||
834 | } | ||
835 | |||
836 | static uint16_t | ||
837 | xbsd_dkcksum(struct xbsd_disklabel *lp) | ||
838 | { | ||
839 | uint16_t *start, *end; | ||
840 | uint16_t sum = 0; | ||
841 | |||
842 | start = (uint16_t *) lp; | ||
843 | end = (uint16_t *) &lp->d_partitions[lp->d_npartitions]; | ||
844 | while (start < end) | ||
845 | sum ^= *start++; | ||
846 | return sum; | ||
847 | } | ||
848 | |||
849 | static int | ||
850 | niro | 816 | xbsd_initlabel(struct partition *p) |
851 | niro | 532 | { |
852 | niro | 816 | struct xbsd_disklabel *d = &xbsd_dlabel; |
853 | niro | 532 | struct xbsd_partition *pp; |
854 | |||
855 | get_geometry(); | ||
856 | memset(d, 0, sizeof(struct xbsd_disklabel)); | ||
857 | |||
858 | d->d_magic = BSD_DISKMAGIC; | ||
859 | |||
860 | if (strncmp(disk_device, "/dev/sd", 7) == 0) | ||
861 | d->d_type = BSD_DTYPE_SCSI; | ||
862 | else | ||
863 | d->d_type = BSD_DTYPE_ST506; | ||
864 | |||
865 | #if !defined(__alpha__) | ||
866 | d->d_flags = BSD_D_DOSPART; | ||
867 | #else | ||
868 | d->d_flags = 0; | ||
869 | #endif | ||
870 | d->d_secsize = SECTOR_SIZE; /* bytes/sector */ | ||
871 | niro | 816 | d->d_nsectors = g_sectors; /* sectors/track */ |
872 | d->d_ntracks = g_heads; /* tracks/cylinder (heads) */ | ||
873 | d->d_ncylinders = g_cylinders; | ||
874 | d->d_secpercyl = g_sectors * g_heads;/* sectors/cylinder */ | ||
875 | niro | 532 | if (d->d_secpercyl == 0) |
876 | d->d_secpercyl = 1; /* avoid segfaults */ | ||
877 | d->d_secperunit = d->d_secpercyl * d->d_ncylinders; | ||
878 | |||
879 | d->d_rpm = 3600; | ||
880 | d->d_interleave = 1; | ||
881 | d->d_trackskew = 0; | ||
882 | d->d_cylskew = 0; | ||
883 | d->d_headswitch = 0; | ||
884 | d->d_trkseek = 0; | ||
885 | |||
886 | d->d_magic2 = BSD_DISKMAGIC; | ||
887 | d->d_bbsize = BSD_BBSIZE; | ||
888 | d->d_sbsize = BSD_SBSIZE; | ||
889 | |||
890 | #if !defined(__alpha__) | ||
891 | d->d_npartitions = 4; | ||
892 | pp = &d->d_partitions[2]; /* Partition C should be NetBSD partition */ | ||
893 | |||
894 | pp->p_offset = get_start_sect(p); | ||
895 | pp->p_size = get_nr_sects(p); | ||
896 | pp->p_fstype = BSD_FS_UNUSED; | ||
897 | pp = &d->d_partitions[3]; /* Partition D should be whole disk */ | ||
898 | |||
899 | pp->p_offset = 0; | ||
900 | pp->p_size = d->d_secperunit; | ||
901 | pp->p_fstype = BSD_FS_UNUSED; | ||
902 | niro | 816 | #else |
903 | niro | 532 | d->d_npartitions = 3; |
904 | pp = &d->d_partitions[2]; /* Partition C should be | ||
905 | the whole disk */ | ||
906 | pp->p_offset = 0; | ||
907 | pp->p_size = d->d_secperunit; | ||
908 | pp->p_fstype = BSD_FS_UNUSED; | ||
909 | #endif | ||
910 | |||
911 | return 1; | ||
912 | } | ||
913 | |||
914 | /* | ||
915 | * Read a xbsd_disklabel from sector 0 or from the starting sector of p. | ||
916 | * If it has the right magic, return 1. | ||
917 | */ | ||
918 | static int | ||
919 | niro | 816 | xbsd_readlabel(struct partition *p) |
920 | niro | 532 | { |
921 | niro | 816 | struct xbsd_disklabel *d; |
922 | niro | 532 | int t, sector; |
923 | |||
924 | niro | 816 | if (!bsd_globals_ptr) |
925 | bsd_globals_ptr = xzalloc(sizeof(*bsd_globals_ptr)); | ||
926 | niro | 532 | |
927 | niro | 816 | d = &xbsd_dlabel; |
928 | |||
929 | niro | 532 | /* p is used only to get the starting sector */ |
930 | #if !defined(__alpha__) | ||
931 | sector = (p ? get_start_sect(p) : 0); | ||
932 | niro | 816 | #else |
933 | niro | 532 | sector = 0; |
934 | #endif | ||
935 | |||
936 | niro | 816 | seek_sector(sector); |
937 | if (BSD_BBSIZE != full_read(dev_fd, disklabelbuffer, BSD_BBSIZE)) | ||
938 | niro | 532 | fdisk_fatal(unable_to_read); |
939 | |||
940 | memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], | ||
941 | sizeof(struct xbsd_disklabel)); | ||
942 | |||
943 | if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC) | ||
944 | return 0; | ||
945 | |||
946 | for (t = d->d_npartitions; t < BSD_MAXPARTITIONS; t++) { | ||
947 | d->d_partitions[t].p_size = 0; | ||
948 | d->d_partitions[t].p_offset = 0; | ||
949 | d->d_partitions[t].p_fstype = BSD_FS_UNUSED; | ||
950 | } | ||
951 | |||
952 | if (d->d_npartitions > BSD_MAXPARTITIONS) | ||
953 | niro | 984 | printf("Warning: too many partitions (%u, maximum is %u)\n", |
954 | niro | 532 | d->d_npartitions, BSD_MAXPARTITIONS); |
955 | return 1; | ||
956 | } | ||
957 | |||
958 | static int | ||
959 | niro | 816 | xbsd_writelabel(struct partition *p) |
960 | niro | 532 | { |
961 | niro | 816 | struct xbsd_disklabel *d = &xbsd_dlabel; |
962 | niro | 532 | unsigned int sector; |
963 | |||
964 | #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__hppa__) | ||
965 | sector = get_start_sect(p) + BSD_LABELSECTOR; | ||
966 | #else | ||
967 | niro | 984 | (void)p; /* silence warning */ |
968 | niro | 532 | sector = BSD_LABELSECTOR; |
969 | #endif | ||
970 | |||
971 | d->d_checksum = 0; | ||
972 | d->d_checksum = xbsd_dkcksum(d); | ||
973 | |||
974 | /* This is necessary if we want to write the bootstrap later, | ||
975 | otherwise we'd write the old disklabel with the bootstrap. | ||
976 | */ | ||
977 | memmove(&disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], | ||
978 | d, sizeof(struct xbsd_disklabel)); | ||
979 | |||
980 | #if defined(__alpha__) && BSD_LABELSECTOR == 0 | ||
981 | alpha_bootblock_checksum(disklabelbuffer); | ||
982 | niro | 816 | seek_sector(0); |
983 | xwrite(dev_fd, disklabelbuffer, BSD_BBSIZE); | ||
984 | niro | 532 | #else |
985 | niro | 816 | seek_sector(sector); |
986 | lseek(dev_fd, BSD_LABELOFFSET, SEEK_CUR); | ||
987 | xwrite(dev_fd, d, sizeof(*d)); | ||
988 | niro | 532 | #endif |
989 | sync_disks(); | ||
990 | return 1; | ||
991 | } | ||
992 | |||
993 | |||
994 | #if !defined(__alpha__) | ||
995 | static int | ||
996 | xbsd_translate_fstype(int linux_type) | ||
997 | { | ||
998 | switch (linux_type) { | ||
999 | case 0x01: /* DOS 12-bit FAT */ | ||
1000 | case 0x04: /* DOS 16-bit <32M */ | ||
1001 | case 0x06: /* DOS 16-bit >=32M */ | ||
1002 | case 0xe1: /* DOS access */ | ||
1003 | case 0xe3: /* DOS R/O */ | ||
1004 | case 0xf2: /* DOS secondary */ | ||
1005 | return BSD_FS_MSDOS; | ||
1006 | case 0x07: /* OS/2 HPFS */ | ||
1007 | return BSD_FS_HPFS; | ||
1008 | default: | ||
1009 | return BSD_FS_OTHER; | ||
1010 | } | ||
1011 | } | ||
1012 | |||
1013 | static void | ||
1014 | xbsd_link_part(void) | ||
1015 | { | ||
1016 | int k, i; | ||
1017 | struct partition *p; | ||
1018 | |||
1019 | niro | 816 | k = get_partition(1, g_partitions); |
1020 | niro | 532 | |
1021 | if (!xbsd_check_new_partition(&i)) | ||
1022 | return; | ||
1023 | |||
1024 | p = get_part_table(k); | ||
1025 | |||
1026 | xbsd_dlabel.d_partitions[i].p_size = get_nr_sects(p); | ||
1027 | xbsd_dlabel.d_partitions[i].p_offset = get_start_sect(p); | ||
1028 | xbsd_dlabel.d_partitions[i].p_fstype = xbsd_translate_fstype(p->sys_ind); | ||
1029 | } | ||
1030 | #endif | ||
1031 | |||
1032 | #if defined(__alpha__) | ||
1033 | static void | ||
1034 | alpha_bootblock_checksum(char *boot) | ||
1035 | { | ||
1036 | uint64_t *dp, sum; | ||
1037 | int i; | ||
1038 | |||
1039 | dp = (uint64_t *)boot; | ||
1040 | sum = 0; | ||
1041 | for (i = 0; i < 63; i++) | ||
1042 | sum += dp[i]; | ||
1043 | dp[63] = sum; | ||
1044 | } | ||
1045 | #endif /* __alpha__ */ | ||
1046 | |||
1047 | niro | 816 | /* Undefine 'global' tricks */ |
1048 | #undef disklabelbuffer | ||
1049 | #undef xbsd_dlabel | ||
1050 | |||
1051 | niro | 532 | #endif /* OSF_LABEL */ |