Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative for boot1.efifat? #250

Closed
dnsefe opened this issue Nov 15, 2021 · 8 comments
Closed

Alternative for boot1.efifat? #250

dnsefe opened this issue Nov 15, 2021 · 8 comments
Assignees
Labels
feature Adding new functionality

Comments

@dnsefe
Copy link

dnsefe commented Nov 15, 2021

With FreeBSD 13 boot1.efifat is no longer built and thus not available (also stated in recent commits). In the arm.sh build script we have the following line under arm_install_efi():

DEV_EFI=$(mdconfig -a -t vnode -f ${STAGEDIR}/boot/boot1.efifat)

I guess we need a different approach in that case and eventually have to handroll our own efi image.

I wonder if an approach such as (see dvd.sh):

dd if=/dev/zero of=${STAGEDIR}/efiboot.img bs=4k count=200

would work. Any suggestions or a possible fix?

@fichtner
Copy link
Member

It’s being worked on for 22.1-RC. Shared code already exists.

@fichtner fichtner added the support Community support label Nov 15, 2021
@dnsefe
Copy link
Author

dnsefe commented Nov 15, 2021

That's great news! I am actually trying to build an image for my RPi CM4 based on 22.1.b1.
I succesfully built the world and kernel using the latest stable/22.1 src. Maybe I should note here that the kernel required an additional parameter to compile succesfully.

Just noticed that there is a release script in src. I guess I will have a look there and come up with some temporary solution until further notice :)

@fichtner
Copy link
Member

The necessary code was already added here

tools/build/common.sh

Lines 1118 to 1153 in c6184a4

setup_efiboot()
{
local EFIFILE
local EFIDIR
local FATBITS
local FATSIZE
FATSIZE=${3:-"33292"}
FATBITS=${4:-"32"}
EFIDIR="EFI/BOOT"
EFIFAT="$(dirname ${2})/boot1.efifat"
if [ -f ${EFIFAT} ]; then
# XXX FreeBSD 12.1 has a predefined file
# and we should use it for compatibility
cp ${EFIFAT} ${1}
return
fi
if [ ${PRODUCT_ARCH} = "amd64" ]; then
EFIFILE=bootx64
elif [ ${PRODUCT_ARCH} = "aarch64" ]; then
EFIFILE=bootaa64
else
echo ">>> Unsupported UEFI architecture: ${PRODUCT_ARCH}" >&2
exit 1
fi
mkdir -p ${1}.d/${EFIDIR}
cp ${2} ${1}.d/${EFIDIR}/${EFIFILE}.efi
makefs -t msdos -o fat_type=${FATBITS} -o sectors_per_cluster=1 \
-o volume_label=EFISYS -s ${FATSIZE}k ${1} ${1}.d
}

If you want you can try to give it a go in the arm script. I still have to verify the new method works in the amd64 images as well before I attempt to convert arm but if you can beat me to it that would be perfectly fine :)

@dnsefe
Copy link
Author

dnsefe commented Nov 22, 2021

Unfortunately, I didn't have time to adjust the code, but I figured out what has to be done :)
I was curious about the contents of boot1.efifat and decided to have a look into it. Apparently,
it consists only of the efi (BOOTaa64.efi) and startup startup.nsh file inside the efi/boot folder.
The efi file is actually built during the process, just under a different name.
In other words mounting boot1.efifat and copying its contents (as below) is not required:

DEV_EFI=$(mdconfig -a -t vnode -f ${STAGEDIR}/boot/boot1.efifat)
mount_msdosfs /dev/${DEV_EFI} ${STAGEDIR}/mnt
cp -r ${STAGEDIR}/mnt/efi ${STAGEDIR}/boot/msdos/efi

Instead we can just copy the efi file (with the adjusted file name) to its right location.

Should have a little more time this week and am hoping to finish it by the end of the week.
I am also planning to add some more options allowing GPT partitions, new devices etc. :)

I will do a PR once I am done and will make sure it's backwards compatible with the current version.

@fichtner
Copy link
Member

@efetropy not sure what you talk about as the code already exist and I linked to it in my previous post.

@dnsefe
Copy link
Author

dnsefe commented Nov 22, 2021

I guess what I wrote is a little bit missleading. To clarify, I just wanted to get rid of the line in the arm.sh script that uses boot1.efifat as it's not available in FreeBSD 13.

In arm.sh, we don't actually use an efiboot image and instead copy over the efi folder (provided by boot1.efifat) to the already made boot partition. That way we also avoid nomenclature for the efi file name. In the code from your previous post, we simply copy the loader.efi file with its adjusted name according to the architecture – in the arm case we would have to copy it to the boot partition.

The ARM script can be adjusted accordingly so that we don't need boot1.efifat at all actually. This rises another question though. FreeBSD 13 defaults to the newer loader_lua.efi and I wonder if loader.efi is symlinked to loader_lua.efi so that we don't have to worry about the case between FreeBSD 12/13. I guess I will know once I am ready to try out my script :)

My last question here is the following as I am not very familiar with these things. For aarch64, the efi file (BOOTaa64.efi) provided by boot1.efifat is almost half the size of loader.efi. I am not sure about the differences and technicalities, but I guess either one can be used?! I am asking since the efi file on the boot partition (EFI/BOOT) and in the boot folder are basically the same on my FreeBSD 13 aarch64 installation.

All in all thank you for the comments @fichtner ! I am almost done with the script, but the harddisk I had my previous built on bit the grass, so it might take some time for results.

UPDATE: Managed to cross compile for arm64 on an amd64 machine. Building base and kernel worked without issues. Haven't built the other packages yet, but I guess they should also work without an issue. I adjusted the script for testing purposes and only included base and kernel. Voila, the image is built with the correct partitions. Tried to boot up on my arm device. EFI works fine, yet I need to figure out why I am getting pernel panics :')

@fichtner
Copy link
Member

Well I meant that setup_efiboot() function already builds the required efifat file, but the arm script isn't using it yet. The loader.efi is properly linked to the used loader (and we use LUA now, yes).

Nice to hear that cross compile still works. :)

@dnsefe
Copy link
Author

dnsefe commented Nov 27, 2021

Nice to hear that cross compile still works. :)

It indeed works with some small changes to the device config. I used a device config named RPI.conf. To give an example for the RPI3 case, proceed as follows. Remove MAKE_ARGS_DEV (line 4-7) and aarch64-binutils (line 12) in:

tools/device/RPI3.conf

Lines 3 to 16 in fdddb70

export MAKE_ARGS_DEV="
CROSS_BINUTILS_PREFIX=/usr/local/aarch64-unknown-freebsd${SRCREVISION}/bin
UBLDR_LOADADDR=0x42000000
"
export PRODUCT_KERNEL=SMP-ARM
export PRODUCT_TARGET=arm64
export PRODUCT_ARCH=aarch64
export PRODUCT_WANTS="aarch64-binutils qemu-user-static u-boot-rpi3 rpi-firmware"
export ARM_FIRMWARE_DIR="/usr/local/share/rpi-firmware"
export ARM_UBOOT_DIR="/usr/local/share/u-boot/u-boot-rpi3"

That was not enough to compile the kernel as it was looking for a kernel config file named SMP-ARM-RPI (instead of SMP-ARM)
due to line 254 in:

tools/build/common.sh

Lines 252 to 255 in fdddb70

# reload the kernel according to device specifications
export PRODUCT_KERNEL="${PRODUCT_KERNEL}${PRODUCT_DEVICE+"-${PRODUCT_DEVICE}"}"

Commenting out that line allowed me to compile the kernel without issues. Compiling xtools also worked (haven't tested packages due to time contraints).

I mentioned kernel panics in my previous post. It was due to a bogus line in /etc/rc.conf which was supposed to be in fstab :) Fixing that solved the booting issue.

I noticed a very odd problem though. If I mount the created image in a FreeBSD 13 host, I can see the correct partitions, e.g.:

FREE SPACE ~ 1M
${DEV}s1 ~ 50M / fat32lba
${DEV}s2 ~ 3G / BSD
${DEV}s2a ~3G / freebsd-ufs

Writing the image with dd to a microSD card also shows the correct partitions there. However, if I copy the image over to my a Linux host and mount the image I only see two partitions – ${DEV}s1 and ${DEV}s2. Somehow FREE SPACE is not shown anymore and ${DEV}s2 & ${DEV}s2a seem to be merged?!
Again writing the image with dd to a microSD card doesn't show the right partitions of the microSD card on my Linux host, BUT on FreeBSD every partition is shown correctly regardless of the the host OS used to write the image.

I can't tell whether this is a bug or a feature under linux (or rather the packages used). Btw., I also downloaded the official FreeBSD 13 image for the device I used and guess what? Both on FreeBSD and Linux the correct partitions are shown – go figure :D

All in all, I am happy that everything worked out in the end and can't wait to try it out on my new device which will arrive soon :)

@fichtner fichtner self-assigned this Jan 4, 2022
@fichtner fichtner added feature Adding new functionality and removed support Community support labels Jan 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Adding new functionality
Development

No branches or pull requests

2 participants