Last days were full of work not only because of the Vampire related fixes and general improvements of AROS; I was also quite busy with the Emu68.
I have shown you already some results of 64-bit version of Emu68 starting successfully on real RasPi hardware and on the machine emulated in qemu. That was of course a big hack on the source code allowing me to boot *somehow* but not really to boot it the right way. I have started fixing it.
First of all, the kernel assumed that it gets loaded at a physical address of 0x00080000. This is correct on RasPi, however is just a wishful thinking on other machines. For example, the Pinebook reserves the lowest 2MB area for ATF - ARM Trusted Firmware. This area is not, and should never be accessible for untrusted software such as e.g. an operating system. Additionally, the binary file I was generating was missing a special header, unused on RasPi, but very helpful when one attempts to load and start the kernel through the uboot. The header specifies few basic things, such as the load offset within the 2MB page (this is the magic 0x00080000 value), it declares basic MMU page size used by the kernel, it says whether the kernel wants to be loaded into lowest possible memory area, or if a location anywhere on a 2MB boundary is fine. And it declares the endianness of the kernel, so that e.g. uboot could refuse loading it if the machine does not support the requested mode. The header contains also place for two opcodes allowing one to skip it using a branch opcode. Why two of them when only one would be enough? Well, this trick allows one to use part of the first of them as an identifier of regular EXE file. This way one can embed a PE header into the kernel making it a valid RasPi, uboot and EFI file at the same time. Tricky but impressive!
How about the rest of the Emu68 kernel? I have rewritten my MMU setup and kernel move routine from C to assembly. Especially the latter was a necessary step, since one of the things being moved is the stack, and as you know I have only a very little control over it when using any higher-level language. Besides, the MMU setup in assembly is now independent on the physical location of the kernel, provided it is aligned on the 2MB page boundary anywhere within RAM.
Finally I have cleaned up the sources of Emu68 a little, trying to separate generic code form platform specific one. It's not ready yet though.
How about PineBook Pro? I got it booting my code, but I cannot use the caches yet. The code loads properly, sets up MMU map, dumps the entire device tree and relocates the kernel. Display is not ready yet, but it is not of the highest priority. So far it looks like this:
[BOOT] Booting Emu68 runtime/AArch64 BigEndian
[BOOT] Boot address is 0xffffff80000800a0
[BOOT] Build ID: 4236bd740a2dda0091e3a2a2ad69e8e5ad5f4496
[BOOT] ARM stack top at 0xffffff8000080000
[BOOT] Bootstrap ends at 0xffffff8000090000
[BOOT] Kernel args (0x00000000f3dbc000)
[BOOT] Local memory pool:
[BOOT] 0xffffff8000090000 - 0xffffff8000ffffff (size=16187392)
[BOOT] Device Tree dump:
[BOOT] model=Pine64 Pinebook Pro. (50696e6536342050696e65626f6f6b2050726f00)
[BOOT] System memory: 0x0000000000200000-0x00000000f6ffffff
[BOOT] Moving kernel from 0x0000000000200000 to 0x00000000f7000000
So, back to Emu68 and AROS m68k :)