# Using ARM64 cross-compile linux kernel for x86_64 contributed by < [Eric Lin](https://github.com/ericlinsechs) > ## Environment ### Host - OS: ubuntu 20.04 - Arch: arm64 ### Target - OS: Linux 5.10.198 - Arch: x86_64 ## Install dependency ```bash! 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 ```bash! 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 ; ``` ```bash! 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: ```bash! #!/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` ```bash 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 ```bash! 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