The current drivers/framework.c is useless, as REGISTER_DRIVER() is a macro
that just directly calls the driver probe function. Every board file has to
reference each driver's probe function by name. This was just done to make room
for proper driver probing in the future, where we are now, so implement that.
Make drivers self-register at link time by emitting a struct driver into a
.uniloader_drivers section via DRIVER_REGISTER(). The linker brackets
the section with __drivers_start / __drivers_end symbols.
Boards describe their hardware as a static struct with the format
{ driver_name, plat_data, label }. Remove the drivers_init hook from
struct board_ops as it's no longer necessary.
The drivers probe will now be placed between early_init and splash.
The framework looks up each device's driver_name up in the
linker section and calls probe(plat_data). A failed probe is logged.
Do --whole-archive as well to convince the linker to not drop the drivers
in archived .o files that aren't called outside the archive.
Adopt all boards to use the framework.
All of the changes in this commit are co-dependent on each other, as we're
doing a large change to the ABI.
get_font_scale_factor() unconditionally dereferences fb_info and debug.c's
fb_output() calls get_font_scale_factor() on each printk call, even before
we have simplefb registered. As __simplefb_raw_print has a check if we're
past simplefb probe (fb_info is filled), do the same for get_font_scale_factor()
and return 1 (not scaled) if the struct is not filled.
The value 5 appeared bare in two places: simplefb.c (when text wraps
past the bottom of the screen) and debug.c (initial y position for
the printk overlay). Replace both with FB_TEXT_TOP_PADDING defined
once in simplefb.h.
The toolchain emits several sections that have no meaning for a flat
binary bootloader:
.eh_frame DWARF unwind tables (we never unwind)
.note.gnu.property BTI/PAC ELF markers (lost at objcopy)
.note.gnu.build-id debug identity (lost at objcopy)
.comment compiler version string
.ARM.attributes ABI metadata
Gcc emits roughly 7-8 KB of .eh_frame by default for a build of this
size; the others are smaller but equally pointless. Just drop all of
them in the linker scripts.
Net effect on dreamlte_defconfig w/ empty embedded blobs:
61960 -> ~54000 bytes. Stonks.
ALIGN(4) is left over from 32-bit linker script templates. On
aarch64 the natural pointer/long alignment is 8, and these sections
usually contain 64-bit constants (pointer tables, 64-bit literals). The
4-byte alignment was harmless because the linker happens to align
individual symbols anyway, but let's just align it properly for the
sake of correctness. For BSS also ensure we have extra padding before
the end of the section.
Several boards call readl()/writel() or use uint32_t but do not include
<string.h> (which is where unic declares these). They build today only
because <drivers/framework.h> pulls <string.h> in.
The framework header has no business pulling string.h; Include it properly
in case we remove framework.h later on (spoiler lol).
The current header implementation is incomplete: the text_offset and
image_size slots are overlaid with internal relocation metadata
(_rel_stack_base / _rel_stack_size), and the flags field is zero,
which makes some bootloaders unhappy. Fill up the the missing props and
while at it, stub out the image header into a header file to avoid duplicating.
image_size is computed in the linker script as _stack_end - _start
so the early stack page is included in the runtime memory footprint
advertised to the previous-stage bootloader.
Patch inspired by work from @Trijal08 and cleaned up to not account for
ELF PiE.
This is the correct format considering the BGRA write format was wrong before, leading it to actually use ABGR.
Signed-off-by: Umer Uddin <umer.uddin@mentallysanemainliners.org>
This is the correct format considering the BGRA write format was wrong before, leading it to actually use ABGR.
Signed-off-by: Umer Uddin <umer.uddin@mentallysanemainliners.org>
Xperia 1 VI is a flagship phone manufactured by Sony, based on the
Qualcomm Snapdragon 8 Gen 3 Mobile Platform.
Add support for this board.
NOTE: This board is new, and as such, it requires some ugly hax and
a fallback boot method to boot any sort of [u-boot/uniLoader/mainline]
In short:
- build:
- ARCH=aarch64 CROSS_COMPILE=aarch64-linux-gnu- make -j32
- cat uniLoader.gz dummy.dtb > uni.dtb
- mkbootimg --kernel uni.dtb --ramdisk <some ramdisk (required)> \
--pagesize 4096 --base 0x0 --kernel_offset 0x8000 \
--ramdisk_offset 0x1000000 --tags_offset 0x100 \
--dtb_offset 0x1f00000 --header_version 0 --os_version 16.0.0 \
--os_patch_level 2026-04 -o boot.img
(yes, all properties are required.)
- prepare device:
- boot to fastboot mode (volume up and plug in USB)
- fastboot erase dtbo erase vendor_boot
- flash:
- fastboot flash boot boot.img continue
Where:
- dummy.dtb is a skeleton.dtsi with a reserved memory node called
splash_region as a child of the chosen node.
Signed-off-by: Igor Belwon <igor.belwon@mentallysanemainliners.org>
Pass the address of the address of the DTB to patch_dtb in boot.c, rather than just the address to the DTB.
This allows the modified DTB address to overwrite the address of the original DTB, fixing a bug where
the ramdisk address was not being passed to the kernel via the DTB successfully.
Due to divmod performing division by subtracting in a linear loop,
it's *really* slow. When performing division with larger numbers (like
32-bit addresses), it goes thru massive amounts of iterations and causes
a stall-like appearance.
Instead, let the compiler handle it by using cpu instructions like
UDIV/MSUB for armv8.
Fixes#86.
Add basic support for Motorola tundra, usable to boot mainline Linux.
UniLoader has to be packaged with mkbootimg (header_version 3), as it
acts as a wrapper for the kernel image and tree.
This commit adds support for the PSVita 1xxx/2xxx variants, which have:
- 4x Cortex A9
- OLED/LCD display (both types get init. by libbaremetal before)
- 512MB RAM (ew)
- Some PowerVR custom GPU (ew)
* Needs to be unlocked via an exploit
* mkbootimg --kernel uniLoader.lz4 --header_version 4 --out boot.img
* Has very slow fastboot (usb 1.1 speeds slow), so flashing via the
SoC flash mode or fastbootd is recommended
* fastboot flash boot boot.img reboot
Signed-off-by: Igor Belwon <igor.belwon@mentallysanemainliners.org>
Tests all supposed-to-be-working devices (read - has a defconfig)
for compilation errors. No arm devices have defconfigs so it
hardcodes the arm64 compiler for now.
gzip: qemu shall use uniLoader.o as the kernel which also enables symbol maps and other cool stuff.
so, the gzip-compressed uniLoader image is useless and can slow down the compile process
libfdt: temporary. it doesn't seem to pick up the fdt that is passed when booting raw kernel
Signed-off-by: Igor Belwon <igor.belwon@mentallysanemainliners.org>
HiSilicon bootloader copies the ramdisk itself, and marks
its memory region as protected, so we can't memcpy on it.
Even more: we also can NOT include the ramdisk into uniLoader
for it, because the kernel partition is too small.
The easiest workaround for that is just using an empty
blob/ramdisk, so it won't be copied. But it breaks
libfdt, as it doesn't know the actual ramdisk size.
The C runtime requires that uninitialized global variables are zero.
In a bare-metal environment, memory contents are undefined at startup
and the BSS section is not automatically cleared, so we must zero out
this entire section ourselves.
Without this, static variables contain garbage values, leading to
unpredictable behavior. For example, the simplefb driver uses a static
variable to track the current print position, which resulted in text
being drawn at random locations on the screen.