(re)installing the boot loader

decuser

Member

Thanks: 2
Messages: 33

#1
In my exploration of /usr/src/sys, I've been looking at boot and messing around with the boot loader. I overwrote my boot0 by booting the 11 dvd and doing:
fdisk -B -b /boot/boot0 ada0

Now, I get a simple boot prompt:
F1 FreeBSD

and I realize that I've changed the boot process (this is a good thing). However, I also realize that 1) I overwrote whatever the installer put there and 2) it ain't what I messed with in /usr/src/sys/boot...

I figured that I could copy /boot/boot0 from the installed system to another media, and then use fdisk to put that boot0 back, would work, but it didn't seem to do anything. But, what I really want to do anyway is learn how to restore the full boot loader when things go wrong, and also how to install the bootloader from /usr/src/sys. I have read portions of the FreeBSD Architecture Handbook related to the boot process, but it's not clear to me exactly what files are needed to put the boot process back together again. Is there a "restore your bootloader and configuration" guide out there or do y'all have a 5 easy steps approach to this?

This is FreeBSD 11 on a VM

Thanks,
Will
 

ShelLuser

Son of Beastie

Thanks: 1,578
Messages: 3,431

#2
Why use fdisk in the first place though? Use gpart(8) instead, it's manualpage will give you a full example of what to do.

Generally speaking the FreeBSD handbook is a good source of documentation, in this case, in this case chapter 12 (booting process) might be a good read.
 

Maelstorm

Well-Known Member

Thanks: 130
Messages: 326

#3
If you overwrote boot0 you might be royally screwed. Depending on your system (BIOS/MBR or UEIF/GPT) boot0 contains critical partitioning information. I have written partitioning code, both MBR and GPT. There are actually *2* copies of the GPT. The first copy starts right after where boot0 is. The second copy is at the end of the physical medium.

In BIOS/MBR, the BIOS reads LBA 0 and executes the program there. LBA 0 is also called boot0 and contains the bootstrap program which looks at the embedded partition table (which has a maximum of four entries) and looks for one that has the active bit set. The partition which has the active bit set, it loads the first sector of that partition and executes the program contained there. That sector has several name such as the volume boot record, OS boot record, etc..., but FreeBSD calls it boot1. Boot1 is not just that one sector, but a series of disk sectors. So the program in the VBR loads the rest of the sectors and combines them into a single program and executes it. Then it goes looking for boot3 which is the main boot loader which loads the kernel and displays the startup screen. Boot3 then calls mi_startup() in /usr/src/sys/kern/start_main.c

Boot2 is part of boot1 so I didn't really mention it.

Now as to how to restore the boot blocks, you can use dd to do that. Since we know where things on the disk are, you can do something like this:

dd if=/dev/ad0 of=/tmp/bootbackup bs=512 count=81

Boot0 is in LBA 0, but there is a gap from LBA 1-63. So boot1 and boot2 start at LBA 64 and since it's 8K in size, that's 16 512-byte sectors. Although I could be off by one or something.
 

SirDice

Administrator
Staff member
Administrator
Moderator

Thanks: 6,609
Messages: 28,149

#4
The boot0cfg(8) you wrote is an old bootmanager, it's only capable of handling MBR with UFS.

What you need is going to depend on MBR vs. GPT, UFS vs. ZFS, CSM vs UEFI. There are a lot of combinations possible and they all need to be configured differently.
 

balanga

Daemon

Thanks: 95
Messages: 2,339

#5
I've never fully understood how the boot process works especially with different boot managers and which boot code goes where and what the differences are between MBR and GPT. I know that if I want to use Grub on a GPT system I ned to include a bios-boot partition, but I'm not sure what the purpose is of the freebsd-boot partition.

I've also noticed, having just installed 11.2 that no EFI partition was needed - (maybe I installed on a different system...)
 
OP
OP
decuser

decuser

Member

Thanks: 2
Messages: 33

#6
hmm, no messy with system installed bootloader, got it! I'll just do a restore of the snapshot I did before I screwed it up. In the future, I will endeavor to do my boot loader explorations on another disk.
 
OP
OP
decuser

decuser

Member

Thanks: 2
Messages: 33

#7
Now as to how to restore the boot blocks, you can use dd to do that. Since we know where things on the disk are, you can do something like this:

dd if=/dev/ad0 of=/tmp/bootbackup bs=512 count=81

Boot0 is in LBA 0, but there is a gap from LBA 1-63. So boot1 and boot2 start at LBA 64 and since it's 8K in size, that's 16 512-byte sectors. Although I could be off by one or something.
OK. So this worked:

dd if=/dev/ada0 of=/tmp/bootbackup bs=512 count=81

where I changed ad0 to ada0 for my configuration. Why doesn't this work?:

dd if=/dev/ada0 of=/tmp/bootbackup bs=1 count=512

to backup just the boot0 (MBR) or this:

dd if=/dev/ada0 of=/tmp/bootbackup bs=1 count=446

to backup just the boot porition. Both of these commands result in:

dd: /dev/ada0: Invalid argument

What gives?
 
OP
OP
decuser

decuser

Member

Thanks: 2
Messages: 33

#8
I've been thunking... is it that you can't read a byte at a time from a virtual box VDI? I'm thinking maybe not. So, if that's the case, here's my convoluted work around - please advise if there's a simpler way.

If I want to restore just the 446 bytes and not the rest, but I can't read (or write?) in chunks smaller than 512 from the virtual disk. How about I read 512 to a file, then replace 446 bytes of the file before writing to the virtual disk?

dd if=/dev/ada0 of=/tmp/bootbackup bs=512 count=1
dd if=/tmp/bootbackup of=/tmp/justthegoodstuff bs=1 count=446


... something goes awry with the boot block, but the partition info is still ok (prolly can't happen if reads and writes are >=512, but hey)

dd if=/dev/ada0 of=/tmp/badboot bs=512 count=1
cp /tmp/badboot /tmp/boottorestore
dd if=/tmp/justthegoodstuff of=/tmp/boottorestore bs=1 count=446
dd if=/tmp/boottorestore bs=512 count=1


off to put theory to test while I eagerly await y'alls sage advice and corrrections.
 

Chris_H

Daemon

Thanks: 186
Messages: 1,076

#9
You know. If you make a backup file of it with dd(1), then save it somewhere where you will always have access it. Like another disk. You can experiment all you like. Cause you'll always have that backup to write it back with. :) If it's GPT. and the backup (on the original disk) ever gets out of sync. gpart(8) will inform you, and allow you to correct it with the backup copy it has. :)

--Chris
 

Maelstorm

Well-Known Member

Thanks: 130
Messages: 326

#10
OK. So this worked:

dd if=/dev/ada0 of=/tmp/bootbackup bs=512 count=81

where I changed ad0 to ada0 for my configuration. Why doesn't this work?:

dd if=/dev/ada0 of=/tmp/bootbackup bs=1 count=512

to backup just the boot0 (MBR) or this:

dd if=/dev/ada0 of=/tmp/bootbackup bs=1 count=446

to backup just the boot porition. Both of these commands result in:

dd: /dev/ada0: Invalid argument

What gives?
The bs parameter is block size which cannot be less than the smallest block size the device can handle. For HDs that's 512 bytes. Count is the number of blocks at bs size to transfer. So bs=1 is a block size of 1 bytes and count=512 means transfer 512 1 byte blocks, which is not going to work for a disk. I think you meant bs=512 count=1.

Oh, and for HDs, bs must be a multiple of 512.
 
Top