Root/
Source at commit 1547 created 12 years 10 months ago. By blackosx, Added UseKernelCache boot option to svn | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * This file contains Original Code and/or Modifications of Original Code␊ |
7 | * as defined in and that are subject to the Apple Public Source License␊ |
8 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
9 | * compliance with the License. Please obtain a copy of the License at␊ |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this␊ |
11 | * file.␊ |
12 | * ␊ |
13 | * The Original Code and all software distributed under the License are␊ |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
18 | * Please see the License for the specific language governing rights and␊ |
19 | * limitations under the License.␊ |
20 | * ␊ |
21 | * @APPLE_LICENSE_HEADER_END@␊ |
22 | */␊ |
23 | ␊ |
24 | ␊ |
25 | /*␊ |
26 | * Copyright (c) 1997 Tobias Weingartner␊ |
27 | * All rights reserved.␊ |
28 | *␊ |
29 | * Redistribution and use in source and binary forms, with or without␊ |
30 | * modification, are permitted provided that the following conditions␊ |
31 | * are met:␊ |
32 | * 1. Redistributions of source code must retain the above copyright␊ |
33 | * notice, this list of conditions and the following disclaimer.␊ |
34 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
35 | * notice, this list of conditions and the following disclaimer in the␊ |
36 | * documentation and/or other materials provided with the distribution.␊ |
37 | * 3. All advertising materials mentioning features or use of this software␊ |
38 | * must display the following acknowledgement:␊ |
39 | * This product includes software developed by Tobias Weingartner.␊ |
40 | * 4. The name of the author may not be used to endorse or promote products␊ |
41 | * derived from this software without specific prior written permission.␊ |
42 | *␊ |
43 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR␊ |
44 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES␊ |
45 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.␊ |
46 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,␊ |
47 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT␊ |
48 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,␊ |
49 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY␊ |
50 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT␊ |
51 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF␊ |
52 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.␊ |
53 | */␊ |
54 | ␊ |
55 | #include <err.h>␊ |
56 | #include <stdio.h>␊ |
57 | #include <stdlib.h>␊ |
58 | #include <string.h>␊ |
59 | #include <unistd.h>␊ |
60 | #include <paths.h>␊ |
61 | #include <sys/types.h>␊ |
62 | #include <sys/fcntl.h>␊ |
63 | #include "disk.h"␊ |
64 | #include "user.h"␊ |
65 | #include "auto.h"␊ |
66 | ␊ |
67 | #define _PATH_MBR "/usr/standalone/i386/boot0"␊ |
68 | ␊ |
69 | void␊ |
70 | usage()␊ |
71 | {␊ |
72 | ␉extern char * __progname;␊ |
73 | ␉fprintf(stderr, "usage: %s "␊ |
74 | ␉ "[-ieu] [-f mbrboot] [-c cyl -h head -s sect] [-S size] [-r] [-a style] disk\n"␊ |
75 | ␉ "\t-i: initialize disk with new MBR\n"␊ |
76 | ␉ "\t-u: update MBR code, preserve partition table\n"␊ |
77 | ␉ "\t-e: edit MBRs on disk interactively\n"␊ |
78 | ␉ "\t-f: specify non-standard MBR template\n"␊ |
79 | ␉ "\t-chs: specify disk geometry\n"␊ |
80 | ␉ "\t-S: specify disk size\n"␊ |
81 | ␉ "\t-r: read partition specs from stdin (implies -i)\n"␊ |
82 | ␉ "\t-a: auto-partition with the given style\n"␊ |
83 | ␉ "\t-d: dump partition table\n"␊ |
84 | ␉ "\t-y: don't ask any questions\n"␊ |
85 | ␉ "\t-t: test if disk is partitioned\n"␊ |
86 | ␉ "`disk' is of the form /dev/rdisk0.\n",␊ |
87 | ␉ __progname);␊ |
88 | ␉fprintf(stderr, "auto-partition styles:\n");␊ |
89 | ␉AUTO_print_styles(stderr);␊ |
90 | ␉exit(1);␊ |
91 | }␊ |
92 | ␊ |
93 | char *mbr_binary = NULL;␊ |
94 | int␊ |
95 | main(argc, argv)␊ |
96 | ␉int argc;␊ |
97 | ␉char **argv;␊ |
98 | {␊ |
99 | ␉int ch, fd;␊ |
100 | ␉int i_flag = 0, m_flag = 0, u_flag = 0, r_flag = 0, d_flag = 0, y_flag = 0, t_flag = 0;␊ |
101 | ␉int c_arg = 0, h_arg = 0, s_arg = 0;␊ |
102 | ␉int size_arg = 0;␊ |
103 | ␉int block_size_arg = 0;␊ |
104 | ␉disk_t disk;␊ |
105 | ␉DISK_metrics *usermetrics;␊ |
106 | ␉char *mbrfile = _PATH_MBR;␊ |
107 | ␉mbr_t *mp;␊ |
108 | ␉char *auto_style = NULL;␊ |
109 | ␊ |
110 | ␉while ((ch = getopt(argc, argv, "ieuf:c:h:s:b:S:ra:dyt")) != -1) {␊ |
111 | ␉␉switch(ch) {␊ |
112 | ␉␉case 'i':␊ |
113 | ␉␉␉i_flag = 1;␊ |
114 | ␉␉␉break;␊ |
115 | ␉␉case 'u':␊ |
116 | ␉␉␉u_flag = 1;␊ |
117 | ␉␉␉break;␊ |
118 | ␉␉case 'e':␊ |
119 | ␉␉␉m_flag = 1;␊ |
120 | ␉␉␉break;␊ |
121 | ␉␉case 'f':␊ |
122 | ␉␉␉mbrfile = optarg;␊ |
123 | ␉␉␉break;␊ |
124 | ␉␉case 'c':␊ |
125 | ␉␉␉c_arg = atoi(optarg);␊ |
126 | ␉␉␉if (c_arg < 1 || c_arg > 262144)␊ |
127 | ␉␉␉␉errx(1, "Cylinder argument out of range.");␊ |
128 | ␉␉␉break;␊ |
129 | ␉␉case 'h':␊ |
130 | ␉␉␉h_arg = atoi(optarg);␊ |
131 | ␉␉␉if (h_arg < 1 || h_arg > 256)␊ |
132 | ␉␉␉␉errx(1, "Head argument out of range.");␊ |
133 | ␉␉␉break;␊ |
134 | ␉␉case 's':␊ |
135 | ␉␉␉s_arg = atoi(optarg);␊ |
136 | ␉␉␉if (s_arg < 1 || s_arg > 63)␊ |
137 | ␉␉␉␉errx(1, "Sector argument out of range.");␊ |
138 | ␉␉␉break;␊ |
139 | ␉␉case 'b':␊ |
140 | ␉␉␉block_size_arg = atoi(optarg);␊ |
141 | ␉␉␉if (block_size_arg & (block_size_arg - 1))␊ |
142 | ␉␉␉␉errx(1, "Block size argument not a power of two.");␊ |
143 | ␉␉␉if (block_size_arg < 512 || block_size_arg > 4096)␊ |
144 | ␉␉␉␉errx(1, "Block size argument out of range 512..4096.");␊ |
145 | ␉␉␉break;␊ |
146 | ␉␉case 'S':␊ |
147 | ␉␉ size_arg = atoi(optarg);␊ |
148 | ␉␉␉break;␊ |
149 | ␉␉case 'r':␊ |
150 | ␉␉␉r_flag = 1;␊ |
151 | ␉␉␉break;␊ |
152 | ␉␉case 'a':␊ |
153 | ␉␉ auto_style = optarg;␊ |
154 | ␉␉␉break;␊ |
155 | ␉␉case 'd':␊ |
156 | ␉␉ d_flag = 1;␊ |
157 | ␉␉␉break;␊ |
158 | ␉␉case 'y':␊ |
159 | ␉␉ y_flag = 1;␊ |
160 | ␉␉␉break;␊ |
161 | ␉␉case 't':␊ |
162 | ␉␉ t_flag = 1;␊ |
163 | ␉␉␉break;␊ |
164 | ␉␉default:␊ |
165 | ␉␉␉usage();␊ |
166 | ␉␉}␊ |
167 | ␉}␊ |
168 | ␉argc -= optind;␊ |
169 | ␉argv += optind;␊ |
170 | ␊ |
171 | ␉/* Argument checking */␊ |
172 | ␉if (argc != 1)␊ |
173 | ␉␉usage();␊ |
174 | ␉else␊ |
175 | ␉␉disk.name = argv[0];␊ |
176 | ␊ |
177 | ␉if (i_flag && u_flag) errx(1, "-i and -u cannot be specified simultaneously");␊ |
178 | ␊ |
179 | ␉/* Put in supplied geometry if there */␊ |
180 | ␉if (c_arg | h_arg | s_arg | size_arg | block_size_arg) {␊ |
181 | ␉␉usermetrics = malloc(sizeof(DISK_metrics));␊ |
182 | ␉␉if (usermetrics != NULL) {␊ |
183 | ␉␉␉if (c_arg && h_arg && s_arg) {␊ |
184 | ␉␉␉␉usermetrics->cylinders = c_arg;␊ |
185 | ␉␉␉␉usermetrics->heads = h_arg;␊ |
186 | ␉␉␉␉usermetrics->sectors = s_arg;␊ |
187 | ␉␉␉␉if (size_arg) {␊ |
188 | ␉␉␉␉ usermetrics->size = size_arg;␊ |
189 | ␉␉␉␉} else {␊ |
190 | ␉␉␉␉ usermetrics->size = c_arg * h_arg * s_arg;␊ |
191 | ␉␉␉␉}␊ |
192 | ␉␉␉} else {␊ |
193 | ␉␉␉ if (size_arg) {␊ |
194 | ␉␉␉ usermetrics->size = size_arg;␊ |
195 | ␉␉␉ DISK_fake_CHS(usermetrics);␊ |
196 | ␉␉␉ } else {␊ |
197 | ␉␉␉ errx(1, "Please specify a full geometry with [-chs].");␊ |
198 | ␉␉␉ }␊ |
199 | ␉␉␉}␊ |
200 | ␉␉␉if (block_size_arg) {␊ |
201 | ␉␉␉␉usermetrics->sector_size = block_size_arg;␊ |
202 | ␉␉␉} else {␊ |
203 | ␉␉␉␉DISK_get_sector_size(&disk, usermetrics);␊ |
204 | ␉␉␉}␊ |
205 | ␉␉}␊ |
206 | ␉} else {␊ |
207 | ␉␉usermetrics = NULL;␊ |
208 | ␉}␊ |
209 | ␊ |
210 | ␉/* Get the geometry */␊ |
211 | ␉disk.real = NULL;␊ |
212 | ␉if (DISK_getmetrics(&disk, usermetrics))␊ |
213 | ␉␉errx(1, "Can't get disk geometry, please use [-chs] to specify.");␊ |
214 | ␊ |
215 | ␉/* If only testing, read MBR and silently exit */␊ |
216 | ␉if (t_flag) {␊ |
217 | ␉ mbr_t *mbr;␊ |
218 | ␊ |
219 | ␉ mp = mbr = MBR_read_all(&disk);␊ |
220 | ␉ while (mp) {␊ |
221 | ␉ if (mp->signature != MBR_SIGNATURE) {␊ |
222 | ␉ MBR_free(mbr);␊ |
223 | ␉ exit(1);␊ |
224 | ␉ }␊ |
225 | ␉ mp = mp->next;␊ |
226 | ␉ }␊ |
227 | ␉ MBR_free(mbr);␊ |
228 | ␉ exit(0);␊ |
229 | ␉}␊ |
230 | ␊ |
231 | ␉/* If not editing the disk, print out current MBRs on disk */␊ |
232 | ␉if ((i_flag + r_flag + u_flag + m_flag) == 0) {␊ |
233 | ␉␉exit(USER_print_disk(&disk, d_flag));␊ |
234 | ␉}␊ |
235 | ␊ |
236 | ␉/* Parse mbr template or read partition specs, to pass on later */␊ |
237 | ␉if (auto_style && r_flag) {␊ |
238 | ␉ errx(1, "Can't specify both -r and -a");␊ |
239 | ␉}␊ |
240 | ␊ |
241 | ␉mbr_binary = (char *)malloc(MBR_CODE_SIZE);␊ |
242 | ␉if ((fd = open(mbrfile, O_RDONLY)) == -1) {␊ |
243 | ␉ warn("could not open MBR file %s", mbrfile);␊ |
244 | ␉ bzero(mbr_binary, MBR_CODE_SIZE);␊ |
245 | ␉} else {␊ |
246 | ␉ int cc;␊ |
247 | ␉ cc = read(fd, mbr_binary, MBR_CODE_SIZE);␊ |
248 | ␉ if (cc < MBR_CODE_SIZE) {␊ |
249 | ␉ err(1, "could not read MBR code");␊ |
250 | ␉ }␊ |
251 | ␉ close(fd);␊ |
252 | ␉}␊ |
253 | ␊ |
254 | ␉if (u_flag) {␊ |
255 | ␉ /* Don't hose the partition table; just write the boot code */␊ |
256 | ␉ mp = MBR_read_all(&disk);␊ |
257 | ␉ bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);␊ |
258 | ␉ MBR_make(mp);␊ |
259 | ␉} else if (i_flag) {␊ |
260 | ␉ /* If they didn't specify -a, they'll get the default auto style */␊ |
261 | ␉ mp = MBR_alloc(NULL);␊ |
262 | ␉ if (AUTO_init(&disk, auto_style, mp) != AUTO_OK) {␊ |
263 | ␉ errx(1, "error initializing disk");␊ |
264 | ␉ }␊ |
265 | ␉ bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);␊ |
266 | ␉ MBR_make(mp);␊ |
267 | ␉} else if (r_flag) {␊ |
268 | ␉ mp = MBR_parse_spec(stdin, &disk);␊ |
269 | ␉ bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);␊ |
270 | ␉ MBR_make(mp);␊ |
271 | ␉} else {␊ |
272 | ␉ /* Use what's on the disk. */␊ |
273 | ␉ mp = MBR_read_all(&disk);␊ |
274 | ␉}␊ |
275 | ␉ ␊ |
276 | ␉/* Now do what we are supposed to */␊ |
277 | ␉if (i_flag || r_flag || u_flag) {␊ |
278 | ␉ USER_write(&disk, mp, u_flag, y_flag);␊ |
279 | ␉}␊ |
280 | ␊ |
281 | ␉if (m_flag) {␊ |
282 | ␉ USER_modify(&disk, mp, 0, 0);␊ |
283 | ␉}␊ |
284 | ␊ |
285 | ␉if (mbr_binary)␊ |
286 | ␉ free(mbr_binary);␊ |
287 | ␊ |
288 | ␉return (0);␊ |
289 | }␊ |
290 |