# 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