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 linux
This 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.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
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/
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_CMDLINE
option - After kernel build is ready, use
linux-postmarketos-exynos7870
to package the kernel
pmbootstrap build --force --envkernel linux-postmarketos-exynos7870
Creating 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).