#!/bin/sh

echo 'x/bu bootinfo,400' \
| crash \
| awk '
	BEGIN {
		bttype[0] = "bootpath"
		bttype[1] = "rootdevice"
		bttype[3] = "bootdisk"
		bttype[4] = "netif"
		bttype[6] = "console"
		bttype[7] = "biosgeom"
		bttype[8] = "symtab"
		bttype[9] = "memmap"
		bttype[10] = "bootwedge"
		bttype[11] = "modulelist"
		bttype[12] = "framebuffer"
		bttype[13] = "userconfcommands"
		bttype[14] = "efi"
		bttype[15] = "efimemmap"
		bttype[16] = "prekern"
	}
	/^bootinfo/ {
		for (i=2; i<=NF; ++i)
			btinfo[++bytes] = $i
	}
	function word(i) {
		return btinfo[i] + btinfo[i+1]*256
	}
	function long(i) {
		return word(i) + word(i+2) * 65536
	}
	function quad(i) {
		return long(i) + long(i+4) * 65536 * 65536
	}
	function dump(i,n,  k) {
		for (k=0; k<n; ++k) {
			if (k % 8 == 0)
				printf " %04x",k;
			printf " %02x",btinfo[i+k]
			if (k % 8 == 7 || k == n-1)
				printf "\n"
		}
	}
	function string(i,n,  k,s) {
		s = ""
		for (k=0; k<n; ++k) {
			s = s sprintf("%c",btinfo[i+k])
		}
		return s
	}
	function part(i) {
		return sprintf("%02x:%02x %u/%u/%u-%u/%u/%u %u+%u", \
			btinfo[i], \
			btinfo[i+4], \
			btinfo[i+3], btinfo[i+1], btinfo[i+2], \
			btinfo[i+7], btinfo[i+5], btinfo[i+6], \
			long(i+8), \
			long(i+12))
	}
	END {
		entries = long(1)

		off = 5
		for (i=1; i<=entries && off <= bytes; ++i) {
			len  = long(off)
			type = long(off+4)
			if (type in bttype) type = bttype[type]
			print i,type
			if (len < 8)
				break
			off += 8
			len -= 8

			if (type == "console") {
				print "\tdevname",string(off,16)
				print "\taddr",long(off+16)
				print "\tspeed",string(off+20)
			}

			else if (type == "bootpath") {
				print "\tpath",string(off,len)
			}

			else if (type == "bootdisk") {
				print "\tlabel",long(off)
				print "\ttype",word(off+4)
				print "\tcheck",word(off+6)
				print "\tpack",string(off+8,16)
				print "\tdev",long(off+24)
				print "\tpart",long(off+28)
			}

			else if (type == "bootwedge") {
				print "\tdev",long(off)
				print "\tstartblk",quad(off+4)
				print "\tnblks",quad(off+12)
				print "\tmatchblk",quad(off+20)
				print "\tmatchnblks",quad(off+28)
				printf "\tmatchhash %08x%08x%08x%08x\n", \
					long(off+36),long(off+40), \
					long(off+44),long(off+48)
			}

			else if (type == "biosgeom") {
				num = long(off)
				rec = off + 4
				for (j=1; j<=num && off <= bytes; ++j) {
					print "\tgeom",j ": ", \
						long(rec+8) "/" \
						long(rec+4) "/" \
						long(rec)
					print "\t\ttotal ",quad(rec+16)
					printf "\t\tflags  %08x\n",long(rec+20)
					printf "\t\tdev    %08x\n",long(rec+24)
					printf "\t\tchksum %08x\n",long(rec+28)
					printf "\t\tipath  %08x\n",long(rec+32)
					printf "\t\tdpath  %08x%08x\n", \
						long(rec+40), \
						long(rec+36)
					printf "\t\tres0   %08x\n",long(rec+44)
					print "\t\tmbr#1 ",part(rec+48)
					print "\t\tmbr#2 ",part(rec+64)
					print "\t\tmbr#3 ",part(rec+80)
					print "\t\tmbr#4 ",part(rec+96)
					rec += 112
				}
			}

			else if (type == "rootdevice")
				print "\troot",string(off,len)

			else if (type == "modulelist") {
				num = long(off)
				endpa = long(off+4)
				printf "\tload @%08x #%u\n",endpa,num
				rec = off + 8
				for (j=1; j<=num && off <= bytes; ++j) {
					print "\t" j
					print "\t\tpath",string(rec)
					print "\t\ttype",long(rec+80)
					print "\t\tlen",long(rec+84)
					print "\t\tbase",long(rec+88)
					rec += 92
				}
			}

			else {
				dump(off, len)
			}
				
			off += len
		}
	}
'
