The raspberry PI OS is arm32-bit by default, but from raspberry PI 3 it will support ARM64-bit, so we have to compile it ourselves.

There are actually a lot of 64 bit kernel compilations for raspberry PI 3B on the Internet. I tried them all, but none of them would boot. It’s not that they’re written incorrectly, but they just don’t seem to work for me. Therefore, the following steps do not guarantee that everyone can succeed, because everyone’s situation is different, caused by different problems, so problems can only rely on their own Baidu or Google.

There are a lot of notes that just compile the kernel to 64-bit, but the file system is still officially 32-bit and not really 64-bit, so I’ll build the root file system to 64-bit as well.

Notes in the record of the time inevitably there are omissions, if any steps are not quite right, welcome to leave a message, timely modification.

If you want to use a 64-bit system without the hassle, you can download an open source 64-bit system: Debian-Pi-AARCH64, which is third-party and not officially provided by Raspberry Pi.

Compile environment

Virtual environment Linux installed by VM virtual machine, how to install a search on the Internet, follow the steps to install.

  • Ubuntu 163.com

Compiler: Ubuntu 18.04-desktop-AMd64

If you want to build a 64-bit kernel, you can only build it on a 64-bit machine.

Cross compiler

Generating 64-bit kernels via cross-compilers

  • Cross compiler Wiki

Definition: A Cross compiler is a compiler that produces executables for one system platform and for another

My understanding of this sentence is vividly explained:

  • Ubuntu 18.04-AMD64: Custom Garment Factory (one system platform)

  • Cross-compiler: machine for making clothes (compiler)

  • Clothing material (executable file source)

  • Raspberry PI 4B: People (Another platform)

With the above, NOW I want to make a garment for people, so I need to find a factory that specializes in making clothes for people. After giving the garment materials to the factory, the clothes made by the machine can be worn by people.

Everyone’s understanding is not the same, as long as you remember the definition of the above professional good, how to understand their own to it.

Compiling the kernel

As defined above, we need to get those four before we can make them; Ubuntu must be installed first; Raspberry PI, of course.

You can use a common user. Do not use the root user to execute the command. When the root user is needed, switch to the root user to execute the command

Preparation before compiling the kernel

  • Get the cross-compiler and configure it

Linaro Toolchain

Download gcc-linaro-7.4.1-2019.02-x86_64_aARCH64-linux-gnu.tar.xz from the link above, possibly updated, date and version will change. Or use the command to download

$ sudo wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aar ch64-linux-gnu.tar.xzCopy the code

Create a working directory from which all subsequent operations will be performed

$ mkdir ~/build && cd ~/build
$ sudo apt-get install lrzsz
Upload and unzip the downloaded files$rz $sudo tar -xvf gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -c /usr/src. $cd/usr/src/&&sudo mv gcc-linaro-7.4.1-2019.02-x86_64_aARCH64-linux-gnu aarch64-linux-gnu $sudo vi /etc/profile or $ sudo vi ~/.bashrc# Add the following at the end
export ARCH_HOME=/usr/src/aarch64-linux-gnu
export PATH=$PATH:$ARCH_HOME/bin
$ source /etc/profile
or
$ source ~/.bashrc
Copy the code

Note: For common users, you need to switch to root and configure the configuration again. Common users also need to configure the configuration

  • Get the Raspberry Kernel source code

Raspberry now defaults to version 4.19, but later versions are available, depending on which version you want to download. Github is extremely slow to download. I migrated Raspberry Linux to the national code cloud, which made downloading faster. The difference is that the official update will not be updated to the repository of my code cloud. To obtain the latest code, you can first fork the official code to your own Github, then migrate to your own code cloud, and replace the link with your own. The following command can be selected to download

$ cd ~/build
$ sudo apt-get install git
# official Github address
$ git clone- the depth = 1 - branch rpi - 4.19 y https://github.com/raspberrypi/linux# address of the code cloud
$ git clone- the depth = 1 - branch rpi - 4.19 y https://gitee.com/nzwxl/linuxCopy the code
  • Install the dependencies required by the compile environment
$ sudo apt-get install git bison flex libssl-dev zip libncurses-dev make
Copy the code

The libncurses-dev dependency is supported behind Menuconfig

The kernel is compiled

If the source file is not called Linux, you can change it to Linux or whatever you want
$ cd linux
You can run this command before compiling to ensure a clean environment. If there is an error in compiling or operation, you can run this command to restart.
$ make distclean
Config, ARCH will be configured as arm64, if not, it will default to x86, CROSS_COMPILE specifies the compiler
# bcm2711_defconfig in the arch/arm64 / configs/bcm2711_defconfig, it will according to the Makefile themselves to find the file
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig
If there is nothing to be clipped, press ESC twice to exit, mainly because I don't know much about it, I will remember it later
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
-j5 means to compile the kernel with multiple processors at the same time. The maximum number of cores in the CPU is 1.5, which can be modified by yourself
$ make -j5 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
Copy the code

Arch /arm64/boot will generate the Image binary kernel file in the arch/arm64/boot directory. If the 32 kernel is made, the zImage binary kernel will be generated in ARCH/ARM /boot. The original kernel file vmlimux is also generated in the Linux directory.

Vmlinunx: the original Linux kernel file.

ZImage: loadable binary kernel file with compressed and debugging information removed.

Image: Loadable binary kernel file without compression.

More information about kernel files is available at Google.

Install the kernel modules

This modules is used in rootfs. Install it in the ~/build working directory and replace [user] with your own user name

$ cd ~/build/linux
Switch to user root
$ su
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/home/[user]/build/ modules_install
$ su [user]
Copy the code

Tree plum send boot file

Because raspberry PI’s official bootloader is not open source, but it provides all the things in the boot directory that can be used. Similarly, I migrated to the code cloud due to slow downloading due to the Internet speed.

$ cd ~/build
$ git clone --depth=1 https://github.com/raspberrypi/firmware/
or
$ git clone --depth=1 https://gitee.com/nzwxl/firmware/
# firmware/boot is the required file
$ ls firmware/boot
Copy the code

Make rootFS for ARM64 architecture

How to make ARM64 rootfs I have recorded in another note, you can continue to follow the order of the note, when the rootFS is finished, go back to this note and connect with the next step

  • Debootstrap makes an ARM64-bit root file system

Kernel, uboot, and Rootfs are packed into the image

Creating an Image File

  • Create a root file system image file with a size of 1000M and partition the image file

The burn shows that 1000 MEgabytes are 90% used, so if you have a lot of work to do, or upload something, it’s best to create a larger image file

$ cd ~/build
$ fallocate -l 1000M rootfs.img
# partition$fdisk rootfs.img a. Enter o. This will clear any partitions on the image file. B. Type p to list partitions. There should be no partitions. C. Type n, then p for primary, 1 for the first partition on the drive, press ENTER to accept the default first sector, and then type + 100M for the last sector. D. Type t, then C sets the first partition to type W95 FAT32 (LBA). E. Type n, then P for the primary drive, 2 for the second partition on the drive, and press ENTER twice to accept the default first and last sectors. F. Write to the partition table and type w to exit.You can run the command to view the partition Settings
$ fdisk -l rootfs.img
Copy the code
  • Mount the image to loopX using kpartx

On Linux, if the image file (.img) contains partition tables, mount cannot be used to mount them; You can mount it using Kpartx; X is the number you display, Y is also the number, everyone may not be the same, the first loopXpY is the first partition after the above partition, and the second is the second partition

$ sudo apt-get install kpartx
$ sudo kpartx -av rootfs.img
add map loopXpY (254:0): 0 204800 linear 7:0 2048
add map loopXpY (254:1): 0 407552 linear 7:0 206848
These two devices can be seen in the /dev/mapper/ directory
$ ls /dev/mapper/
Copy the code
  • Format the partition and specify the partition LABEL name
$ sudo mkfs.vfat -n BOOT /dev/mapper/loop5p1
$ sudo mkfs.ext4 -F -L ROOTFS -O "^has_journal" /dev/mapper/loop5p2
The -n parameter in the first command is to specify the LABEL. You can view the parameter details in the man mkfs.vfat command
Man mkfs.ext4 -l specifies the LABEL to be used by man mkfs.ext4
Copy the code
  • Create a mount point and mount it

After formatting the partition, we can now mount the loopXpY device to the file

$ sudo mkdir {/mnt/loopXp1,/mnt/loopXp2}
$ sudo mount /dev/mapper/loop5p1 /mnt/loopXp1
$ sudo mount /dev/mapper/loop5p2 /mnt/loopXp2
Copy the code

Copy the files required for kernel and boot

$ cd ~/build
# copy the files required by boot
$ sudo cp -r firmware/boot/* /mnt/loopXp1/
$ sudo cp linux/arch/arm64/boot/dts/broadcom/*.dtb /mnt/loopXp1
$ sudo cp linux/arch/arm64/boot/dts/overlays/*.dtb* /mnt/loopXp1/overlays/
$ sudo cp linux/arch/arm64/boot/dts/overlays/README /mnt/loopXp1/overlays/
# copy kernel
$ sudo cp linux/arch/arm64/boot/Image /mnt/loopXp1/kernel8.img
Copy the code

Write cmdline.txt and config.txt

Reference: RPi_cmdline. TXT

Write cmdline. TXT

# Add content and save exit
$ sudo vim /mnt/loopXp1/cmdline.txt
console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait fsck.repair=yes
Copy the code
  • Console =serial0,115200: Indicates the device used by the serial port and the transmission rate
  • Console =tty1: Console output uses the TTy1 device
  • Root =/dev/mmcblk0p2: Set partition 2 of the memory card to the root partition
  • Rootfstype =ext4: The root partition type f2fs should be changed to F2fs
  • Rw: writable mount and partition
  • Rootwait: Wait for the kernel to identify the root partition device before mounting it
  • Sck. repair=yes: Automatically checks and repairs file system errors during startup

Write config. TXT

# Add content and save exit
$ sudo vim /mnt/loopXp1/config.txt

Read the kernel in 64-bit
arm_64bit=1
If you want to boot in ARMV8 mode, set this option
arm_control=0x200
The name of the kernel
kernel=kernel8.img

The u-boot is several seconds late in booting the kernel
boot_delay=1

# Turn off Bluetooth
# See /boot/overlays/README for all available options
dtoverlay=disable-bt
Enable audio snd_bcm2835
dtparam=audio=on
Copy the code

Synchronize rootfs to mirror the second partition

$ sudo apt-get install rsync
$ cd ~/build/linux-rootfs/
# start sync
$ sudo rsync -HPavz -q ./ /mnt/loopXp2
Copy the code

Rsync Parameter description: Run the rsync command

Write the fstab file

If you want the boot directory in the first partition to display files after the system starts, add the following content to /etc/fstab:

$ sudo vim /mnt/loopXp2/etc/fstab
<file system>   <mount point>    <type>   <options>  <dump> <pass>
LABEL=BOOT      /boot            vfat     defaults   0      1
Copy the code
  • File system: Can be the actual partition name or the volume label of the actual partition. The volume label name has been specified above
  • Mount point: indicates the mount point
  • Type: file system type for this partition. The type of vFAT bit FAT32 should be
  • Options: indicates mounting options, used to set mounting parameters. Common parameters are as follows
    • defaults: rw, suid, dev, exec, auto, nouser, and async.
    • Auto: the system automatically mounts the file. Fstab uses this option by default
    • Noauto Startup does not automatically mount
    • Only superusers can mount nouser
    • Ro Mount as read-only
    • Rw mount with read and write permission
    • User Any user can mount it
  • Dump: yes Backup. If the value is set to 1, the dump backup program is allowed to back up data. If the value is set to 0, the backup operation is ignored.
  • Pass: indicates the FSCK disk check setting. The value is an order. When the value is 0, it is never checked; The/root partition is always 1. For other partitions, start from 2. The smaller the number, the better. If the two partitions have the same number, the better.

Installing a Kernel Module

Since modules were installed in the working directory build when compiling the kernel, you can directly copy them to the second partition. If you are not sure, you can use the command to install modules to the second partition and change the path.

$ cd ~/build
$ sudo cp -r lib/modules/ /mnt/loopXp2/lib/
Copy the code

Unmount and burn IMG files to SD card

$ cd ~/build
$ sync
$ sudo umount /mnt/loopXp1/
$ sudo umount /mnt/loopXp2/
$ sudo kpartx -dv rootfs.img
Copy the code

Download rootfs.img to Windowns and burn it to SD card. The method of burning SD card can be refer to:

  • Raspberry Pi 4 Model B No display Log in to the terminal using SSH

Start Raspberry and run the command to check that the kernel version is 64-bit

reference

  • [1]Raspberry kernel building

  • [2]Raspberry Pi 3 64-bit kernel

  • [3] Build a custom raspberry PI kernel

  • [4] Starting from the kernel, we build a 64-bit system for Treeplum 3