Samsung Exynos 7885/Mainlining
Prepare device package
Since a kernel package doesn't exist for the Exynos 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" in: ~/.local/var/pmbootstrap/cache_git/pmaports/device/[downstream or testing]/device-name/deviceinfo
to avoid errors related to ramdisk being too big.
When preparing the port for mainline, a new device info should be created, but for testing only kernel builds, it can be added to downstream.
This folder is created after launching pmbootstrap init.
Download kernel sources and additional tools
- Clone the close-to-mainline kernel source git repository:
$ git clone https://gitlab.com/HenriDellal/linux-exynos7885.git linux
- This repository has three branches:
exynos7870/6.15-rc1is a copy of exynos7870 mainline kernel fork at https://gitlab.com/exynos7870-mainline/linuxexynos7885-baseincludes VDavid003's patches from https://github.com/VDavid003/linux/tree/linux-6.11-rc2-7885 rebased on top of master branch6.15-rc1-a10is 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
- Download the downstream kernel source;
- Clone uniLoader:
$ git clone https://github.com/ivoszbg/uniLoader.git
uniLoader 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 (refer to the uniLoader page for how to get these values):
PAYLOAD_ENTRY- memory address where kernel is loaded;RAMDISK_ENTRY- memory address where ramdisk is loaded, can be found in downstream aslinux,initrd-startproperty (this can be also extracted from the device tree);FRAMEBUFFER_BASE-0x0ec000000for 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/
Testing if uniLoader works
This step is optional. The tools unpack_bootimg and mkbootimg are available here: https://github.com/LineageOS/android_system_tools_mkbootimg/tree/lineage-23.0
You can test if uniLoader works by repacking any working boot image with uniLoader.
To get an example of mkbootimg command, use --format mkbootimg
$ unpack_bootimg --boot_img boot.img --out unpacked-boot-img --format=mkbootimg
Use extract-dtb to get separate Image and dtb files, then copy the files from unpacked image to the 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 the ramdisk is already in the 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 |
In the folder: linux/arch/arm64/boot/dts/exynos/, create a new minimal dts file, like the one in the example below:
// 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 the dts:
&serial_2 {
status = "okay";
};
Now you can add a rule in arch/arm64/boot/dts/exynos/Makefile to build the dts and start building the kernel.
Building kernel
To create the kernel config, run
$ make defconfig exynos7870.config exynos7885.config
Using uniLoader makes the 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_CMDLINE option. After the kernel build is ready, package the kernel:
$ pmbootstrap build --force --envkernel linux-postmarketos-exynos7870
Creating boot image
To build uniLoader you need to have gcc-aarch64-linux-gnu installed (check your distro for the exact name).
Build the device package if you haven't built it yet, then run pmbootstrap export to get the 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 # dtb is a file, not a folder
$ cp /tmp/postmarketOS-export/initramfs uniLoader/blob/ramdisk
Clean the old uniLoader binary
$ cd uniLoader
$ [ -f uniLoader ] && rm uniLoader
For the next steps, make sure to deactivate envkernel:
The next command can be skipped if already done during uniLoader testing.
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) a105f_defconfig
Build the uniLoader binary
$ make ARCH=aarch64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
Replace a105f_defconfig with the defconfig you have created, if necessary.
Now, use mkbootimg to create boot.img (example is in the uniLoader section).