Samsung Exynos 7885/Mainlining
Prepare device package
Since linux-postmarketos- package doesn't exist for 7885 family yet, you need to add linux-postmarketos-exynos7870 in depends. It will be used for kernel packaging with envkernel, because the packaging procedure is similar.
It is recommended to set deviceinfo_create_initfs_extra="true" to avoid errors related to ramdisk being too big.
Download kernel sources and additional tools
1. Clone close-to-mainline kernel source git repository
git clone https://gitlab.com/HenriDellal/linux-exynos7885.git linuxThis repository has three branches:
- exynos7870/6.15-rc1 is a copy of exynos7870 mainline kernel fork at https://gitlab.com/exynos7870-mainline/linux
- exynos7885-base includes VDavid003's patches from https://github.com/VDavid003/linux/tree/linux-6.11-rc2-7885 rebased on top of master branch
- 6.15-rc1-a10 is a WIP tree for Galaxy A10 which includes some additional patches for 7885, so you may want to take a look at that branch too
2. Download downstream kernel source, e.g. https://github.com/ResurrectionRemix-Devices/android_kernel_samsung_exynos7885
3. Clone uniLoader
git clone https://github.com/ivoszbg/uniLoader.gituniLoader porting
Example of porting can be seen in this commit: https://github.com/ivoszbg/uniLoader/commit/b92c92452bef0443077566ffab6580cf1e680fe3
It can be done in following steps:
- Copy board file from any working 7885 device (e.g. board/samsung/board-jackpotlte.c) and modify codename and framebuffer values (you need to change width and height only)
- Add device entry to board/Kconfig and change default values for following options
PAYLOAD_ENTRY - memory address where kernel is loaded
RAMDISK_ENTRY - memory address where ramdisk is loaded, can be found in downstream as linux,initrd-start property.
FRAMEBUFFER_BASE - 0x0ec000000 for all 7885 devices
FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, FRAMEBUFFER_STRIDE - self-explanatory
After that, add rule to build board file for your device in board/Makefile and create uniLoader defconfig in configs/
Creating uniLoader image
You can test if uniLoader works by repacking any working boot image with uniLoader.
# --format mkbootimg to get example of mkbootimg command
unpack_bootimg --boot_img boot.img --out unpacked-boot-img --format=mkbootimg
Use extract-dtb to get separate Image and dtb files
Now, copy files from unpacked image to uniloader blobs folder
cp unpacked-boot-img/Image uniLoader/blob/Image
cp unpacked-boot-img/dtb uniLoader/blob/dtb
cp unpacked-boot-img/ramdisk uniLoader/blob/ramdisk
# replace a105f_defconfig with yours in this command
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) a105f_defconfig
make ARCH=aarch64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
# create empty_ramdisk because ramdisk is already in uniloader binary
touch empty_ramdisk
mkbootimg --header_version 1 --kernel uniLoader --ramdisk empty_ramdisk --pagesize 0x00000800 --base 0x00000000 --kernel_offset 0x10008000 --ramdisk_offset 0x11000000 --second_offset 0x10f00000 --tags_offset 0x10000100 --out boot.img
Writing minimal dts
| Before you start, it is recommended to switch to either exynos7885 or a10 branch and then create a new branch, commit your changes afterwards so your work is not lost and some changes can be reverted | 
Example:
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include "exynos7885.dtsi"
/ {
	model = "Samsung Galaxy A10";
	compatible = "samsung,a10", "samsung,exynos7885";
	chassis-type = "handset";
	chosen {
		#address-cells = <2>;
		#size-cells = <1>;
		ranges;
		stdout-path = "fb0";
		fb0: framebuffer@ec000000 {
			compatible = "simple-framebuffer";
			reg = <0x0 0xec000000 (720 * 1520 * 4)>;
			width = <720>;
			height = <1520>;
			stride = <(720 * 4)>;
			format = "a8r8g8b8";
		};
	};
	reserved-memory {
		#address-cells = <2>;
		#size-cells = <1>;
		ranges;
		framebuffer_region@ec000000 {
			reg = <0x0 0xec000000 (720 * 1520 * 4)>;
			no-map;
		};
		abox_rmem: memory@e9400000 {
			reg = <0x0 0xe9400000 0x400000>;
		};
	};
	memory@80000000 {
		device_type = "memory";
		reg = <0x0 0x80000000 0x3da00000>,
		      <0x0 0xc0000000 0x40000000>;
	};
};
&oscclk {
	clock-frequency = <26000000>;
};
Change model and compatible for your device, as well as framebuffer width and height. &oscclk and memory nodes need to be checked against downstream.
If you have UART, you can change stdout-path to serial by changing stdout-path to &serial_2 and enable serial_2 node by adding this node override to dts
&serial_2 {
	status = "okay";
};
Now you can add a rule in arch/arm64/boot/dts/exynos/Makefile to build dts and start building kernel
Building kernel
In order to build, you need to follow envkernel guide at Compiling_kernels_with_envkernel.sh with following considerations:
- To create kernel config, run
make defconfig exynos7870.config exynos7885.config- Using uniLoader makes cmdline set by mkbootimg useless, so if you want to e.g. disable splash, add this configuration to exynos7885.config fragment or already compiled .output/.config as CONFIG_CMDLINEoption
- After kernel build is ready, use linux-postmarketos-exynos7870to package the kernel
pmbootstrap build --force --envkernel linux-postmarketos-exynos7870Creating boot image
Build device package if you didn't build it yet, then run pmbootstrap export to get initramfs.
Now, copy output files to uniLoader and create boot.img
cp linux/.output/arch/arm64/boot/Image uniLoader/blob/Image
cp linux/.output/arch/arm64/boot/dts/exynos/CHANGEME.dtb uniLoader/blob/dtb
cp /tmp/postmarketOS-export/initramfs uniLoader/blob/ramdisk
# cleaning old uniLoader binary
cd uniLoader
[ -f uniLoader ] && rm uniLoader
# next command can be skipped if already done during uniLoader testing
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) a105f_defconfig
# build uniLoader binary
make ARCH=aarch64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
Now, use mkbootimg to create boot.img (example is in uniLoader section).