Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
1da177e4 LT |
2 | /* This utility makes a bootblock suitable for the SRM console/miniloader */ |
3 | ||
4 | /* Usage: | |
5 | * mkbb <device> <lxboot> | |
6 | * | |
7 | * Where <device> is the name of the device to install the bootblock on, | |
8 | * and <lxboot> is the name of a bootblock to merge in. This bootblock | |
9 | * contains the offset and size of the bootloader. It must be exactly | |
10 | * 512 bytes long. | |
11 | */ | |
12 | ||
13 | #include <fcntl.h> | |
14 | #include <unistd.h> | |
aeb3f462 | 15 | #include <stdlib.h> |
1da177e4 LT |
16 | #include <stdio.h> |
17 | ||
18 | /* Minimal definition of disklabel, so we don't have to include | |
19 | * asm/disklabel.h (confuses make) | |
20 | */ | |
21 | #ifndef MAXPARTITIONS | |
22 | #define MAXPARTITIONS 8 /* max. # of partitions */ | |
23 | #endif | |
24 | ||
25 | #ifndef u8 | |
26 | #define u8 unsigned char | |
27 | #endif | |
28 | ||
29 | #ifndef u16 | |
30 | #define u16 unsigned short | |
31 | #endif | |
32 | ||
33 | #ifndef u32 | |
34 | #define u32 unsigned int | |
35 | #endif | |
36 | ||
37 | struct disklabel { | |
38 | u32 d_magic; /* must be DISKLABELMAGIC */ | |
39 | u16 d_type, d_subtype; | |
40 | u8 d_typename[16]; | |
41 | u8 d_packname[16]; | |
42 | u32 d_secsize; | |
43 | u32 d_nsectors; | |
44 | u32 d_ntracks; | |
45 | u32 d_ncylinders; | |
46 | u32 d_secpercyl; | |
47 | u32 d_secprtunit; | |
48 | u16 d_sparespertrack; | |
49 | u16 d_sparespercyl; | |
50 | u32 d_acylinders; | |
51 | u16 d_rpm, d_interleave, d_trackskew, d_cylskew; | |
52 | u32 d_headswitch, d_trkseek, d_flags; | |
53 | u32 d_drivedata[5]; | |
54 | u32 d_spare[5]; | |
55 | u32 d_magic2; /* must be DISKLABELMAGIC */ | |
56 | u16 d_checksum; | |
57 | u16 d_npartitions; | |
58 | u32 d_bbsize, d_sbsize; | |
59 | struct d_partition { | |
60 | u32 p_size; | |
61 | u32 p_offset; | |
62 | u32 p_fsize; | |
63 | u8 p_fstype; | |
64 | u8 p_frag; | |
65 | u16 p_cpg; | |
66 | } d_partitions[MAXPARTITIONS]; | |
67 | }; | |
68 | ||
69 | ||
70 | typedef union __bootblock { | |
71 | struct { | |
72 | char __pad1[64]; | |
73 | struct disklabel __label; | |
74 | } __u1; | |
75 | struct { | |
76 | unsigned long __pad2[63]; | |
77 | unsigned long __checksum; | |
78 | } __u2; | |
79 | char bootblock_bytes[512]; | |
80 | unsigned long bootblock_quadwords[64]; | |
81 | } bootblock; | |
82 | ||
83 | #define bootblock_label __u1.__label | |
84 | #define bootblock_checksum __u2.__checksum | |
85 | ||
f8343685 | 86 | int main(int argc, char ** argv) |
1da177e4 LT |
87 | { |
88 | bootblock bootblock_from_disk; | |
89 | bootblock bootloader_image; | |
90 | int dev, fd; | |
91 | int i; | |
92 | int nread; | |
93 | ||
94 | /* Make sure of the arg count */ | |
95 | if(argc != 3) { | |
96 | fprintf(stderr, "Usage: %s device lxboot\n", argv[0]); | |
97 | exit(0); | |
98 | } | |
99 | ||
100 | /* First, open the device and make sure it's accessible */ | |
101 | dev = open(argv[1], O_RDWR); | |
102 | if(dev < 0) { | |
103 | perror(argv[1]); | |
104 | exit(0); | |
105 | } | |
106 | ||
107 | /* Now open the lxboot and make sure it's reasonable */ | |
108 | fd = open(argv[2], O_RDONLY); | |
109 | if(fd < 0) { | |
110 | perror(argv[2]); | |
111 | close(dev); | |
112 | exit(0); | |
113 | } | |
114 | ||
115 | /* Read in the lxboot */ | |
116 | nread = read(fd, &bootloader_image, sizeof(bootblock)); | |
117 | if(nread != sizeof(bootblock)) { | |
118 | perror("lxboot read"); | |
aeb3f462 | 119 | fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread); |
1da177e4 LT |
120 | exit(0); |
121 | } | |
122 | ||
123 | /* Read in the bootblock from disk. */ | |
124 | nread = read(dev, &bootblock_from_disk, sizeof(bootblock)); | |
125 | if(nread != sizeof(bootblock)) { | |
126 | perror("bootblock read"); | |
aeb3f462 | 127 | fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread); |
1da177e4 LT |
128 | exit(0); |
129 | } | |
130 | ||
131 | /* Swap the bootblock's disklabel into the bootloader */ | |
132 | bootloader_image.bootblock_label = bootblock_from_disk.bootblock_label; | |
133 | ||
134 | /* Calculate the bootblock checksum */ | |
135 | bootloader_image.bootblock_checksum = 0; | |
136 | for(i = 0; i < 63; i++) { | |
137 | bootloader_image.bootblock_checksum += | |
138 | bootloader_image.bootblock_quadwords[i]; | |
139 | } | |
140 | ||
141 | /* Write the whole thing out! */ | |
142 | lseek(dev, 0L, SEEK_SET); | |
143 | if(write(dev, &bootloader_image, sizeof(bootblock)) != sizeof(bootblock)) { | |
144 | perror("bootblock write"); | |
145 | exit(0); | |
146 | } | |
147 | ||
148 | close(fd); | |
149 | close(dev); | |
150 | exit(0); | |
151 | } | |
152 | ||
153 |