@Hypex I haven't read all of the lengthy discussion but I don't think amigaboot.of does any ELF loading. It does what BBoot does which is just load all the modules in the memory and make a list of them that is passed to the loader binary that probably handles the ELF stuff (or just relocations) and calls kernel. If you want to see what OF calls amigaboot.of makes you can try: qemu-system-ppc -M pegasos2 -kernel amigaboot.of -trace enable="vof*" but it won't get very far because at some point it tries to use interpret to call into OF which is not handled by VOF. Once I tried adding handling of the alloc-mem call it first makes so it could get past that but then it tried to open devices to read blocks from disk which would have been too much to emulate in VOF so that's when I decided to write BBoot instead. Amigaboot.of probably needs open and read words or similar to work for devices to boot from so in OF you can try "cd /path/to/device" and then "words" to see if it defines the necessary words and try if it works.
By the way if CFE can read a zip file from disk into memory you could add support for X1000 to BBoot and forget amigaboot.of.
I haven't read all of the lengthy discussion but I don't think amigaboot.of does any ELF loading. It does what BBoot does which is just load all the modules in the memory and make a list of them that is passed to the loader binary that probably handles the ELF stuff (or just relocations) and calls kernel.
Unless something radically changed in the last 20 years booting AmigaOS 4.x, no matter with with firmware, involves 3 major parts: 1) The firmware itself, aka the 1st level boot loader (= AmigaOS 3.x/m68k on classic Amigas, U-Boot on the AmigaOne SE/XE/µA1/X5000/A1222, CFE on X1000, SmartFirmware on the Pegasos2, etc.): Loads and starts the 2nd level boot loader (SLB_v2 on the A1 and Sam440/460, AmigaBoot.(of|ub) on X1000/X5000/A1222, no idea about the Pegasos2). Loading the SLB_v2 (or replacements like Acube's ub2lb/Parthenope) doesn't involve any file systems, it's stored in the "BOOT" sectors of the RSDK/RDB blocks of a HDD/SSD, or using the El Torito standard in case of ISO9660 (ATAPI CD/DVD/BD hardware, or an IOS9960 image stored on an USB stick). 2) The 2nd level boot loader implements the file systems, for example FFS, ext2fs (for booting PPC Linux), ISO9660, SFS, etc., using callback hooks from the firmware for reading sectors from the current boot device (no matter if PATA, SATA, NVMe, USB, MicroSD or whatever). I don't know all of them, but for example the A1/Sam SLB_v2 supports loading and unpacking gzip and bzip2 compressed kickstart modules as well. There is a replacement for SLB_v2 from ACube called Parthenope/ub2lb which supports booting Linux and AROS (maybe MorphOS too, not sure), but unlike the original SLB_v2 it doesn't support booting AmigaOS 4.x from SFS\0 and SFS\2 partitions. 3) The "EXEC" entry in the kicklayout: A simple ELF parser which might be different for different systems (loader, loader.ub, loader.of, ...): relocating the other ELF executables in the kicklayout (all "MODULE" entries in the kicklayout). But "loader" only works in RAM, it doesn't support loading anything from disk, that was alreay done by the 1st level (firmware) and/or 2nd level (SLB_v2/ub2lb/...) boot loaders already.
I haven't read all of the lengthy discussion but I don't think amigaboot.of does any ELF loading. It does what BBoot does which is just load all the modules in the memory and make a list of them that is passed to the loader binary that probably handles the ELF stuff (or just relocations) and calls kernel.
Thanks for your input. The lengthy discussion was driven by me trying to figure out how to boot OS4 off USB, which apparently was possible a decade ago, but looks impossible now.
With amigaboot it would build a list. I would call it KickList made up of KickModules. I agree it would be the final EXEC loader binary handling the ELF loads. Technically the elf.library could handle ELF loading but since it can't load it self that won't be doing it. What I don't know is if the loader is doing it directly or knows how to ask CFE, since CFE obviously has an ELF loader. It would be efficient to use existing functions, but if they are not suitable or not available, then it has to be coded in. I couldn't find any evidence for an ELF loader in the EXEC loader. There are "ELF" strings in binary but they are messages. Given common ELF magic code doesn't look for a long word ID like it could, but looks by the byte, a 7F ELF string may not be as obvious. Or I needed to check all 7F bytes.
My obsession stems from my own boot loader X1Boot, that I wrote to boot Linux off HDD, where I needed to load the kernel ELF in memory and wanted to do it exactly as CFE does by using CFE. Since I really needed to duplicate what it does to launch the kernel. But, to a binary, there is no CFE at that point and only OF. I don't know if the OF API offers ELF loading, nor if the X1000 OF could even do it, so gave up. IIRC I ended hacking some UBoot ELF code in. Even online I didn't find clear info when looking for simple ELF loader code. I found some guy asking about where to find source for an ELF loader, only to be told not to do that because it's the OS job. There is no OS when you are running on firmware. I constantly find forums of people online, who think they can give answers by sharing there opinion, without reading or understanding a question. These people are allegedly smart.
Thanks! So I gave it a shot. It said it couldn't find firmware. Which is strange as it should know where it stores it's own files. I had to do this: qemu-system-ppc -M pegasos2 -kernel amigaboot.of -trace enable="vof*" -L /usr/share/qemu/
Amigaboot.of probably needs open and read words or similar to work for devices to boot from so in OF you can try "cd /path/to/device" and then "words" to see if it defines the necessary words and try if it works.
I would say so. It shouldn't need any forth words though and I'm not sure CFE OF handles that at all. But I know it does need to search the device tree for block devices, by opening tree items and checking them for a block type. Expanding the path and opening it. Then using seek and read methods.
I know this because I once wrote my my OF debugger on OS4. Just very basic and printing what OF client calls were made. But it was very hacky and cashed a lot because I didn't do any fancy MMU mapping so had to catch all DSI crashes and remap them. However it lead the way and I took the core code and turned it into an OF binary. Once I learnt how to compile an OF binary that worked in CFE with the quirks of the CFE memory map. Then I had a simple debugger running direct. Load in the intended target, amigaboot.of in my case. Then load and run my debugger which would patch it's own client handler in, put it in R5 and jump direct to amigaboot! Now I could see what it was up too.
Quote:
By the way if CFE can read a zip file from disk into memory you could add support for X1000 to BBoot and forget amigaboot.of.
I forget exactly what it does but it may help to solve it. CFE doesn't do zip AFAIK but it does do classic GZip. Same difference I suppose apart from the header. This would help for USB. As I see it, the only way now to boot off USB would be to load a binary blob in that contains an ELF loader binary embedded with all Kickstart modules in one file. Or, alternately, Kickstart modules packed in one file that could be loaded as a ramdisk. Then another loader booted that would find it. Either way all the modules would need joining in one file with a way to link them back from offsets and size info.
A number of years ago now I was helping a friend install Linux. In the process ub2lb had been installed. However, the Workbench was on an SFS partition, so of course it broke.
After investigating it I wasn't sure why it had insisted on installing Parthenope and I don't recall if it made a sanity check to see if system would still boot. Although it has more features and easy menu layout, an a1boot.conf would have sufficed. Of course, it would need a boot volume, if root volume was incompatible. It's for these reasons why I choose to use the traditional a1boot method when writing up the A1 specific code for my A1 Linux installer.
Parthenope caused a pain as a separate FFS volume was needed for Kicklayout. Which made software updates harder to manage because the Kickstart had to be duplicated each time by hand. I'm not sure if the trick to manage multi boot comfigs on A1 by linking Kickstart directories would help but I never tried it.
Thanks for your input. The lengthy discussion was driven by me trying to figure out how to boot OS4 off USB, which apparently was possible a decade ago, but looks impossible now.
The lengthy discussion is partly because you write too much.
Quote:
What I don't know is if the loader is doing it directly or knows how to ask CFE, since CFE obviously has an ELF loader. It would be efficient to use existing functions, but if they are not suitable or not available, then it has to be coded in.
At least on pegasos2 it does not seem to use the firmware for that and I think it may be the same on X1000. There is a loader.of version but it seems to only call to OF for memory allocation and instantiating rtas but probably parses ELF files itself. The proof that it works on QEMU pegasos2 with VOF that does not have any elf loading but AmigaOS boots. So loader.of only uses the OF client interface that has no elf loading calls and it does not use "interpret" unlike amigaboot.of which is not emulated by VOF.
Quote:
I couldn't find any evidence for an ELF loader in the EXEC loader. There are "ELF" strings in binary but they are messages.
It does not have to load ELF files, the modules are already loaded in memory so it only needs to do the relocations, maybe that's why it's not a full elf loader.
Quote:
Thanks! So I gave it a shot. It said it couldn't find firmware. Which is strange as it should know where it stores it's own files. I had to do this: qemu-system-ppc -M pegasos2 -kernel amigaboot.of -trace enable="vof*" -L /usr/share/qemu/
QEMU finds its resources when you run it from the build dir or properly install it but on Windows or if you just have the qemu-system-ppc exe copied from the build dir maybe you need to use -L.
Quote:
Okay so I got this back in return:
I get a bit more, than that. Your QEMU seems to be too old and does not have the stdin link yet. Try with current QEMU but it won't run until trying to read anything from disk as it fails before trying to allocate buffers. If you add handling of interpret alloc-mem to VOF (I may have patches for that) then it gets to trying to call the words you've found. So this does the same as your debugger did.
Quote:
I would say so. It shouldn't need any forth words though and I'm not sure CFE OF handles that at all. But I know it does need to search the device tree for block devices, by opening tree items and checking them for a block type. Expanding the path and opening it. Then using seek and read methods.
Those seek and read methods are what OF calls words and you can list on a device with the "words" word after cd-ing to the device node in the OF prompt. So if you have a device but it does not define these words or they don't work amigaboot.of won't be able to read blocks from that disk. Or maybe it does not recognise that device as a disk if it only looks for specific device names.
Quote:
I forget exactly what it does but it may help to solve it. CFE doesn't do zip AFAIK but it does do classic GZip. Same difference I suppose apart from the header.
No need to handle the zip file just load it in memory. BBoot will read and extract the zip file, the firmware just needs to load it from disk as BBoot does not have disk and filesystem handling but the firmware should already be able to do that. This works on real Pegasos2 with SmartFirmware so it should work the same on X1000 and you may just need to add the machine type and basic parameters to use on X1000 to BBoot which currently will exit with unknown machine as I don't know what's on X1000. If you can send me a device tree dump I can try to add support for it in BBoot and see if that would boot.
Quote:
Or, alternately, Kickstart modules packed in one file that could be loaded as a ramdisk. Then another loader booted that would find it.
No need to handle the zip file just load it in memory.
That no problems then, CFE can do exactly that:
CFE> help load
SUMMARY
Load an executable file into memory without executing it
USAGE
load [-options] host:filename|dev:filename
This command loads an executable file into memory, but does not
execute it. It can be used for loading data files, overlays or
other programs needed before the 'boot' command is used. By
default, 'load' will load a raw binary at virtual address 0x20000000.
OPTIONS
-elf Load the file as an ELF executable
-srec Load the file as ASCII S-records
-raw Load the file as a raw binary
-uboot Load the file as a U-Boot (PPCBoot) image
-z Load compressed file
-loader=* Specify CFE loader name
-tftp Load the file using the TFTP protocol
-fatfs Load the file from a FAT file system
-rawfs Load the file from an unformatted file system
-ext2 Load the file from an EXT2 filesystem
-fs=* Specify CFE file system name
-max=* Specify the maximum number of bytes to load (raw only)
-addr=* Specify the load address (hex) (raw only)
*** command status = 0
CFE>
Quote:
This works on real Pegasos2 with SmartFirmware so it should work the same on X1000 and you may just need to add the machine type and basic parameters to use on X1000 to BBoot which currently will exit with unknown machine as I don't know what's on X1000. If you can send me a device tree dump I can try to add support for it in BBoot and see if that would boot.
I am not a Hypex you wrote to, but i will be faster:
@kas1e OK can you try this? BBoot X1000 test I'm not sure I got the serial address right where it should print messages by default but if that does not work you can try to set /options/bboot variable as on pegasos2 to "Of V5 Ab" as mentioned in the Configuration section of the README. If it works I'll make a proper release or let me know if there's something to fix. To try and use it you'd need to do the equivalent of bboot.fth with CFE commands if CFE can't run Forth scripts but if it can bboot.fth might also work with some editing. Let me know that too so I can update the docs with needed commands for X1000. According to the load command description you posted maybe you need something like "load -raw -addr=0x600000 Kickstart.zip" which is the default address so should work without setting linux,initrd-start and linux,initrd-end variables that would be needed for other initrd address.
And checking code of bboot-0.8 i see that this one prints by prom_read/write , and after then you use direct UART (why not always prom ones ?) , and that crashes. So i at first think it's because of wrong address, but i change on correct one and it still crashes.. Then i check my bare-metal CFE hello world via UART, and find out old notes about that:
Quote:
CFE runs with MMU off. So, accessing UART (even correct one) => MCE. For hello-uart-world in bare-metal CFE example i just set CPU control register flag to bypass the cache (CFE seems to do the same around own UART access).
Probably other machines like peg2 and amigaone runs with MMU on ?
Anyway, i cookie up on uboot-0.8 sources nemo-support too, and with this fix for cache have at least that:
[RUN!]
OF interface initialized
BBoot 0.8 (unreleased)
Cannot get inird start
[EXCP]*** program exit status = 0
[CFE ]CFE>
Now need to understand how to get rid of it without forth support ..
Edited by kas1e on 2026/4/10 6:14:34 Edited by kas1e on 2026/4/10 6:36:43 Edited by kas1e on 2026/4/10 6:40:17 Edited by kas1e on 2026/4/10 7:14:39
Probably other machines like peg2 and amigaone runs with MMU on ?
At least they have a mapping for the io region. I don't know what CFE has and I could not get it to run enough on QEMU to check.
Quote:
Anyway, i cookie up on uboot-0.8 sources nemo-support too, and with this fix for cache have at least that:
Can you send me your patch to check, and include in next release?
Quote:
Cannot get inird start Now need to understand how to get rid of it without forth support ..
That's simple, in bboot.c there's no default address for if(of). Just add initrd_addr=0x600000; initrd_len=0 as done in the else branch of that if instead of goto error or set /chosen/linux,initrd-start and /chosen/linux,initrd-end properties (I don't know how can you do that in CFE. Then it should at least be able to find the zip and boot.
And checking code of bboot-0.8 i see that this one prints by prom_read/write , and after then you use direct UART (why not always prom ones ?) , and that crashes. So i at first think it's because of wrong address, but i change on correct one and it still crashes.. Then i check my bare-metal CFE hello world via UART, and find out old notes about that:
Address should be correct in the 0.9-alpha version I've sent. If serial is a problem setting /options/bboot variable to include Of instead of Os should disable serial access and output to firmware console. But if you can't set /chosen/linux,initrd* variables then it may not work. Since you're already compiling it I'll wait for your patch before making another test version as that probably works better than what I can do without testing.
Makefile thing can be fully ignored of course, i just adapt it to my local, + add x1000 define, so just you will see what exactly added/changed. Also i were having issues after i load up zip file to the memory and bboot.c's scanner were off with garbage as didnt' know size of zip file, so added this subfunc which calculate it.
+ there were some crash always when i was about to start executing kernels code, so had to add some small change in bboot.c too, but not sure if it all correct places. OF course you probabaly will simple remove x1000 ifdefs and making it all cross platform, but i add them just so you see what i add at all.
Also i were having issues after i load up zip file to the memory and bboot.c's scanner were off with garbage as didnt' know size of zip file, so added this subfunc which calculate it.
I had that already fixed in 0.9-alpha just haven't pushed that commit yet.
Quote:
+ there were some crash always when i was about to start executing kernels code, so had to add some small change in bboot.c too, but not sure if it all correct places. OF course you probabaly will simple remove x1000 ifdefs and making it all cross platform, but i add them just so you see what i add at all.
Let me have a look and try to make another test version based on this.
@kas1e Try this new test version which disables serial and falls back to the default address if no /chosen/linux,initrd* variables are found. This is built with this patch on top of latest version from git.
What is needed to properly fix serial output? Which bit in which register should be set to disable cache during access? Or should be a non-cachable TLB entry created for the IO area instead? I'd expect the firmware to do that. CFE runs enough on my QEMU patch to log something early to serial (so far it says SDRAM init failed so it does not continue further without RAM) so I may be able to check there but if you already know then I don't have to find out again.
Probably because "kickstart.zip" file name length it's too much for FAT16 ?
Need to try to cookie up usb boot stick to see how it goes with bboot and then we can find if it problem with loader or with CFE itself.
Quote:
What is needed to properly fix serial output? Which bit in which register should be set to disable cache during access?
Instead of enabling full mmu , we make data accesses cache-inhibited by setting LPCR (SPR 318) reg , and bit 62 RMI (Real Mode cache Inhibit) to value = 0x2. So i did it before like that : save reg, set rmi, do uart i/o, restore reg
Quote:
Or should be a non-cachable TLB entry created for the IO area instead?
Why not, but we need then to enable MMU (at least partially?) which looks harder imho.
Quote:
I'd expect the firmware to do that.
Probably for itself, but not for ones we run via "boot -elf .....". But dunno, maybe we can somehow cheat it all..
EDIT: tested your new alpha : yes, everything works fine now ! Cool ! :) Time to cookie up usb boot stick for x1000 and made some tests about this damn "many years happens" issue of non-bootable usb sticks on x1000.
Probably other machines like peg2 and amigaone runs with MMU on ?
No. No idea about the Peg2, but U-Boot on the A1 (SE/XE/µA1) is executed with all caches disabled, even the tiny L1 instruction and data caches (= extremely slow execution of any U-Boot code, especially loading GZip or BZip2 compressed Kickstart modules), and no MMU setup at all: Virtual = Physical address.
EDIT: tested your new alpha : yes, everything works fine now ! Cool ! :) Time to cookie up usb boot stick for x1000 and made some tests about this damn "many years happens" issue of non-bootable usb sticks on x1000.
OK thanks for testing and info on the LPCR. I've seen on QEMU CFE poking this but I did not know without documentation what it was for and did not try too hard to find in available open sources what it could be. I'll think how we could do that in BBoot to make serial work too for a proper release. Until then this alpha version should do.
For loading Kickstart.zip from USB what error do you get when BBoot is trying to parse it? Is it completely missing or truncated or otherwise corrupted? Maybe there's a length limit CFE can load from disk and the zip is too big? Or the CFE USB driver is just buggy? Does it work from a HD partition?
The lengthy discussion is partly because you write too much.
Lol. I still recall a comment on AW.net asking why my replies were so wordy. But I think matthey, if he indeed graces this forum, has the most long and informative posts.
It's not intentional, I try and keep it down, but then I keep going down a rabbit hole and I need to climb myself out of it.
Quote:
At least on pegasos2 it does not seem to use the firmware for that and I think it may be the same on X1000. There is a loader.of version but it seems to only call to OF for memory allocation and instantiating rtas but probably parses ELF files itself. The proof that it works on QEMU pegasos2 with VOF that does not have any elf loading but AmigaOS boots. So loader.of only uses the OF client interface that has no elf loading calls and it does not use "interpret" unlike amigaboot.of which is not emulated by VOF.
I've looked in other boot loader code and they implement custom ELF loaders. Also after reading through the OS1275 guide I don't see any specific mention of ELF loading. It mentions loading programs but that's too vague. By the looks of any ELF loading is done when loading from disk to memory and, unless memory can be specified as a load path, doesn't look like it can load an ELF from memory into an absolute place.
Quote:
It does not have to load ELF files, the modules are already loaded in memory so it only needs to do the relocations, maybe that's why it's not a full elf loader.
Somewhat use of confusing terms like load. Generally a load would be loading from disk, which I also would associate with disk. But here I mean in ELF image loaded from disk into memory that is then loaded/reloaded or moved to the loading location specified in the ELF binary.
I also use the term load in my X1Boot loader when data has already been loaded from disk, but it is loading it into memory, or in reality relocating it. Be in an ELF binary. Or a ramdisk. If in future I implement a custom disk loader, that will load files in from disk directly itself, I will call it reading.
So far as I know the modules, which can be a mix of binary data/text or ELF files, are loaded in by amigaboot.of and linked into a list. I didn't see any evidence it relocates them so it looked like loader.of did the job. But also, they are designed as Amiga binaries, so have no absolute location. So would need dynamic relocation in memory reserved for Kickstart.
Quote:
QEMU finds its resources when you run it from the build dir or properly install it but on Windows or if you just have the qemu-system-ppc exe copied from the build dir maybe you need to use -L.
I'm on Linux Mint 22.1. That could be the problem. Apart not being on bleeding latest Mint like most Ubuntu based distros the software is way behind.
(base) damien@damien-Lenovo-V130-15IKB ~ $ qemu-system-ppc --version
QEMU emulator version 6.1.0
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
I'm sure I downloaded or compiled a newer version for running MorphOS. So looking I've got the source to 6.1.0. Doesn't look like I compiled it but it's installed to local.
Quote:
I get a bit more, than that. Your QEMU seems to be too old and does not have the stdin link yet. Try with current QEMU but it won't run until trying to read anything from disk as it fails before trying to allocate buffers. If you add handling of interpret alloc-mem to VOF (I may have patches for that) then it gets to trying to call the words you've found. So this does the same as your debugger did.
Ok I have version 8.2.2 installed but the local one is taking over. I don't know where it's installed from. This is why I like official packages and like distro maintainers to offer latest. I install all this stuff manually for whatever reason and I can't track it. Could just delete all files I find in local. The makefile failed to uninstall. Anyway.
Quote:
Those seek and read methods are what OF calls words and you can list on a device with the "words" word after cd-ing to the device node in the OF prompt. So if you have a device but it does not define these words or they don't work amigaboot.of won't be able to read blocks from that disk. Or maybe it does not recognise that device as a disk if it only looks for specific device names.
From what I can tell it scans the OF device tree and tries to open all block devices it finds. Seem inefficient. Manually checking a whole tree instead of looking up a list of boot sources. Perhaps there is no "boot-sources" node from which childs can be looked at. But I haven't seen other boot loaders use such a brute force method.
No need to handle the zip file just load it in memory. BBoot will read and extract the zip file, the firmware just needs to load it from disk as BBoot does not have disk and filesystem handling but the firmware should already be able to do that. This works on real Pegasos2 with SmartFirmware so it should work the same on X1000 and you may just need to add the machine type and basic parameters to use on X1000 to BBoot which currently will exit with unknown machine as I don't know what's on X1000. If you can send me a device tree dump I can try to add support for it in BBoot and see if that would boot.
That's similar to what my own boot loader does. Which is more of a chain loader. My loader leverages on amigaboot.of to load in a list of files for it. Then checks each for compression or raw data. It supports XZ and GZip. Extracting kernel or ramdisk to expected location. I don't see it used but X1000 does support loading UBoot files. Though considered foreign, they are useful, because you can combine a program with data like a mini archive loaded into memory.
Quote:
That's what BBoot does. Have you looked it up at all? See:
Thanks. I actually did after replying. But I was all typed out.
Finding all block devices in the tree should not take too long as the OF device tree is probably not that large. At least this way it should find all possible boot devices. BBoot seems to work on X1000 as testing from kas1e shows so this proves you don't need an elf loader just load the modules and make the list describing them and start loader.of that will take care of relocating and starting the kernel. You need to pass the OF client interface pointer on to loader.of too. Unless you also want to replace loader.of too but I don't see why you'd want to.
For loading Kickstart.zip from USB what error do you get when BBoot is trying to parse it? Is it completely missing or truncated or otherwise corrupted? Maybe there's a length limit CFE can load from disk and the zip is too big? Or the CFE USB driver is just buggy? Does it work from a HD partition?
I was wrong, actually it works. Probably issue was that when i use my own version i play a bit with uart IO, and it exit like nothing happens, but now when i put your one to use and debug works, i can see that kickstart.zip on the usbdisk was with "Could not find file 'L/CrossDOSFileSystem'" (which is default on x1000's installation), so simple fixing it, and can load kickstart from usb and start bboot from usbdisk too.