xref: /openbsd/sbin/pdisk/dump.c (revision 5fe72782)
1*5fe72782Skrw /*	$OpenBSD: dump.c,v 1.75 2016/02/23 02:39:54 krw Exp $	*/
2fb04e59aSjasper 
386ec409aSkrw /*
486ec409aSkrw  * dump.c - dumping partition maps
586ec409aSkrw  *
686ec409aSkrw  * Written by Eryk Vershen
786ec409aSkrw  */
8dce63815Sdrahn 
9dce63815Sdrahn /*
10dce63815Sdrahn  * Copyright 1996,1997,1998 by Apple Computer, Inc.
11dce63815Sdrahn  *              All Rights Reserved
12dce63815Sdrahn  *
13dce63815Sdrahn  * Permission to use, copy, modify, and distribute this software and
14dce63815Sdrahn  * its documentation for any purpose and without fee is hereby granted,
15dce63815Sdrahn  * provided that the above copyright notice appears in all copies and
16dce63815Sdrahn  * that both the copyright notice and this permission notice appear in
17dce63815Sdrahn  * supporting documentation.
18dce63815Sdrahn  *
19dce63815Sdrahn  * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
20dce63815Sdrahn  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21dce63815Sdrahn  * FOR A PARTICULAR PURPOSE.
22dce63815Sdrahn  *
23dce63815Sdrahn  * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
24dce63815Sdrahn  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
25dce63815Sdrahn  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
26dce63815Sdrahn  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
27dce63815Sdrahn  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28dce63815Sdrahn  */
29dce63815Sdrahn 
300392b273Skrw #include <sys/queue.h>
310392b273Skrw 
32dce63815Sdrahn #include <stdio.h>
33dce63815Sdrahn #include <stdlib.h>
34dce63815Sdrahn #include <string.h>
35a8aa5af7Skrw #include <util.h>
36dce63815Sdrahn 
373f55d322Skrw #include "partition_map.h"
38dce63815Sdrahn #include "dump.h"
39dce63815Sdrahn #include "io.h"
40dce63815Sdrahn 
4171c5b58dSkrw void	dump_block(unsigned char *, int);
42356b92ceSkrw void	dump_block_zero(struct partition_map *);
43f4c16b6bSkrw void	dump_partition_entry(struct entry *, int, int, int);
44356b92ceSkrw int	get_max_base_or_length(struct partition_map *);
45356b92ceSkrw int	get_max_name_string_length(struct partition_map *);
46356b92ceSkrw int	get_max_type_string_length(struct partition_map *);
47dce63815Sdrahn 
48dce63815Sdrahn void
dump_block_zero(struct partition_map * map)49356b92ceSkrw dump_block_zero(struct partition_map *map)
50dce63815Sdrahn {
51a8aa5af7Skrw 	char buf[FMT_SCALED_STRSIZE];
5270060700Skrw 	struct ddmap  *m;
53a8aa5af7Skrw 	int i;
54dce63815Sdrahn 
55a8aa5af7Skrw 	printf("\nDevice block size=%u, Number of Blocks=%u",
56a8aa5af7Skrw 	       map->sbBlkSize, map->sbBlkCount);
57*5fe72782Skrw 	if (fmt_scaled((long long)map->sbBlkCount * map->sbBlkSize, buf) == 0)
58a8aa5af7Skrw 		printf(" (%s)\n", buf);
59a8aa5af7Skrw 	else
60a8aa5af7Skrw 		printf("\n");
61dce63815Sdrahn 
626f012227Skrw 	printf("DeviceType=0x%x, DeviceId=0x%x\n", map->sbDevType,
636f012227Skrw 	    map->sbDevId);
646f012227Skrw 	if (map->sbDrvrCount > 0) {
65dce63815Sdrahn 		printf("Drivers-\n");
666f012227Skrw 		m = map->sbDDMap;
676f012227Skrw 		for (i = 0; i < map->sbDrvrCount; i++) {
6837e225b6Skrw 			printf("%d: %3u @ %u, ", i + 1, m[i].ddSize,
6937e225b6Skrw 			    m[i].ddBlock);
70b42d9302Smartin 			printf("type=0x%x\n", m[i].ddType);
71dce63815Sdrahn 		}
72dce63815Sdrahn 	}
73dce63815Sdrahn 	printf("\n");
74dce63815Sdrahn }
75dce63815Sdrahn 
76dce63815Sdrahn 
77dce63815Sdrahn void
dump_partition_map(struct partition_map * map)78356b92ceSkrw dump_partition_map(struct partition_map *map)
79dce63815Sdrahn {
80f4c16b6bSkrw 	struct entry *entry;
813f012ab0Skrw 	int digits, max_type_length, max_name_length;
82dce63815Sdrahn 
83dce63815Sdrahn 	printf("\nPartition map (with %d byte blocks) on '%s'\n",
84ead46a34Skrw 	       map->sbBlkSize, map->name);
85dce63815Sdrahn 
86dce63815Sdrahn 	digits = number_of_digits(get_max_base_or_length(map));
87a8b53b4cSkrw 	if (digits < 6)
88dce63815Sdrahn 		digits = 6;
89dce63815Sdrahn 	max_type_length = get_max_type_string_length(map);
90a8b53b4cSkrw 	if (max_type_length < 4)
91dce63815Sdrahn 		max_type_length = 4;
92dce63815Sdrahn 	max_name_length = get_max_name_string_length(map);
93a8b53b4cSkrw 	if (max_name_length < 6)
94dce63815Sdrahn 		max_name_length = 6;
95a8aa5af7Skrw 	printf(" #: %*s %-*s %*s   %-*s\n", max_type_length, "type",
9635985165Skrw 	    max_name_length, "name", digits, "length", digits, "base");
97dce63815Sdrahn 
980392b273Skrw 	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
993f012ab0Skrw 		dump_partition_entry(entry, max_type_length,
1003f012ab0Skrw 		    max_name_length, digits);
101dce63815Sdrahn 	}
102dce63815Sdrahn 	dump_block_zero(map);
103dce63815Sdrahn }
104dce63815Sdrahn 
105dce63815Sdrahn 
106dce63815Sdrahn void
dump_partition_entry(struct entry * entry,int type_length,int name_length,int digits)107a8aa5af7Skrw dump_partition_entry(struct entry *entry, int type_length, int name_length,
108a8aa5af7Skrw     int digits)
109dce63815Sdrahn {
110a8aa5af7Skrw 	char buf[FMT_SCALED_STRSIZE];
111dce63815Sdrahn 
112f8fa35e5Skrw 	printf("%2ld: %*.32s", entry->disk_address, type_length,
113f8fa35e5Skrw 	    entry->dpme_type);
114575b2bc1Skrw 	printf("%c%-*.32s ", contains_driver(entry) ? '*' : ' ',
115575b2bc1Skrw 	    name_length, entry->dpme_name);
116b42d9302Smartin 
117f8fa35e5Skrw 	printf("%*u @ %-*u", digits, entry->dpme_pblocks, digits,
118f8fa35e5Skrw 	    entry->dpme_pblock_start);
119dce63815Sdrahn 
120*5fe72782Skrw 	if (fmt_scaled((long long)entry->dpme_pblocks *
121*5fe72782Skrw 	    entry->the_map->sbBlkSize, buf) == 0)
122a8aa5af7Skrw 		printf("(%s)\n", buf);
123a8aa5af7Skrw 	else
124dce63815Sdrahn 		printf("\n");
125dce63815Sdrahn }
126dce63815Sdrahn 
127dce63815Sdrahn 
128dce63815Sdrahn void
show_data_structures(struct partition_map * map)129356b92ceSkrw show_data_structures(struct partition_map *map)
130dce63815Sdrahn {
131f4c16b6bSkrw 	struct entry *entry;
13270060700Skrw 	struct ddmap *m;
1333f012ab0Skrw 	int i;
134dce63815Sdrahn 
135dce63815Sdrahn 	printf("Header:\n");
136dce63815Sdrahn 	printf("map %d blocks out of %d,  media %lu blocks (%d byte blocks)\n",
13735985165Skrw 	    map->blocks_in_map, map->maximum_in_map, map->media_size,
138ead46a34Skrw 	    map->sbBlkSize);
1393f55d322Skrw 	printf("Map is%s writable", rflag ? " not" : "");
1403f55d322Skrw 	printf(" and has%s been changed\n", (map->changed) ? "" : " not");
141dce63815Sdrahn 	printf("\n");
142dce63815Sdrahn 
143dce63815Sdrahn 	printf("Block0:\n");
1446f012227Skrw 	printf("signature 0x%x", map->sbSig);
1456f012227Skrw 	printf("Block size=%u, Number of Blocks=%u\n", map->sbBlkSize,
1466f012227Skrw 	    map->sbBlkCount);
1476f012227Skrw 	printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%x\n", map->sbDevType,
1486f012227Skrw 	    map->sbDevId, map->sbData);
1496f012227Skrw 	if (map->sbDrvrCount == 0) {
150dce63815Sdrahn 		printf("No drivers\n");
151dce63815Sdrahn 	} else {
1526f012227Skrw 		printf("%u driver%s-\n", map->sbDrvrCount,
1536f012227Skrw 		    (map->sbDrvrCount > 1) ? "s" : "");
1546f012227Skrw 		m = map->sbDDMap;
1556f012227Skrw 		for (i = 0; i < map->sbDrvrCount; i++) {
156024cef13Skrw 			printf("%u: @ %u for %u, type=0x%x\n", i + 1,
15737e225b6Skrw 			    m[i].ddBlock, m[i].ddSize, m[i].ddType);
158dce63815Sdrahn 		}
159dce63815Sdrahn 	}
160dce63815Sdrahn 	printf("\n");
161dce63815Sdrahn 	printf(" #:                 type  length   base    "
162dce63815Sdrahn 	       "flags     (      logical      )\n");
1630392b273Skrw 	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
164f8fa35e5Skrw 		printf("%2ld: %20.32s ", entry->disk_address, entry->dpme_type);
165f8fa35e5Skrw 		printf("%7u @ %-7u ", entry->dpme_pblocks,
166f8fa35e5Skrw 		    entry->dpme_pblock_start);
16731859932Skrw 		printf("%c%c%c%c%c%c%c%c%c ",
168f8fa35e5Skrw 		       (entry->dpme_flags & DPME_VALID) ? 'V' : '.',
169f8fa35e5Skrw 		       (entry->dpme_flags & DPME_ALLOCATED) ? 'A' : '.',
170f8fa35e5Skrw 		       (entry->dpme_flags & DPME_IN_USE) ? 'I' : '.',
171f8fa35e5Skrw 		       (entry->dpme_flags & DPME_BOOTABLE) ? 'B' : '.',
172f8fa35e5Skrw 		       (entry->dpme_flags & DPME_READABLE) ? 'R' : '.',
173f8fa35e5Skrw 		       (entry->dpme_flags & DPME_WRITABLE) ? 'W' : '.',
174f8fa35e5Skrw 		       (entry->dpme_flags & DPME_OS_PIC_CODE) ? 'P' : '.',
175f8fa35e5Skrw 		       (entry->dpme_flags & DPME_OS_SPECIFIC_2) ? '2' : '.',
176f8fa35e5Skrw 		       (entry->dpme_flags & DPME_OS_SPECIFIC_1) ? '1' : '.');
177f8fa35e5Skrw 		printf("( %7u @ %-7u )\n", entry->dpme_lblocks,
178f8fa35e5Skrw 		    entry->dpme_lblock_start);
179dce63815Sdrahn 	}
180dce63815Sdrahn 	printf("\n");
181dce63815Sdrahn 	printf(" #:  booter   bytes      load_address      "
182dce63815Sdrahn 	    "goto_address checksum processor\n");
1830392b273Skrw 	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
184dce63815Sdrahn 		printf("%2ld: ", entry->disk_address);
185f8fa35e5Skrw 		printf("%7u ", entry->dpme_boot_block);
186f8fa35e5Skrw 		printf("%7u ", entry->dpme_boot_bytes);
187f8fa35e5Skrw 		printf("%8x ", entry->dpme_load_addr);
188f8fa35e5Skrw 		printf("%8x ", entry->dpme_goto_addr);
189f8fa35e5Skrw 		printf("%8x ", entry->dpme_checksum);
190f8fa35e5Skrw 		printf("%.32s", entry->dpme_processor_id);
191dce63815Sdrahn 		printf("\n");
192dce63815Sdrahn 	}
193dce63815Sdrahn 	printf("\n");
194dce63815Sdrahn }
195dce63815Sdrahn 
196dce63815Sdrahn 
197dce63815Sdrahn void
full_dump_partition_entry(struct partition_map * map,int ix)198356b92ceSkrw full_dump_partition_entry(struct partition_map *map, int ix)
199dce63815Sdrahn {
200f8fa35e5Skrw 	struct entry *entry;
201dce63815Sdrahn 	int i;
202024cef13Skrw 	uint32_t t;
203dce63815Sdrahn 
204f8fa35e5Skrw 	entry = find_entry_by_disk_address(ix, map);
205f8fa35e5Skrw 	if (entry == NULL) {
206dce63815Sdrahn 		printf("No such partition\n");
207dce63815Sdrahn 		return;
208dce63815Sdrahn 	}
209f8fa35e5Skrw 	printf("             signature: 0x%x\n", entry->dpme_signature);
210f8fa35e5Skrw 	printf(" number of map entries: %u\n", entry->dpme_map_entries);
2113f012ab0Skrw 	printf("        physical start: %10u  length: %10u\n",
212f8fa35e5Skrw 	    entry->dpme_pblock_start, entry->dpme_pblocks);
2133f012ab0Skrw 	printf("         logical start: %10u  length: %10u\n",
214f8fa35e5Skrw 	    entry->dpme_lblock_start, entry->dpme_lblocks);
215dce63815Sdrahn 
216f8fa35e5Skrw 	printf("                 flags: 0x%x\n", entry->dpme_flags);
217dce63815Sdrahn 	printf("                        ");
218f8fa35e5Skrw 	if (entry->dpme_flags & DPME_VALID)
2193f012ab0Skrw 		printf("valid ");
220f8fa35e5Skrw 	if (entry->dpme_flags & DPME_ALLOCATED)
2213f012ab0Skrw 		printf("alloc ");
222f8fa35e5Skrw 	if (entry->dpme_flags & DPME_IN_USE)
2233f012ab0Skrw 		printf("in-use ");
224f8fa35e5Skrw 	if (entry->dpme_flags & DPME_BOOTABLE)
2253f012ab0Skrw 		printf("boot ");
226f8fa35e5Skrw 	if (entry->dpme_flags & DPME_READABLE)
2273f012ab0Skrw 		printf("read ");
228f8fa35e5Skrw 	if (entry->dpme_flags & DPME_WRITABLE)
2293f012ab0Skrw 		printf("write ");
230f8fa35e5Skrw 	if (entry->dpme_flags & DPME_OS_PIC_CODE)
2313f012ab0Skrw 		printf("pic ");
232f8fa35e5Skrw 	t = entry->dpme_flags >> 7;
233dce63815Sdrahn 	for (i = 7; i <= 31; i++) {
234bd45c0ecSkrw 		if (t & 0x1)
235dce63815Sdrahn 			printf("%d ", i);
236dce63815Sdrahn 		t = t >> 1;
237dce63815Sdrahn 	}
238dce63815Sdrahn 	printf("\n");
239dce63815Sdrahn 
240f8fa35e5Skrw 	printf("                  name: '%.32s'\n", entry->dpme_name);
241f8fa35e5Skrw 	printf("                  type: '%.32s'\n", entry->dpme_type);
242f8fa35e5Skrw 	printf("      boot start block: %10u\n", entry->dpme_boot_block);
243f8fa35e5Skrw 	printf("boot length (in bytes): %10u\n", entry->dpme_boot_bytes);
244f8fa35e5Skrw 	printf("          load address: 0x%08x\n", entry->dpme_load_addr);
245f8fa35e5Skrw 	printf("         start address: 0x%08x\n", entry->dpme_goto_addr);
246f8fa35e5Skrw 	printf("              checksum: 0x%08x\n", entry->dpme_checksum);
247f8fa35e5Skrw 	printf("             processor: '%.32s'\n", entry->dpme_processor_id);
24835985165Skrw 	printf("dpme_reserved_1 -");
249f8fa35e5Skrw 	dump_block(entry->dpme_reserved_1, sizeof(entry->dpme_reserved_1));
25035985165Skrw 	printf("dpme_reserved_2 -");
251f8fa35e5Skrw 	dump_block(entry->dpme_reserved_2, sizeof(entry->dpme_reserved_2));
25235985165Skrw 	printf("dpme_reserved_3 -");
253f8fa35e5Skrw 	dump_block(entry->dpme_reserved_3, sizeof(entry->dpme_reserved_3));
25435985165Skrw 	printf("dpme_reserved_4 -");
255f8fa35e5Skrw 	dump_block(entry->dpme_reserved_4, sizeof(entry->dpme_reserved_4));
256dce63815Sdrahn }
257dce63815Sdrahn 
258dce63815Sdrahn 
259dce63815Sdrahn void
dump_block(unsigned char * addr,int len)260dce63815Sdrahn dump_block(unsigned char *addr, int len)
261dce63815Sdrahn {
2623f012ab0Skrw 	int i, j, limit1, limit;
2633f012ab0Skrw 
264dce63815Sdrahn #define LINE_LEN 16
265dce63815Sdrahn #define UNIT_LEN  4
266dce63815Sdrahn #define OTHER_LEN  8
267dce63815Sdrahn 
268dce63815Sdrahn 	for (i = 0; i < len; i = limit) {
269dce63815Sdrahn 		limit1 = i + LINE_LEN;
270bd45c0ecSkrw 		if (limit1 > len)
271dce63815Sdrahn 			limit = len;
272bd45c0ecSkrw 		else
273dce63815Sdrahn 			limit = limit1;
274dce63815Sdrahn 		printf("\n%03x: ", i);
275dce63815Sdrahn 		for (j = i; j < limit1; j++) {
276bd45c0ecSkrw 			if (j % UNIT_LEN == 0)
277dce63815Sdrahn 				printf(" ");
278bd45c0ecSkrw 			if (j < limit)
279dce63815Sdrahn 				printf("%02x", addr[j]);
280bd45c0ecSkrw 			else
281dce63815Sdrahn 				printf("  ");
282dce63815Sdrahn 		}
283dce63815Sdrahn 		printf(" ");
284dce63815Sdrahn 		for (j = i; j < limit; j++) {
285bd45c0ecSkrw 			if (j % OTHER_LEN == 0)
286dce63815Sdrahn 				printf(" ");
287bd45c0ecSkrw 			if (addr[j] < ' ')
288dce63815Sdrahn 				printf(".");
289bd45c0ecSkrw 			else
290dce63815Sdrahn 				printf("%c", addr[j]);
291dce63815Sdrahn 		}
292dce63815Sdrahn 	}
293dce63815Sdrahn 	printf("\n");
294dce63815Sdrahn }
295dce63815Sdrahn 
296dce63815Sdrahn void
full_dump_block_zero(struct partition_map * map)297356b92ceSkrw full_dump_block_zero(struct partition_map *map)
298dce63815Sdrahn {
29970060700Skrw 	struct ddmap *m;
300dce63815Sdrahn 	int i;
301dce63815Sdrahn 
3026f012227Skrw 	m = map->sbDDMap;
303dce63815Sdrahn 
3046f012227Skrw 	printf("             signature: 0x%x\n", map->sbSig);
3056f012227Skrw 	printf("       size of a block: %u\n", map->sbBlkSize);
3066f012227Skrw 	printf("      number of blocks: %u\n", map->sbBlkCount);
3076f012227Skrw 	printf("           device type: 0x%x\n", map->sbDevType);
3086f012227Skrw 	printf("             device id: 0x%x\n", map->sbDevId);
3096f012227Skrw 	printf("                  data: 0x%x\n", map->sbData);
3106f012227Skrw 	printf("          driver count: %u\n", map->sbDrvrCount);
311f7e12bbcSkrw 	for (i = 0; i < 8; i++) {
312f7e12bbcSkrw 		if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0)
313dce63815Sdrahn 			break;
314024cef13Skrw 		printf("      driver %3u block: %u\n", i + 1, m[i].ddBlock);
315024cef13Skrw 		printf("        size in blocks: %u\n", m[i].ddSize);
316dce63815Sdrahn 		printf("           driver type: 0x%x\n", m[i].ddType);
317dce63815Sdrahn 	}
318dce63815Sdrahn 	printf("remainder of block -");
3196f012227Skrw 	dump_block(map->sbReserved, sizeof(map->sbReserved));
320dce63815Sdrahn }
321dce63815Sdrahn 
322dce63815Sdrahn int
get_max_type_string_length(struct partition_map * map)323356b92ceSkrw get_max_type_string_length(struct partition_map *map)
324dce63815Sdrahn {
325f4c16b6bSkrw 	struct entry *entry;
3263f012ab0Skrw 	int max, length;
327dce63815Sdrahn 
328dce63815Sdrahn 	max = 0;
329dce63815Sdrahn 
3300392b273Skrw 	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
331f8fa35e5Skrw 		length = strnlen(entry->dpme_type, DPISTRLEN);
332bd45c0ecSkrw 		if (length > max)
333dce63815Sdrahn 			max = length;
334dce63815Sdrahn 	}
335dce63815Sdrahn 
336dce63815Sdrahn 	return max;
337dce63815Sdrahn }
338dce63815Sdrahn 
339dce63815Sdrahn int
get_max_name_string_length(struct partition_map * map)340356b92ceSkrw get_max_name_string_length(struct partition_map *map)
341dce63815Sdrahn {
342f4c16b6bSkrw 	struct entry *entry;
3433f012ab0Skrw 	int max, length;
344dce63815Sdrahn 
345dce63815Sdrahn 	max = 0;
346dce63815Sdrahn 
3470392b273Skrw 	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
348f8fa35e5Skrw 		length = strnlen(entry->dpme_name, DPISTRLEN);
349bd45c0ecSkrw 		if (length > max)
350dce63815Sdrahn 			max = length;
351dce63815Sdrahn 	}
352dce63815Sdrahn 
353dce63815Sdrahn 	return max;
354dce63815Sdrahn }
355dce63815Sdrahn 
356dce63815Sdrahn int
get_max_base_or_length(struct partition_map * map)357356b92ceSkrw get_max_base_or_length(struct partition_map *map)
358dce63815Sdrahn {
359f4c16b6bSkrw 	struct entry *entry;
360dce63815Sdrahn 	int max;
361dce63815Sdrahn 
362dce63815Sdrahn 	max = 0;
363dce63815Sdrahn 
3640392b273Skrw 	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
365f8fa35e5Skrw 		if (entry->dpme_pblock_start > max)
366f8fa35e5Skrw 			max = entry->dpme_pblock_start;
367f8fa35e5Skrw 		if (entry->dpme_pblocks > max)
368f8fa35e5Skrw 			max = entry->dpme_pblocks;
369dce63815Sdrahn 	}
370dce63815Sdrahn 
371dce63815Sdrahn 	return max;
372dce63815Sdrahn }
373