This is an old revision of the document!
The Dreaded ACPI Timeout Bug
Some models can experience really, really long boot times with OpenBSD. This bug has been known for a while and seems to have appeared around OpenBSD 7.6. It has featured in a lot of discussions, and resolving it caused so much unbridled joy that it prompted the creation of this entire wiki.
The Symptoms
Booting the stock installer or kernel will cause the boot procedure to hang quite early on, usually after identifying the hard disks:
As @brynet@bsd.network pointed out, it is caused by “some kind of regression that triggers a weird ACPI firmware bug on this machine.”
The machine will boot, eventually, if you leave it long enough, usually 2+ hours. However, without applying a simple patch to the kernel, it will do the same thing every single time you boot the machine.
Affected Models
- A1502 Early 2015 Macbook Pro
- Maybe others?
Patch to fix the ACPI bug
Index: sys/dev/acpi/acpi.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpi.c,v diff -u -p -u -r1.444 acpi.c --- sys/dev/acpi/acpi.c 24 Mar 2025 09:53:20 -0000 1.444 +++ sys/dev/acpi/acpi.c 20 Apr 2025 19:45:13 -0000 @@ -823,8 +823,8 @@ acpi_pci_set_powerstate(pci_chipset_tag_ } #endif /* NACPIPWRRES > 0 */ - if (state == ACPI_STATE_D0 && pre) - aml_evalname(sc, pdev->node, "_PS0", 0, NULL, NULL); +// if (state == ACPI_STATE_D0 && pre) +// aml_evalname(sc, pdev->node, "_PS0", 0, NULL, NULL); } int
How to patch
You have two options: build a custom installer and install your system with a patched kernel, or going the “slow way” and wait out the long boot time on booting the installer; installing the system; waiting out the first boot; then patching the kernel for the machine you are on.
Before you start, give the following manual pages a good read, you will have a much clearer understanding of what's going on:
- If going the “Custom installer” route, OpenBSD FAQ - Creating Install Media
I. The Slow Boot Way
Waiting out the slow boot times is probably a little bit easier, and it doesn't require you to have another working OpenBSD install that you can use to compile a custom kernel and create a custom installer image.
So after you have downloaded the latest installXX.img
, flashed it to a USB drive or whatever, plugged it in, booted up the Mac by holding down Option until you see the bootloader screen, selected the USB drive (“EFI BOOT” usually), started the installer, waited / slept / went for a walk until it got over the ACPI nonsense, installed, rebooted, waited / slept / went for a walk until it got over the ACPI nonsense again, and logged in…
0. Setting some ENV variables
It makes your life easier if you set the $CVSROOT env variable in your ~/.profile
or ~/.kshrc
or preferred place that will get sourced on login.
First, pick a server close to you from the list at the bottom of the OpenBSD Anonymous CVS page
Then add to your dotfile of choice the below:
export CVSROOT=anoncvs@url-to-your-cvs-server-of-cho.ice:/cvs
And source it:
$ . ~/.my-favourite-dotfile
1. Add your user to the source groups
You need to be a member of wsrc
and wobj
groups. As root, therefore, run:
# usermod -G wsrc,wobj $YOURUSERNAME
2. CVS Checkout the Tree of the Sauce
It is important that you get the sources for the branch you follow. Check the instructions under “Getting an Initial Tree” on the OpenBSD Anonymous CVS page.
If you are on -current
, it's advised you make sure you are on the latest snapshot before downloading the source tree, by running # sysupgrade -s
first.
First checkout takes a while, but once done, you should have the source tree in /usr/src
.
3. Patch / Edit the appropriate files
Paste the contents of the Patch above into a new file (let's call it best-patch-ever.diff mac_acpi_patch.diff
for our purposes), and then run:
$ patch < mac_acpi_patch.diff
You can of course simply comment out the two (!) affected lines manually; you need to delete / comment out two lines in /usr/src/sys/dev/acpi/acpi.c
. (In OpenBSD 7.7 they start at :823).
4. Compiling
Follow the release(8)
man page closely here.
As root, first, change directories to the appropriate directory in /sys
. Make sure you are in the right folder because /usr/src/sys
follows the same directory structure, but if you compile from there, you won't get the right results. This was a lesson learned The Hard Way™. So to be on the safe side do exactly as the manpage says, and run:
$ doas -s # cd /sys/arch/amd64/compile/GENERIC.MP
Then proceed as the manual suggests, with root privileges - otherwise “make install” will fail. This is another lesson learned The Hard Way™.
# make obj # make config # make && make install
After you reboot, the new kernel should be the one in use. It will be easy to tell whether the patch worked, because if your system boots “normally”, it worked, if you are back at waiting for 2+ hours at “sd0”, it failed and you need to check over whether you did everything correctly.
Updating the patched system
If you want to avoid having to wait 2+ hours again TWICE everytime you have to update your system, there is, fortunately, a much quicker way to do it. Basically the less painfully slow update method is a hybrid of manual and automatic installation with custom-compiling the kernel. Credits go to Stuart Henderson for pointing out this possibility.
The below will be a walkthrough that follows -current
, a few commands will be different for -stable
, these will be indicated.
0. Preparation
0.a. READ UP. Seriously.
Read through the OpenBSD Manual Installation howto in the FAQ first as well as the man pages linked above, if you have not done so. They will make your life much much easier.
0.b. Preparation
Follow the “Preparation” steps on the Manual Upgrade page: especially on becoming root “properly” and installing the boot blocks. Make sure you install the boot blocks to the appropriate drive, do not just go with “sd0” as it was in the tutorial, if, say your root is on e.g. sd3.
1. Get the upgrade files
Fetch the updates and move them to a new location. When you run sysupgrade
the installer files are stored in /home/_sysupgrade
, and two extra files are created, /bsd.update
and /auto_upgrade.conf
. You want to copy the installer files from /home/_sysupgrade
somewhere else, and delete the auto-update files.
# sysupgrade -ns # mkdir /usr/update # mv /home/_sysupgrade/* /usr/update/ # rm /{bsd.update,auto_upgrade.conf}
NB: On -stable
you want to run sysupgrade -n
.
2. Update the source tree
Follow the Anonymous CVS guides for updating the source tree to the latest version. ☛ ASIDE - What to do if acpi.c changes drastically and the patch doesn't work anymore? 1)
To update the source tree on -current
, run:
$ cd /usr/src $ cvs -q up -Pd -A
NB: On -stable
you want to use -rOPENBSD_7_7
as the last parameter instead of “-A”.
3. Re-compile the GENERIC.MP Kernel
See above, but run # make clean
before compiling and do not run # make install
at the end:
# cd /sys/arch/amd64/compile/GENERIC.MP/ # make clean # make obj # make config # make
Your newly compiled kernel file, bsd.gdb
will be in the symlinked obj
directory. The symlink points to /usr/obj/sys/arch/amd64/compile/GENERIC.MP/bsd.gdb
.
Now we have: - The latest update files stored away safely - The latest kernel, compiled with our own patch
So it is time to move on to the installation.
4. Manual installation
This follows closely the official manual installation guide, but diverges for the installation of the kernel.
4.a. Make sure you have done all the preparation in the official guide
Did you?
4.b Install the newly compiled kernel
We did not run make install
after compiling because we are going to do this little dance as suggested:
# cd /usr/update # ln -f /bsd /obsd # cp /usr/obj/sys/arch/amd64/compile/GENERIC.MP/bsd.gdb /nbsd && mv /nbsd /bsd # cp bsd.rd / # cp bsd /bsd.sp # You might not even have this file, relatively safe to skip this last one
4.c follow the rest of the Manual Install Process
Follow closely the linked manual installation guide, and continue the process: Enable KARL; Install new userland. Reboot. Run MAKEDEV, update the boot loader, run sysmerge
and fw_update
.
DONE!
/usr/src/sys/dev/acpi/acpi.c
, might change in the future. It is good to check the CVS logs, or keep an eye on the acpi.c on GitHub's CVS mirror. If you would see that the lines we have been working with have changed in the source or new features have been introduced, then you need to revert your local modifications to the CVS version. To do this, you need to run,
$ cd /usr/src/sys/dev/acpi/ $ cvs update -C acpi.cCVS will tell you where it stashed the previous file, it usually starts with “.#” or similar. You can then run
diff
and see what the changes were, decide whether you need to find the lines that were previously around :823 and automatically or manually patch again, or not.