1
/* silo - bootblock installation program
3
Copyright (C) 1996 Maurizio Plaza
4
1996,98,99,2000 Jakub Jelinek
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21
#if !defined(VERSION) || !defined(IMGVERSION)
22
#error VERSION and IMGVERSION must be defined
24
#define DFL_CONFIG "/etc/silo.conf"
25
#define DFL_BACKUP "/boot/old.b"
26
#define DFL_PRIMARY "/boot/first.b"
27
#define DFL_PRIMARY_U "/boot/ultra.b"
28
#define DFL_SECONDARY "/boot/second.b"
31
#include "../second/fs/ufs.c"
41
#include <sys/ioctl.h>
43
# include <sys/stat.h>
44
# include <sys/types.h>
45
# include <sys/time.h>
46
# define _LINUX_STAT_H
48
# define _LINUX_TIME_H
49
# define _LINUX_STRING_H_
52
# include <linux/fs.h>
53
# include <ext2fs/ext2_fs.h>
54
# include <ext2fs/ext2fs.h>
55
# include <scsi/scsi.h>
58
# include <sys/sysmacros.h>
59
# define mmajor(x) major(x)
60
# define mminor(x) minor(x)
61
# define mmakedev(x,y) makedev(x,y)
63
# define mmajor(x) (int)((x) >> 8)
64
# define mminor(x) (int)((x) & 0xff)
65
# define mmakedev(major, minor) (((major) << 8) | (minor))
68
#elif defined (__sun__)
69
# include <sys/types.h>
70
# include <sys/stat.h>
71
# include <non-linux/ext2_fs.h>
72
# include <ext2fs/ext2fs.h>
76
static int ufs_blocks (struct hwdevice *, ino_t);
78
# error "Unknown system"
82
#include <sys/utsname.h>
89
#include "../first/first.h"
90
#include "../first/ultra.h"
91
#include "../first/fd.h"
92
#include "../first/ieee32.h"
94
#define DIGIT_OFFSET (DIGIT_OFFSET_TMP + 0x223)
95
#define LETTER_OFFSET (LETTER_OFFSET_TMP + 0x223)
96
#define NUMBER_OFFSET (NUMBER_OFFSET_TMP + 0x223)
97
#define ULTRA_LETTER_OFFSET (ULTRA_LETTER_OFFSET_TMP + 0x223)
98
#define ULTRA_NUMBER_OFFSET (ULTRA_NUMBER_OFFSET_TMP + 0x223)
99
#define FD_DIGIT_OFFSET (FD_DIGIT_OFFSET_TMP + 0x223)
100
#define FD_LETTER_OFFSET (FD_LETTER_OFFSET_TMP + 0x223)
102
/* Checks our config file for errors */
103
int confcheck(char*);
104
char *cfg_get_strg (char *, char *);
105
int cfg_get_flag (char *, char *);
106
static int allow_confchk_fail = 0;
108
/* This is just so that we don't have to fight with incompatible ufs_fs.h headers */
109
#define SILO_UFS_MAGIC 0x00011954
110
struct silo_ufs_super_block {
111
unsigned char xxx1[36];
112
unsigned int fs_fsize;
113
unsigned char xxx2[1332];
114
unsigned int fs_magic;
117
struct sun_disklabel {
118
unsigned char info[128]; /* Informative text string */
119
unsigned char spare[292]; /* Boot information etc. */
120
unsigned short rspeed; /* Disk rotational speed */
121
unsigned short pcylcount; /* Physical cylinder count */
122
unsigned short sparecyl; /* extra sects per cylinder */
123
unsigned char spare2[4]; /* More magic... */
124
unsigned short ilfact; /* Interleave factor */
125
unsigned short ncyl; /* Data cylinder count */
126
unsigned short nacyl; /* Alt. cylinder count */
127
unsigned short ntrks; /* Tracks per cylinder */
128
unsigned short nsect; /* Sectors per track */
129
unsigned char spare3[4]; /* Even more magic... */
130
struct sun_partition {
131
unsigned long start_cylinder;
132
unsigned long num_sectors;
134
unsigned short magic; /* Magic number */
135
unsigned short csum; /* Label xor'd checksum */
138
enum typeenum { TYPE_UNKNOWN, TYPE_SCSI, TYPE_IDE };
151
struct hwdevice *next;
154
__u32 swab32 (__u32 value)
156
return ((value >> 24) | ((value >> 8) & 0xff00) |
157
((value << 8) & 0xff0000) | (value << 24));
160
__u16 swab16 (__u16 value)
162
return (value >> 8) | (value << 8);
164
#define bswab32(x) (x)
165
#define bswab16(x) (x)
168
int prombug = 1; /* Number of gigabytes PROM is able to boot from. if ultra, it is always inf. */
172
int floppy_image = 0; /* Calculate cross checksums. */
173
char *flash_image = NULL; /* Open this and calculate flash checksum. */
174
char *first, *second, *old; /* File names */
177
enum fs_type { unknownfs, ext2fs, ufsfs, romfs } fstype = unknownfs;
179
static void silo_fatal(char *fmt,...)
183
fprintf (stderr, "Fatal error: ");
184
vfprintf (stderr, fmt, ap);
190
int devopen (const char *name, int flags)
192
int fd = open (name, flags);
193
if (fd < 0 && errno == ENOENT) {
196
if (*name == '/') name++;
197
fd = open (name, flags);
204
int check_fs (int fd)
206
struct silo_ufs_super_block ufs;
207
struct ext2_super_block sb; /* Super Block Info */
208
struct romfs_super_block {
215
if (lseek (fd, 1024, 0) != 1024 || read (fd, &sb, sizeof (sb)) != sizeof (sb))
216
silo_fatal("Cannot read Super Block!");
217
if (swab16 (sb.s_magic) == EXT2_SUPER_MAGIC) {
218
if (fstype == unknownfs) fstype = ext2fs;
219
return 1024 << swab32 (sb.s_log_block_size);
221
if (lseek (fd, 0, 0) != 0 || read (fd, &rsd, sizeof(rsd)) != sizeof (rsd))
223
if (!strncmp ((char *)&rsd, "-rom1fs-", 8)) {
224
if (fstype == unknownfs) fstype = romfs;
227
if (lseek (fd, 8192, 0) != 8192 || read (fd, &ufs, sizeof (ufs)) != sizeof (ufs))
229
if (bswab32 (ufs.fs_magic) == SILO_UFS_MAGIC) {
230
if (fstype == unknownfs) fstype = ufsfs;
236
void read_sb (struct hwdevice *hwdev)
240
struct sun_disklabel *sdl;
245
if ((fd = devopen ((char *)hwdev->dev, O_RDONLY)) == -1)
246
silo_fatal("Cannot open superblock on %s", hwdev->dev);
247
hwdev->bs = check_fs (fd);
248
if (hwdev->bs == (unsigned short)-1)
249
silo_fatal("File systems other than ext2, ext3, ufs and romfs "
250
"not yet supported", hwdev->dev);
252
hwdev->nsect = hwdev->bs / 512;
253
if (hwdev->part == -1)
255
sdl = (struct sun_disklabel *) &buff;
256
if ((fd = devopen (hwdev->wholedev, O_RDONLY)) == -1)
257
silo_fatal("Error opening %s", hwdev->wholedev);
258
if (read (fd, buff, sizeof (buff)) != sizeof (buff))
259
silo_fatal("Error reading %s's label", hwdev->wholedev);
260
for (i = 0; i < 8; i++) {
261
if (i == 2) continue;
262
if (!sdl->partitions[i].start_cylinder && sdl->partitions[i].num_sectors) {
265
p = strchr (hwdev->wholedev, 0);
266
*p++ = '1' + hwdev->partat0;
272
if (i == 8 && !sdl->partitions[2].start_cylinder && sdl->partitions[2].num_sectors) {
276
p = strchr (hwdev->wholedev, 0);
277
*p++ = '1' + hwdev->partat0;
282
for (i = 0; i < 8; i++) {
283
if (!sdl->partitions[i].start_cylinder) {
290
silo_fatal("In order to install SILO you must start at least "
291
"one partition on cylinder\n"
292
"0. Consider setting %s3 as WHOLE_DISK (starting at 0 "
293
"and ending at disk end)\n"
294
"and %s1 starting on cylinder 0 (both will make your "
295
"life easier)\n", hwdev->wholedev, hwdev->wholedev);
297
hwdev->doff = bswab16(sdl->ntrks) * bswab16(sdl->nsect) * bswab32(sdl->partitions[hwdev->part].start_cylinder);
301
#define SECOND_B_TEMPL "%s___@#$%d___"
303
void gpb_cleanup(char *filename, int n)
308
for (i = 1; i <= n; i++) {
309
sprintf (buffer, SECOND_B_TEMPL, filename, i);
314
void make_room_for_raid1 (struct hwdevice *hwdev, char *name)
323
if ((fd = open (name, O_RDWR)) == -1)
324
silo_fatal("Cannot open %s", name);
325
if (fstat (fd, &st) < 0)
326
silo_fatal("Couldn't stat %s", name);
327
if (lseek (fd, 0x90c, 0) != 0x90c || read(fd, buf, 12) != 12)
328
silo_fatal("Could not read %s version and length header", name);
329
if (memcmp (buf, "SILO", 4))
330
silo_fatal("Second stage %s too old", name);
331
len = *(int *)&buf[8];
332
if (len % 512 || st.st_size < len || (st.st_size - len) % 2048)
333
silo_fatal("Second stage %s has wrong size", name);
334
i = raid1 - 1 - (st.st_size - len) / 2048;
336
if (lseek (fd, len, 0) != len)
337
silo_fatal("Could not seek in %s", name);
339
/* Should not use ftruncate here, because we cannot have fs
341
for (i = 4 * i; i > 0; i--) {
342
if (write (fd, buf, 512) != 512)
343
silo_fatal("Could not write to %s", name);
350
int get_partition_blocks (struct hwdevice *hwdev, char *filename)
357
char *name = filename;
362
if ((fd = open (name, O_RDONLY)) == -1) {
363
gpb_cleanup(filename, movecount);
364
silo_fatal("Cannot find %s", name);
366
if (fstat (fd, &st) < 0) {
367
gpb_cleanup(filename, movecount);
368
silo_fatal("Couldn't stat %s", name);
373
if (fstype == romfs) {
374
char *p = strrchr (name, '/');
376
if (p) p++; else p = name;
377
start = (long)st.st_ino + 16 + ((strlen(p) + 16) & ~15);
379
silo_fatal("File %s on romfs not aligned on 512B boundary. "
380
"Use genromfs -a to generate the image", name);
381
start = hwdev->doff + start / 512;
382
if (flash_image) start += 1024 / 512; /* make room for ieee32 */
383
for (j = 0; j * 512 < size; j++)
384
hwdev->blocks[j] = start + j;
385
hwdev->blocks[j] = 0;
389
for (i = 0, j = 0;; i++) {
391
if ((j << 9) >= size || ioctl (fd, FIBMAP, &block) < 0)
395
silo_fatal("Filesystem holes are not yet supported for "
396
"second stage loader. Mail "
397
"silo-general@lists.sparc-boot.org");
401
if (prombug && block * hwdev->nsect + hwdev->doff >= 0x200000 * prombug) {
405
silo_fatal("Your %s is located above the "
406
"magic %dGB boundary from the "
407
"start of the disk\n"
408
"on one of the RAID1 mirrors. "
409
"Please make sure it is below the "
411
"mirrors.", filename, prombug);
414
silo_fatal("Not enough memory");
415
if (read (fd, buf, size) != size)
416
silo_fatal("Cannot read from %s", filename);
420
sprintf (buffer, SECOND_B_TEMPL, filename, movecount);
422
fd = creat (name, 0644);
423
if (!fd || write (fd, buf, size) != size) {
424
gpb_cleanup(filename, movecount);
425
silo_fatal("Your %s is located above the magic %dGB "
426
"boundary from the start of the disk.\n"
427
"Please move it down, so that SILO first "
428
"stage loader can load it.",
434
gpb_cleanup(filename, movecount);
435
silo_fatal("Your %s is located above the magic %dGB boundary "
436
"from the start of the disk.\n"
437
"Please move it down, so that SILO first stage loader can load it.", filename, prombug);
439
for (k = 0; k < hwdev->nsect; k++)
440
hwdev->blocks[j++] = block * hwdev->nsect + hwdev->doff + k;
442
hwdev->blocks[j] = 0;
446
/* As current RAID1 does not reserve any space for bootblocks, non-masterboot
447
would resync away the bootblock unless second.b starts on exactly the same
448
offsets in each device */
449
if (memcmp (hwdevs->blocks, hwdev->blocks, sizeof(hwdev->blocks)))
450
silo_fatal("With silo -t on RAID1 all mirrors must "
451
"start at the same offset\n"
452
"from the start of the disk.");
454
for (i = 0; i < 4; i++)
455
hwdev->blocks[i] = hwdev->blocks[second_b_len / 512 + (hwdev->id - 1) * 4 + i];
460
if (rename (name, filename) < 0) {
461
gpb_cleanup(filename, movecount - 1);
462
silo_fatal("Cannot rename a suitably located copy (below 1GB "
463
"from start of disk) of %s to it's old position.\n"
464
"Please check %s\n", filename, filename);
466
gpb_cleanup(filename, movecount - 1);
468
#elif defined(__sun__)
469
ufs_blocks (hwdev, st.st_ino);
475
char *new_root = NULL;
477
void write_block_device (struct hwdevice *hwdev)
484
if ((fd = devopen (masterboot ? hwdev->wholedev : hwdev->dev,
486
silo_fatal("Cannot open %s", hwdev->dev);
487
if (flash_image) off = IEEE32_OFFSET;
488
else if (floppy_image) off = 1020 + 512 - 4;
490
if (lseek (fd, off, SEEK_SET) != off)
491
silo_fatal("Seek error on %s", hwdev->dev);
494
for (j = 0; j < 512 && hwdev->blocks[j]; j++);
497
rc = write (fd, &tmp, 4);
499
silo_fatal("Couldn't write to %s", hwdev->dev);
501
tmp = bswab32 (hwdev->blocks[0]);
502
rc = write (fd, &tmp, 4);
504
silo_fatal("Couldn't write to %s", hwdev->dev);
506
if (!ultra || floppy_image) {
508
offset = FD_DIGIT_OFFSET;
510
offset = DIGIT_OFFSET;
511
if (lseek (fd, offset, SEEK_SET) != offset)
512
silo_fatal("Seek error on %s", hwdev->dev);
513
part = hwdev->partat0 + '0';
514
rc = write (fd, &part, 1);
516
silo_fatal("Couldn't write to %s", hwdev->dev);
519
offset = FD_LETTER_OFFSET;
521
offset = ULTRA_LETTER_OFFSET;
523
offset = LETTER_OFFSET;
524
if (lseek (fd, offset, SEEK_SET) != offset)
525
silo_fatal("Seek error on %s", hwdev->dev);
526
part = hwdev->partat0 + 'a';
527
rc = write (fd, &part, 1);
529
silo_fatal("Couldn't write to %s", hwdev->dev);
532
offset = ULTRA_NUMBER_OFFSET;
534
offset = NUMBER_OFFSET;
535
if (lseek (fd, offset, SEEK_SET) != offset)
536
silo_fatal("Seek error on %s", hwdev->dev);
539
part = hwdev->id + 1;
540
rc = write (fd, &part, 1);
542
silo_fatal("Couldn't write to %s", hwdev->dev);
548
void write_block_tables (struct hwdevice *hwdev, char *filename, char *config_file, int partno)
553
unsigned char partno;
554
unsigned char partat0;
555
unsigned char raid_dsk_number;
557
unsigned char silover[8];
559
unsigned char partnos[32];
560
unsigned char partat0s[32];
565
if ((fd = open (filename, O_RDWR)) == -1) {
567
silo_fatal("Cannot open %s", filename);
568
if ((fd = open (filename, O_RDONLY)) >= 0) {
569
close (fd); /* Maybe it is romfs */
570
if ((fd = devopen (hwdev->wholedev, O_RDWR)) == -1)
571
silo_fatal("Cannot open %s", hwdev->wholedev);
574
silo_fatal("Cannot open %s", filename);
577
char *p = (char *)hwdev->blocks, *pend = p + sizeof (hwdev->blocks);
580
silo_fatal("RAID1 not supported with read-only filesystems");
581
for (i = 0, rc = 0; p < pend; i++, p+=512) {
582
if (lseek (fd, hwdev->blocks [i] * 512, SEEK_SET) != hwdev->blocks [i] * 512)
583
silo_fatal("Cannot seek in %s", filename);
584
rc += write (fd, p, 512);
587
if (lseek (fd, 0, SEEK_SET) != 0)
588
silo_fatal("Cannot seek in %s", filename);
589
rc = write (fd, hwdev->blocks, sizeof (hwdev->blocks));
591
if (rc != sizeof (hwdev->blocks))
592
silo_fatal("Couldn't write to %s", filename);
593
if (lseek (fd, second_b_len, SEEK_SET) != second_b_len)
594
silo_fatal("Cannot seek in %s", filename);
595
for (d = hwdev->next; d; d = d->next)
596
rc = write (fd, d->blocks, sizeof (d->blocks));
599
if (rc != sizeof (hwdev->blocks))
600
silo_fatal("Couldn't write to %s", filename);
602
i = hwdev->blocks [0x808/512] * 512 + 0x808 % 512;
605
if (lseek (fd, i, SEEK_SET) != i)
606
silo_fatal("Cannot seek in %s", filename);
607
if (read (fd, &buffer, sizeof(buffer)) != sizeof(buffer))
608
silo_fatal("Couldn't read from %s", filename);
609
if (lseek (fd, i, SEEK_SET) != i)
610
silo_fatal("Cannot seek in %s", filename);
611
if (buffer.l != 'L' || memcmp(buffer.silover, "SILO", 4))
612
silo_fatal("Corrupted %s or second stage with incorrect version",
614
buffer.partno = partno;
615
buffer.partat0 = hwdev->partat0;
616
buffer.raid_dsk_number = 0;
617
strncpy (buffer.silo_conf, config_file, 255);
618
buffer.silo_conf[255] = 0;
620
for (d = hwdev; d; d = d->next) {
621
buffer.partnos[d->id] = d->part + 1;
622
buffer.partat0s[d->id] = d->partat0;
625
if (write (fd, &buffer, sizeof(buffer)) != sizeof(buffer))
626
silo_fatal("Couldn't write to %s", filename);
628
for (d = hwdev; d; d = d->next)
629
write_block_device (d);
635
"SILO " VERSION " Sparc Improved boot LOader\n"
636
"Usage: %s [options]\n"
638
" -r root_path chroots into root_path (all paths relative to this)\n"
639
" -b secondary use secondary as second stage loader instead of /boot/second.b\n"
640
" -i primary install primary as first stage loader (instead of\n"
641
" /boot/first.b). If -i is specified, your boot block will be\n"
642
" always overwritten (by default only if it is not SILO or has\n"
644
" -C config specify alternate config file instead of /etc/silo.conf\n"
645
" (your config file has to reside on the same physical disk as\n"
646
" secondary - perhaps on different partitions - on that disk's\n"
647
" bootblock will be primary installed)\n"
648
" -S backup force saving your old bootblock into backup\n"
649
" -s backup save your old bootblock only if backup doesn't exist yet\n"
650
" -p 0|2 force prom version to be 0 or 2 (default is auto-detection)\n"
651
" -t store bootblock on the same partition as second stage loader\n"
652
" (default is into the bootblock of the whole disk)\n"
653
" -f force overwriting of bootblock\n"
655
" -v print your PROM major version (0 or 2) and exit\n"
656
" -u force v9 (ultrasparc) target, even on v8\n"
657
" -U force v8 target, even on v9\n"
658
" -F make a romfs bootable floppy\n"
659
" -J image make a romfs bootable flash image\n"
660
" -J and -F are incompatible\n"
661
" -a Allow silo.conf syntax check to fail\n"
666
int examine_bootblock (char *device, char *filename, int do_backup)
668
char buffer[512 * 15];
673
if ((fd = devopen (device, O_RDONLY)) == -1)
674
silo_fatal("Cannot open %s", device);
675
if (lseek (fd, 512, 0) != 512)
676
silo_fatal("Couldn't seek on %s", device);
677
if (read (fd, buffer, sizeof (buffer)) != sizeof(buffer))
678
silo_fatal("Couldn't read your old bootblock");
680
if (memcmp (buffer + 24, "SILO" IMGVERSION, 8))
684
if ((fp = fopen (filename, "w")) == NULL) {
687
silo_fatal("Cannot open file for saving backup of your bootblock");
689
if ((rc = fwrite (buffer, 1, sizeof (buffer), fp)) != sizeof (buffer))
690
silo_fatal("Couldn't write to %s backup of your bootblock",
697
void flash_check_sum (char *data, unsigned int dsize)
701
for (sum = 0; dsize-- != 0; data++)
702
sum += *((unsigned char *)data);
710
void install_first_stage (char *device, char *filename)
716
struct sun_disklabel sdl;
718
if ((fd = devopen (device, floppy_image ? O_RDWR : O_WRONLY)) == -1)
719
silo_fatal("Couldn't open device %s for writing", device);
720
if ((fp = fopen (filename, "r")) == NULL)
721
silo_fatal("Couldn't open file %s", filename);
722
rc = fread (buff, 1, (floppy_image || flash_image) ? 1024 : 512, fp);
724
silo_fatal("Couldn't read new silo bootblock from %s", filename);
731
if (lseek (fd, 0, 0))
732
silo_fatal("Couldn't seek on %s", device);
733
if (read(fd, (char *)&sdl, 512) != 512)
734
silo_fatal("Couldn't read on %s", device);
735
if (lseek (fd, 0, 0))
736
silo_fatal("Couldn't seek on %s", device);
737
if (strncmp ((char *)&sdl, "-rom1fs-", 8))
738
silo_fatal("Couldn't find romfs image on %s", device);
739
memcpy (((char *)&sdl) + 128, floppy_label + 128, 512 - 128);
740
ush = (unsigned short *)&sdl;
742
/* This is a bit difficult, since we have to make two checksums right:
743
partition table expects xor of all u16 in the first 512 bytes to be 0,
744
romfs expects sum of all u32 in the first 512 bytes to be 0.
745
Algorithm written by Gert-jan Los (los@lsdb.bwl.uni-mannheim.de). */
746
sdl.csum = 0xdead; /* Could be zero... */
747
ush[6] = 0; ush[7] = 0;
748
memset (ush + 60, 0, 8);
749
for (i = 0, d = 0; i < 256; i+=2)
750
d += *(unsigned int *)(ush + i);
751
for (i = 0, x = 0; i < 256; i++)
754
s = (x ^ 1) << 16 ^ 1;
757
*(unsigned int *)(ush + 6) = s;
759
*(unsigned int *)(ush + 60) = (-d/2);
760
*(unsigned int *)(ush + 62) = (-d/2);
762
if (write (fd, &sdl, 512) != 512)
763
silo_fatal("Couldn't write new partition table to %s", device);
764
} else if (flash_image) {
766
* Make sure that both block table address and checksum fit.
769
silo_fatal("Flash bootblock is too large");
771
* Here we do an assumption which is not quite safe.
772
* PROM gets the size looking at section headers,
773
* we use the file size for that. If there is any padding,
774
* these sizes will diverge. So far everything was ok.
776
flash_check_sum (buff, rc);
778
} else if (lseek (fd, 512, 0) != 512)
779
silo_fatal("Couldn't seek on %s", device);
780
if (write (fd, buff, rc) != rc)
781
silo_fatal("Couldn't write new silo bootblock to %s", device);
786
int get_prom_ver(int use_prom)
788
#if defined(__linux__)
789
FILE *f = fopen("/proc/cpuinfo","r");
795
while (fgets(buffer, 1024, f)) {
796
if (!strncmp (buffer, "promlib", 7)) {
797
p = strstr (buffer, "Version ");
800
if (*p == '0' || (*p >= '2' && *p <= '3')) {
804
} else if (!strncmp (buffer, "prom", 4) &&
805
isspace(buffer[4])) {
806
p = strchr (buffer, ':');
809
while (isspace (*p)) p++;
811
case '2': if (p[1] == '.' && isdigit(p[2]) &&
812
(p[2] >= '6' || isdigit(p[3])))
814
case '3': prombug = 0; break;
821
#elif defined(__sun__)
825
ver = prom_getversion ();
830
/* Canonicalize path, and return a new path. Do everything in situ.
831
The new path differs from path in:
832
Multiple `/'s are collapsed to a single `/'.
833
Leading `./'s and trailing `/.'s are removed.
834
Trailing `/'s are removed.
835
Non-leading `../'s and trailing `..'s are handled by removing
836
portions of the path. */
837
char *canonicalize_pathname (char *path)
842
stub_char = (*path == '/') ? '/' : '.';
844
/* Walk along path looking for things to compact. */
850
while (path[i] && path[i] != '/')
855
/* If we didn't find any slashes, then there is nothing left to do. */
859
/* Handle multiple `/'s in a row. */
860
while (path[i] == '/')
863
if ((start + 1) != i) {
864
strcpy (path + start + 1, path + i);
868
/* Handle backquoted `/'. */
869
if (start > 0 && path[start - 1] == '\\')
872
/* Check for trailing `/'. */
873
if (start && !path[i]) {
879
/* Check for `../', `./' or trailing `.' by itself. */
880
if (path[i] == '.') {
881
/* Handle trailing `.' by itself. */
886
if (path[i + 1] == '/') {
887
strcpy (path + i, path + i + 1);
892
/* Handle `../' or trailing `..' by itself.
893
Remove the previous ?/ part with the exception of
894
../, which we should leave intact. */
895
if (path[i + 1] == '.' && (path[i + 2] == '/' || !path[i + 2])) {
896
while (--start > -1 && path[start] != '/');
897
if (!strncmp (path + start + 1, "../", 3))
899
strcpy (path + start + 1, path + i + 2);
913
char *find_dev(dev_t number)
916
# define DEVNAME "/dev"
918
# define DEVNAME "/dev/dsk"
923
static char name[PATH_MAX+2];
928
if (!number) return NULL;
929
for (i = 0; i < 2; i++) {
931
if (i == 1 && oldroot != -1) {
935
if ((dp = opendir(p)) == NULL) continue;
937
p = strchr (name + 1, 0);
939
while ((dir = readdir(dp))) {
940
strcpy(p,dir->d_name);
941
if (stat(name + 1,&s) < 0) continue;
942
if (S_ISBLK(s.st_mode) && s.st_rdev == number) {
944
if (i == 1 && oldroot != -1) {
953
if (i && oldroot != -1)
958
struct hwdevice *get_device(int majno, int minno)
960
char dev[1024], wholedev[1024];
961
struct hwdevice *hwdev;
963
enum typeenum type = TYPE_UNKNOWN;
974
unit = (majno & 7) * 16 + ((minno & 0xf0) >> 4);
977
sprintf (dev, "/dev/sd%c%c", unit + 'a', part + '0');
978
strcpy (wholedev, dev);
981
sprintf (dev, "/dev/sd%c%c%c", (unit / 26) + 'a' - 1, (unit % 26) + 'a', part + '0');
982
strcpy (wholedev, dev);
988
case 3: type = TYPE_IDE; unit = 0; goto do_ide;
989
case 22:type = TYPE_IDE; unit = 2; goto do_ide;
991
case 34:type = TYPE_IDE; unit = 2*(majno - 33) + 4;
993
unit += ((minno & 64) >> 6);
994
part = (minno & 0x3f) - 1;
995
sprintf (dev, "/dev/hd%c%d", unit + 'a', part + 1);
996
strcpy (wholedev, dev);
999
case 7: /* Loop device */
1001
sprintf (dev, "/dev/loop%d", unit);
1003
strcpy (wholedev, dev);
1005
case 9: /* RAID device */
1007
md_array_info_t md_array_info;
1008
md_disk_info_t md_disk_info;
1009
int md_fd, i, id = 0;
1010
struct hwdevice *d, *last;
1012
sprintf (dev, "/dev/md%d", minno);
1013
md_fd = devopen (dev, O_RDONLY);
1015
silo_fatal("Could not open RAID device");
1016
if (ioctl (md_fd, GET_ARRAY_INFO, &md_array_info) < 0)
1017
silo_fatal("Could not get RAID array info");
1018
if (md_array_info.major_version == 0 && md_array_info.minor_version < 90)
1019
silo_fatal("Raid versions < 0.90 are not "
1021
if (md_array_info.level != 1)
1022
silo_fatal("Only RAID1 supported");
1025
for (i = 0; i < md_array_info.raid_disks; i++) {
1026
md_disk_info.number = i;
1027
if (ioctl (md_fd, GET_DISK_INFO, &md_disk_info) < 0)
1028
silo_fatal("Could not get RAID disk "
1029
"info for disk %d\n", i);
1030
if(md_disk_info.majorno != 0 && md_disk_info.minorno != 0) {
1031
d = get_device (md_disk_info.majorno, md_disk_info.minorno);
1032
if (md_disk_info.state == MD_DISK_FAULTY) {
1033
printf ("disk %s marked as faulty, skipping\n", d->dev);
1040
while (d->next != NULL) d = d->next;
1045
silo_fatal("No non-faulty disks found "
1047
for (d = hwdev; d; d = d->next)
1055
char *p = find_dev (makedev (majno, minno));
1058
silo_fatal("Couldn't find out what device is second "
1061
strcpy (wholedev, p);
1063
if (strlen (p) == strlen ("/dev/dsk/c0t0d0s0")) {
1064
p = strchr (p, 0) - 2;
1065
if (*p == 's' && p[1] >= '0' && p[1] <= '7') {
1066
p = strchr (wholedev, 0) - 1;
1076
hwdev = malloc(sizeof(struct hwdevice) + strlen(dev) + strlen(wholedev) + 4);
1078
silo_fatal("Not enough memory");
1079
memset(hwdev, 0, sizeof(*hwdev));
1080
hwdev->dev = (char *)(hwdev + 1);
1081
strcpy (hwdev->dev, dev);
1082
hwdev->wholedev = strchr(hwdev->dev, 0) + 2;
1083
strcpy (hwdev->wholedev, wholedev);
1085
hwdev->partat0 = -1;
1090
int main(int argc,char **argv)
1092
char *name = NULL, *config_file, *install = NULL, *secondary = NULL, *backup, *p;
1095
struct stat st1, st2, st3;
1096
int force_backup = 0;
1097
int config_file_partno = 1;
1099
struct hwdevice *hwdev;
1102
int print_prom_version = 0;
1105
if (prom_init () >= 0)
1108
if (uname (&uts) >= 0 && !strcmp (uts.machine, "sparc64"))
1110
config_file = DFL_CONFIG;
1111
backup = DFL_BACKUP;
1115
while (argc && **argv == '-') {
1117
if (argv[0][2] && argv[0][1] != 'p') usage(name);
1118
switch ((*argv++)[1]) {
1120
if (!argc) usage(name);
1121
secondary = *argv++;
1125
if (!argc) usage(name);
1133
if ((argv[-1])[2] == '0')
1135
else if ((argv[-1])[2] == '2')
1137
else if (argv[-1][2])
1139
else if (argc && **argv == '0') {
1143
} else if (argc && **argv == '2') {
1153
if (!argc) usage(name);
1154
config_file = *argv++;
1158
if (!argc) usage(name);
1164
if (!argc) usage(name);
1169
if (!argc) usage(name);
1180
print_prom_version = 1;
1189
if (!argc) usage(name);
1190
flash_image = *argv++;
1194
allow_confchk_fail = 1;
1200
if (promver == -1 && !ultra)
1201
promver = get_prom_ver(use_prom);
1206
if (print_prom_version) {
1208
printf("IEEE 1275\n");
1210
printf ("%d\n", promver);
1213
if (!new_root) new_root = getenv("ROOT");
1215
fprintf(stderr, "SILO version " VERSION "\n");
1218
if (argc) usage(name);
1219
if (floppy_image && flash_image) usage(name);
1223
if (*flash_image == '/') {
1224
p = malloc(strlen(flash_image) + 2);
1225
strcpy(p, flash_image);
1228
q = getcwd(NULL, 0);
1229
p = malloc(strlen(flash_image) + 3 + strlen(q));
1233
p = malloc(PATH_MAX + 3 + strlen(flash_image));
1234
getcwd(p, PATH_MAX);
1237
strcat(p, flash_image);
1242
if (new_root && strcmp("/", new_root)) {
1243
if (stat (new_root, &st1) < 0 || !S_ISDIR(st1.st_mode)) {
1244
silo_fatal("New root %s is not a directory", new_root);
1246
oldroot = open("/", O_RDONLY);
1251
/* This _must_ be done after chrooting */
1252
if (!confcheck(config_file) && !allow_confchk_fail)
1255
/* Check for some values in the config that override defaults */
1256
if (cfg_get_flag(NULL, "partition-boot"))
1260
if (cfg_get_strg(NULL, "secondary"))
1261
secondary = cfg_get_strg(NULL, "secondary");
1263
secondary = DFL_SECONDARY;
1266
secondary = strdup (secondary);
1267
if (stat (secondary, &st1) < 0)
1268
silo_fatal("Cannot open second stage loader %s", secondary);
1269
hwdevs = get_device (mmajor(st1.st_dev), mminor(st1.st_dev));
1271
silo_fatal("SILO supports at most 32 disks in the RAID1 array");
1272
if (raid1 && masterboot) {
1273
struct hwdevice *d, *d1;
1274
/* Check if we have to remove some RAID1 mirrors, because
1275
we can support only one RAID1 mirror per physical device
1277
for (d = hwdevs; d; d = d->next)
1278
for (d1 = d; d1->next; d1 = d1->next)
1279
if (!strcmp (d->wholedev, d1->next->wholedev)) {
1280
d1->next = d1->next->next;
1286
* The filesystem starts at offset 1024 into the flash. This
1287
* makes it impossible to patch the first stage through /dev/loopN.
1288
* We use argument to -J as a way to access the whole flash image.
1290
* XXX There is no good way to ensure that argument to -J
1291
* is what we have mounted off a loopback or a ramdisk.
1292
* So we do not bother trying.
1295
silo_fatal("-J cannot be used with RAID1");
1296
hwdevs->wholedev = flash_image;
1299
backup = malloc (strlen(backup) + 20);
1300
config_file = strdup (config_file);
1302
if (!backup || !config_file)
1303
silo_fatal("Not enough memory");
1304
if (stat (config_file, &st2) >= 0) {
1305
if (raid1 && st1.st_dev != st2.st_dev)
1306
silo_fatal("Config file %s has to be on the same RAID1 device "
1307
"as second stage bootblock", config_file);
1308
else if (hwdevs->type == TYPE_UNKNOWN && st1.st_dev != st2.st_dev)
1309
silo_fatal("Config file %s has to be on the %s device",
1310
config_file, hwdevs->dev);
1312
else if ((hwdevs->type == TYPE_SCSI && (mmajor(st2.st_dev) != mmajor(st1.st_dev) || (mminor(st2.st_dev) & (~0xf)) != (mminor(st1.st_dev) & (~0xf)))) ||
1313
(hwdevs->type == TYPE_IDE && (mmajor(st2.st_dev) != mmajor(st1.st_dev) || (mminor(st2.st_dev) & (~0x3f)) != (mminor(st1.st_dev) & (~0x3f)))))
1314
#elif defined(__sun__)
1315
else if (hwdevs->type == TYPE_SCSI && (st2.st_dev & (~0x7)) != (st1.st_dev & (~0x7)))
1317
# error "Unknown system"
1319
silo_fatal("Config file %s has to be on the %s device "
1320
"(on any partition there)", config_file,
1324
char readlinkbuf[2048];
1326
char buffer[2048], buffer2[2048];
1328
strcpy (buffer, config_file);
1329
for (p = buffer;;) {
1330
q = strchr (p, '/');
1335
if (lstat (*buffer ? buffer : "/", &st3) < 0)
1336
silo_fatal("Couldn't stat %s\n", config_file);
1337
if (st3.st_dev == st2.st_dev) {
1342
if (S_ISLNK(st3.st_mode)) {
1343
len = readlink (buffer, readlinkbuf, 2048);
1345
silo_fatal("Couldn't readlink %s\n", config_file);
1346
readlinkbuf[len] = 0;
1347
if (*readlinkbuf == '/') {
1349
r = readlinkbuf+len;
1350
if (readlinkbuf[len - 1] != '/')
1354
strcpy (buffer, readlinkbuf);
1358
r = strrchr (buffer, '/');
1359
memcpy (buffer2, buffer, r - buffer + 1);
1360
strcpy (buffer2 + (r - buffer + 1), readlinkbuf);
1362
strcat (buffer2, "/");
1363
strcat (buffer2, q + 1);
1365
strcpy (buffer, buffer2);
1373
silo_fatal("Internal error\n");
1378
config_file_partno = -1;
1379
else if (hwdevs->type == TYPE_SCSI)
1381
config_file_partno = (mminor(st2.st_dev) & 0x0f);
1382
#elif defined(__sun__)
1383
config_file_partno = (st2.st_dev & 7) + 1;
1385
# error "Unknown system"
1388
else if (hwdevs->type == TYPE_IDE)
1389
config_file_partno = (mminor(st2.st_dev) & 0x3f);
1392
config_file_partno = 1;
1394
for (hwdev = hwdevs; hwdev; hwdev = hwdev->next)
1396
for (hwdev = hwdevs, f = 0; hwdev; hwdev = hwdev->next) {
1397
int fb = force_backup;
1401
p = strchr (backup, 0);
1402
sprintf (p, "-raid1-%d", hwdev->id);
1404
if (!force_backup) {
1405
if (stat (backup, &st2) < 0)
1408
f |= examine_bootblock (masterboot ? hwdev->wholedev : hwdev->dev, backup, fb);
1412
if (f || install || force) {
1414
install = strdup (ultra ? DFL_PRIMARY_U : DFL_PRIMARY);
1415
else if (*install == '/')
1416
install = strdup (install);
1417
for (hwdev = hwdevs; hwdev; hwdev = hwdev->next)
1418
install_first_stage (masterboot ? hwdev->wholedev : hwdev->dev, install);
1420
make_room_for_raid1(hwdevs, secondary);
1421
for (hwdev = hwdevs; hwdev; hwdev = hwdev->next)
1422
get_partition_blocks (hwdev, secondary);
1423
write_block_tables (hwdevs, secondary, config_file, config_file_partno);
1430
static errcode_t std_open (const char *name, int flags, io_channel * channel);
1431
static errcode_t std_close (io_channel channel);
1432
static errcode_t std_set_blksize (io_channel channel, int blksize);
1433
static errcode_t std_read_blk (io_channel channel, unsigned long block, int count, void *data);
1434
static errcode_t std_write_blk (io_channel channel, unsigned long block, int count, const void *data);
1435
static errcode_t std_flush (io_channel channel);
1437
static struct struct_io_manager struct_std_manager =
1439
EXT2_ET_MAGIC_IO_MANAGER,
1440
"linux I/O Manager",
1449
static ufs_filsys fs = NULL;
1450
static io_manager std_io_manager = &struct_std_manager;
1451
static int std_fd = 0;
1453
static unsigned int cbs = 1024; /* Block Size */
1455
static errcode_t std_open (const char *name, int flags, io_channel * channel)
1461
return EXT2_ET_BAD_DEVICE_NAME;
1462
io = (io_channel) malloc (sizeof (struct struct_io_channel));
1464
return EXT2_ET_BAD_DEVICE_NAME;
1465
std_fd = devopen (name, O_RDONLY);
1467
silo_fatal("Cannot open %s", name);
1468
memset (io, 0, sizeof (struct struct_io_channel));
1469
io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
1470
io->manager = std_io_manager;
1471
io->name = (char *) malloc (strlen (name) + 1);
1472
strcpy (io->name, name);
1473
io->block_size = cbs;
1475
io->write_error = 0;
1481
static errcode_t std_close (io_channel channel)
1486
static errcode_t std_set_blksize (io_channel channel, int blksize)
1488
channel->block_size = cbs = blksize;
1491
static errcode_t std_read_blk (io_channel channel, unsigned long block, int count, void *data)
1495
size = (count < 0) ? -count : count * cbs;
1496
if (lseek (std_fd, block * cbs, SEEK_SET) != block * cbs)
1497
silo_fatal("Cannot seek");
1498
if (read (std_fd, data, size) != size)
1499
silo_fatal("Read error on block %d", block);
1503
static errcode_t std_write_blk (io_channel channel, unsigned long block, int count, const void *data)
1507
static errcode_t std_flush (io_channel channel)
1511
static int ufs_block_idx = 0;
1512
static int ufs_blocks_dump (ufs_filsys fs, blk_t *block, int i, void *private)
1515
struct hwdevice *hwdev = (struct hwdevice *)private;
1516
for (j = 0; j < hwdev->nsect; j++)
1517
blocks [ufs_block_idx++] = *block * hwdev->nsect + hwdev->doff + j;
1521
static int ufs_blocks (struct hwdevice *hwdev, ino_t inode)
1523
if (ufs_open (hwdev->dev, std_io_manager, &fs))
1524
silo_fatal("Cannot open ufs filesystem containing second stage");
1525
hwdev->nsect = cbs / 512;
1526
if (ufs_block_iterate (fs, inode, ufs_blocks_dump, hwdev))
1527
silo_fatal("Block iterating error on second stage");
1528
blocks [ufs_block_idx] = 0;