FreeBSD support #673
Replies: 27 comments 14 replies
-
FreeBSD booting has been a long-standing project "want" - we'd absolutely welcome it! Roughly speaking, how would the |
Beta Was this translation helpful? Give feedback.
-
+1 for this. I've dreamt of FreeBSD support ever since the OpenZFS unification. |
Beta Was this translation helpful? Give feedback.
-
To boot entirely off a ZFS BE, the process would be approximately
Setting 'bootdev' like this will cause the boot loader to use that as the 'load' device for both the loader's file (lua scripts, loader.conf) as well as finding the kernel here. Both will also clear 'bootonce' if it is set, but the latter will boot the geribils BE regardless of its current bootonce setting. For this project, the second form is likely preferable (the first form is actually loader.kboot's default). There's also ways to pass in a mfs image, should that be desirable. We use
with a loader.conf in that has image that has
in it. loader.kboot has a number heuristics to guess the right thing to use, so it sees that the boot device should be this MD file. It's unclear how helpful these probing things are, and you may need to be more explicit with |
Beta Was this translation helpful? Give feedback.
-
A few questions:
ZFSBootMenu is modular enough / we already have OS detection via |
Beta Was this translation helpful? Give feedback.
-
I'll have to see how hard it is to build on Linux... I have a linux test machine that was just built for me that I need to log into for amd64 kboot work anyway... /stand is built such that the loader.kboot is a linux binary, no matter what... Some of the other loaders may be less tolerant of that, but 'can be built' might mean needing to build a few things piecemeal, then linking loader.kboot.... we do pull from bits of the FreeBSD kernel, OpenZFS sources, FreeBSD's libc, etc when building the boot loader stuff, so it would be a relatively full source tree... |
Beta Was this translation helpful? Give feedback.
-
Any updates on this issue? 😄 |
Beta Was this translation helpful? Give feedback.
-
Bumping this up for attention. Is there any help needed to kickstart the work on this ? |
Beta Was this translation helpful? Give feedback.
-
I have LinuxBoot working for FreeBSD/arm64, but not for FreeBSD/amd64 yet. I guess, what do you need from me to proceed? |
Beta Was this translation helpful? Give feedback.
-
Unfortunately, right now we realistically only support amd64. The most readily available arm64 hardware - RPI - has a number of problems that limits it's usefulness for us. Once amd64 support is available, we'll be happy to start hacking on integrating that tool into ZBM! |
Beta Was this translation helpful? Give feedback.
-
Well, FreeBSD/amd64 loader.kboot builds and runs on the Linux side, FreeBSD has an annoying couple of bugs still that panic the boot... I'll let you know when that changes. |
Beta Was this translation helpful? Give feedback.
-
hello, I'm looking into this. have you discovered anything new since last month? |
Beta Was this translation helpful? Give feedback.
-
I still need to fix a few things on the amd64 side of the house for LinuxBoot, and $WORK has had me focused on other stuff. Though soon I should become focused on it again now that we're entering an end of the year quiet period. |
Beta Was this translation helpful? Give feedback.
-
Nice to meet you, bsdimp. I got the kboot building on my gentoo host, nice work by the way. |
Beta Was this translation helpful? Give feedback.
-
Sure. The more the better. aarch64 works fairly well (though I have had some problems pushing the linuxboot linux kernel and inintrd all the way into the UEFI FD image). |
Beta Was this translation helpful? Give feedback.
-
@philmb3487 and by 'kboot' do you mean the loader.kboot that's in FreeBSD? |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Update, I have it loading the FreeBSD kernel, and booting into early init code. But there is a problem in the lgdt() load in machdep.c:954, as the stack seems to be off by a few bytes, and the machine hangs up. |
Beta Was this translation helpful? Give feedback.
-
It's pretty cool for sure. I wrote a little utility 'kexecbsd' to boot freebsd kernel's. I need to add support for AMD64. At the very least, now I know it can be done, and how. |
Beta Was this translation helpful? Give feedback.
-
I'm struggling with AMD64. It's a lot stricter when it comes to memory accesses, I'm getting a general fault when using any sort of 'push' instruction and pulling my hair out trying to figure it out. My GDT allows writes.
what could make 'push' break? |
Beta Was this translation helpful? Give feedback.
-
I'm spending more time on this.
Trampoline entry ends up at 0x0000000012b00000, but the loader seems to think it should go to 0x12d00000. Paging structure PML4T should be located at 0x12d01000, but that location is not filled in properly (there's just ASCII text, the actual mapping code looks OK). |
Beta Was this translation helpful? Give feedback.
-
That first segment looks suspicious, that for sure should not be there. Also, I'd like to add a column 'NAME' so we know what's being loaded. Maybe that's not possible if printing the kexec_segment structure... MEMSZ looks OK. |
Beta Was this translation helpful? Give feedback.
-
Yea, last time I was actively doing things, we'd panic. But we do store the page table after the trampoline page. And there's an offset sometimes in reporting. As luck would have it, linuxboot is next up on my work dance card, which I start Monday after a trip to the bay area. Maybe I'll try it on my mac + qemu so I can use it on the trip this week instead. I kept hitting issues with amd64 when I first started doing the work, so I switched to arm64, and we routinely boot FreeBSD with kexec on an embedded platform we're working to integrate with, so I know it works well on arm64. Now to get it to work for amd64... Do you have any FreeBSD changes to get to where you are? |
Beta Was this translation helpful? Give feedback.
-
Yeah, the paging is fine. My toy experimental loader booted fine with that algorithm. Set the physical memory below 4GB identity mapped, and the top 2GB of RAM to the loaded kernel. And the kernel started at ffffffff803d7000.
I wish you good luck then. Please let your boss know I would be more than willing to work on whatever project they have, should they be okay with a remote worker... :-)
space_avail() seems to be the culprit, as far as I can see. By faking the available memory,
Segment 1 is clearly the loaded ELF bundle, with modules, and segment 2 is clearly the trampoline code, along with the 9 paging tables that go in cr3. I have not tested yet, that should come tomorrow, but it's looking better. Here are my recommendations, parsing /proc/iomem is fine, but there's an even easier way, the /sys filesystem on linux provides firmware/memmap/ for information about the memory segments. But never mind, the /proc/iomem way should be fine, just a bit more parsing to do. The seg.c file does the right thing, I think, but it doesn't seem to be called properly, because otherwise the first segment would load properly. In other words, I'm talking about,
space_avail() should panic in case 0 is the result. I think of it as allocating memory, in case allocating memory for the kernel fails, there's really nothing we can do to recover. I think there's no need to go so high.... I copied the kernel in memory to 0x200000 (as is indicated in the elf file, PA field of the program's LOAD entries) and that worked just fine. The machine should pretty much always have memory at 2MiB we can use. Perhaps there are EFI considerations here I'm not thinking about, that seems to be the reason for "staging", ie you're copying around twice the kernel? |
Beta Was this translation helpful? Give feedback.
-
@bsdimp Doh, the code already reads from /sys/firmware/memmap, so that's great. Looks like I read too fast. Here's a patch that hopefully gets rid of the gnat with space_avail(), --- a/stand/kboot/kboot/arch/amd64/load_addr.c
+++ b/stand/kboot/kboot/arch/amd64/load_addr.c
@@ -53,11 +53,11 @@ struct kv
{ system_ram, "System RAM" },
{ acpi_tables, "ACPI Tables" },
{ acpi_nv_storage, "ACPI Non-volatile Storage" },
- { unusable, "Unusable memory" },
+ { unusable, "Unusable memory" },
{ persistent_old, "Persistent Memory (legacy)" },
{ persistent, "Persistent Memory" },
{ soft_reserved, "Soft Reserved" },
- { reserved, "reserved" },
+ { reserved, "Reserved" },
{ 0, NULL },
}; |
Beta Was this translation helpful? Give feedback.
-
We're parsing it, but we're not doing it correctly. As part of doing the arm64 work after the initial amd64 support I refactored this stuff. I need to redo the amd64 stuff with that, and I'll likely just grab /sys/firmware/efi/runtime-map... unless you've already done that :). |
Beta Was this translation helpful? Give feedback.
-
So kexec / EFI / Linux question. On aarch64, I can easily get the EFI systbl (EFI_SYSTEM_TABLE) and from that get both the config table and the config table length. I think I have that covered (with our without /dev/mem, the only casualty of no /dev/mem is printing the table in the loader). But on amd64/x86_64, I have only pointers to the config table, the fw_vendor and the runtime services table. There's nothing that points to the systbl nor does there seem to be a way to get the number of entries in the config table. I'm having trouble finding where this comes from in the kexec case. The efi_setup_data has a PA for the tables (as element tables), for smbios, for the runtime table, etc. But not the count of number of entries. I don't see anything in the kernel that 'probes' for that, nor any math done to get/set nr_tables. I don't see it doing something weird as finding the right map entry and inferring the length from that... Anybody here know what I'm missing (or know who to ask to wisper the right file to read or the right routine to grep for)? All the places inside the Linux kernel fish it out of systab, but I don't see where it's set in the kexec path since kexec can't get systab directly, only the fields that are valid after ExitBootServices, except nr_tables... I'm feeling extra unobservant today. |
Beta Was this translation helpful? Give feedback.
-
So I think what's going on:
This means that the data from (2) isn't exported via sysfs because purgatory, the in-kernel-kexec-loader copies it over. The pointer to the boot_param structure is stored in rsi. So that means we'll have to snag systbl from the efi_info in the trampoline (offset 0x1c0 from %rsi) and write it to an address we burn into the trampoline code which corresponds to the metadata section we associate with the kernel. And we'll also need a new section that we'll pass in the PAs we harvest from the sysfs for runtime, cfgtbl and fw_vendor. This will let the kernel piece together the systbl, and the PAs it needs to access the runtime and cfgtbl stuff (since the pointers stored there can no longer be assumed to be 1:1 PA == VA since SetVirtualAddresses rewrites them). I'll have to create a new metadata section for that which the kernel can read and cope in the kexec case. We can reuse a lot of the code that I did for aarch64 which provides the PA if the systbl in a sensible way. Not sure why the same issue isn't there. So, once all this is coded up, I should be passing in all the right EFI data for us to make good progress, though the VA != PA issues will likely need some more intensive FreeBSD kernel hacking than I wanted to do if I want to support EFI variables (which i want to because $WORK is dependent on it). So that's how Linux gets the length of the cfgtbl.... Simple and clear, eh? Oh, and arch/x86/include/uapi/asm/bootparam.h and arch/x86/kernel/kexec-bzimage64.c are the breadcrumbs I'll need in the future. |
Beta Was this translation helpful? Give feedback.
-
FreeBSD now has loader.kboot for booting from Linux into FreeBSD. this works really well on aarch64, and will soon work well for amd64 (once I find the time to finish it).
I've been asked if ZBM could support FreeBSD booting. Looking quickly at the code, it looks like that could be accommodated with a custom detection for FreeBSD and a different boot recipe using loader.kboot instead of the kexec tools that the current script uses.
Would you be open to working together to make this happen?
Beta Was this translation helpful? Give feedback.
All reactions