Try   HackMD

Using ARM64 cross-compile linux kernel for x86_64

contributed by < Eric Lin >

Environment

Host

  • OS: ubuntu 20.04
  • Arch: arm64

Target

  • OS: Linux 5.10.198
  • Arch: x86_64

Install dependency

sudo apt-get install libelf-dev bison flex make gcc-8 gcc-x86-64-linux-gnu qemu qemu-system-x86-64 libncurses5-dev build-essential

Get Linix Kernel Source Code

Download archive

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/snapshot/linux-5.10.198.tar.gz

gzip -d linux-5.10.198.tar.gz
tar -xf linux-5.10.198.tar

Get Busybox for building minimal file system

Download

https://busybox.net/downloads/busybox-1.32.0.tar.bz2

Config settings

sudo ln -s /usr/x86_64-linux-gnu/lib/libmvec.a /usr/lib/x86_64-linux-gnu/libmvec.a ; \
sudo ln -s /usr/x86_64-linux-gnu/lib/libm-2.31.a /usr/lib/x86_64-linux-gnu/libm-2.31.a ;
export ARCH=x86 ; \
export CROSS_COMPILE=x86_64-linux-gnu- ; \
make menuconfig

Enable building static binary

Settings --->
    Build Options --->
        [*] Build static binary (no shared libs)
make install

A folder called _install will be created under busybox root folder, copy it to linux-5.10.198

cd linux-5.10.198/_install
mkdir etc ; \
mkdir dev ; \
mkdir mnt ; \
mkdir -p etc/init.d ; \
cd etc/init.d ; \
vim rcS

Copy the following context to rcS:

#!/bin/sh
mkdir –p /proc
mkdir –p /tmp
mkdir -p /sys
mkdir –p /mnt
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev –s
mknod /dev/tty2 c 4 2
mknod /dev/tty3 c 4 3
mknod /dev/tty4 c 4 4

Change rcS permissions

chmod 777 rcS

Go to _install/etc

vi fstab

Copy following context to fstab:

proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0

Under the same path (_install/etc):

vi initta

Copy following context to inittab:

::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a –r

Go to _install/dev

sudo mknod console c 5 1; \
sudo mknod null c 1 3;

Create initramfs file

Pack everything up as a ramdisk image. Make sure you’re inside _install directory before running the following command:

find -print0 | cpio -0oH newc | gzip -9 > ~/initramfs_x86.cpio.gz

There should be a new file initramfs_x86.cpio.gz in your home directory.

Compile Linux Kernel

Edit defconfig

vi ./arch/x86/configs/x86_64_defconfig

Add the following contexts in it:

CONFIG_CMDLINE=""
CONFIG_INITRAMFS_SOURCE="_install"
CONFIG_VMSPLIT_3G=y
CONFIG_HIGHMEM=y

Creat a specific directory for building

mkdir build; \
sudo cp -r ./_install ./build
export KBUILD_OUTPUT=./build; \
export ARCH=x86; \
export CROSS_COMPILE=x86_64-linux-gnu-; \
make x86_64_defconfig
make menuconfig

Build Linux Kernel

export KBUILD_OUTPUT=./build; \
make bzImage -j4 ARCH=x86 CROSS_COMPILE=x86_64-linux-gnu-;

Run Linux kernel on QEMU

qemu-system-x86_64 -nographic -kernel ./linux-5.10.198/build/arch/x86_64/boot/bzImage -append "rdinit=/linuxrc nokaslr console=ttyS0" -m 256 -initrd ./initramfs_x86.cpio.gz

Troubleshooting

(.text+0x0): multiple definition of yylloc; dtc-lexer.lex.o (symbol from plugin):(.text+0x0): first defined here`

https://review.lineageos.org/c/LineageOS/android_kernel_oneplus_sm8150/+/273023/1/scripts/dtc/dtc-lexer.lex.c_shipped

scripts/selinux/mdp/mdp.c:49: ../security/selinux/include/classmap.h:251:2: error: #error New address family defined, please update secclass_map.

https://blog.csdn.net/zhangpengfei991023/article/details/109672491

fatal error: openssl/bio.h: No such file or directory

https://stackoverflow.com/questions/59016911/fatal-error-openssl-bio-h-no-such-file-or-directory

error: ‘-mindirect-branch’ and ‘-fcf-protection’ are not compatible

  • change gcc version to gcc-8