Built Debian 9 (4.20 kernel) for my N1 boxCross build Debian 9 for N1
This is what the box finally looks like:
123456789101112131415161718192021222324252627282930 $ ssh root@1.1.1.2Linux n1-box 4.20.0 #2 SMP PREEMPT Mon Dec 31 12:00:00 UTC 2018 aarch64 The programs included with the Debian GNU/Linux system are free software;the exact distribution terms for each program are described in theindividual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extentpermitted by applicable law.Last login: Mon Dec 31 17:03:06 2018 from 1.1.1.1[root@n1-box ~]# uname -aLinux n1-box 4.20.0 #2 SMP PREEMPT Mon Dec 31 12:00:00 UTC 2018 aarch64 GNU/Linux[root@n1-box ~]# neofetch _,met$$$$$gg. root@n1-box ,g$$$$$$$$$$$$$$$P. ----------- ,g$$P" """Y$$.". OS: Debian GNU/Linux 9 (stretch) aarch64 ,$$P' `$$$. Model: Phicomm N1',$$P ,ggs. `$$b: Kernel: 4.20.0`d$$' ,$P"' . $$$ Uptime: 3 hours, 55 minutes $$P d$' , $$P Packages: 215 $$: $$. - ,d$$' Shell: bash 4.4.12 $$; Y$b._ _,d$P' CPU: (4) @ 1.5GHz Y$$. `.`"Y$$$$P"' Memory: 67MB / 1986MB `$$b "-.__ `Y$$ ████████████████████████ `Y$$. `$$b. `Y$$b. `"Y$b._ `"""
It turns out to be quite easy..
Build the kernel
- Download the kernel source.
- Download the cross-compilation toolchain.
- Add the cross-compilation toolchain to
PATH
. - For my N1 box, I also had to add
__linux__
macro manully in arch/arm64/Makefile
(but I was changing variable KBUILD_CFLAGS
instead of cflags-y
) and move the TEXT_OFFSET higher so that u-boot won’t clash with the kernel. - Build the kernel, dtbs (I still use my customized one though) and modules by
make ARCH=arm64 CROSS_COMPILE=aarch64-elf- Image dtbs modules
. - “Install” (copy, indeed) the kernel and the modules by
make ARCH=arm64 CROSS_COMPILE=aarch64-elf- INSTALL_PATH=/path/to/kernel-install INSTALL_MOD_PATH=/path/to/modules-install install modules_install dtbs_install
. - Once the installtion finished,
vmlinuz
may be used to replace zImage
. The modules will be used later.
Debootstrap
the rootfs
Before deboostrap
ping the rootfs, we will need qemu-user-static
for emulating aarch64 environment.
debootstrap
ping an aarch64 rootfs on x86/64 would be a 2 stage process.
- We first download the packages by
sudo debootstrap --arch=arm64 --verbose --foreign stretch rootfs [mirror]
in the x86/64 world. - Then we “enter” the aarch64 world by
sudo chroot rootfs /bin/bash
, and finish the debootstrap
ping by /debootstrap/debootstrap --second-stage
.
We might also install some package (openssh-server
, net-tools
, just to name a few) / add configs we think useful at this moment.
root’s password might also be set now by executing passwd
.
To be able to connect to the box through ethernet, I also added /etc/network/interfaces.d/eth0
:
12 allow-hotplug eth0iface eth0 inet dhcp
… and enabled PermitRootLogin yes
in /etc/ssh/sshd_config
.
Create initramfs
Before we leave the aarch64 world, we would want to create an initramfs for booting.
initramfs-tools
and u-boot-tools
will be needed for this step.
First we have to copy the modules compiled in the first step to /lib/modules/[kernel-version]/
(Keep in mind we’re still in the aarch64 world, with /
being chroot
ed.
The initramfs can then be created by update-initramfs -c -k [kernel-version]
.
But what update-initramfs
creates is a cpio archive, and is not directly usable in u-boot environment. To convert it to uInitrd
, which is recognized by u-boot, we need to execute mkimage -A arm64 -T ramdisk -C none -n uInitrd -d /boot/initrd.img /boot/uInitrd
.
Boot the newly built system
Now we may leave the aarch64 world.
We still would like to keep uEnv.ini
/ *_autoscript
(which could also be mkimage
d by us if we want to) and .dtb
s in /boot
(the first partition of the USB drive in my case), but now zImage
could be replaced with our newly built vmlinuz
, and uInitrd
could be replaced by what we made in the previous step. If you’d like to, it’s also possible to use our newly built dtbs, but I kept my old one (with my patches) though. All other files might be deleted now (if you haven’t).
This is what /boot
looks like now (this list is captured after I installed my newly built system onto my EMMC, s905_autoscript
will be used instead if boot from USB drive):
123456789101112 # find /boot//boot//boot/config-4.20.0/boot/dtb/boot/dtb/meson-gxl-s905d-phicomm-n1.dtb/boot/emmc_autoscript/boot/emmc_autoscript.cmd/boot/initrd.img-4.20.0/boot/System.map-4.20.0/boot/uEnv.ini/boot/uInitrd/boot/zImage
As for the rootfs, we could simply rm -rf ./*
the old one, and rsync -a /path/to/rootfs /path/to/root-partition (which is the second partition of the USB drive in my case)
.
It’s also possible to pack these files into boot.tar.gz
and rootfs.tar.gz
individually, if you’d like to.
Having done all of these, we could now try to boot from the system we newly built (the USB drive in my case).
If all goes well, our newly built system should boot without errors.
Install to EMMC
It would be straight forward to install it to EMMC.
After booting from the USB drive with the system we newly made, we just have to remove the old files in EMMC, and copy (or preferrably, rsync -a
, to keep ownerships / permissions / …) the files in /dev/sda1
(the first partition of the USB drive) / /dev/sda2
(the second partition) into /dev/mmcblk1p1
(the first partiiton in EMMC) / /dev/mmcblk1p2
individually, and we’re done.
Install “standard” softwares
After rebooting from EMMC, we might want to install some “standard” softwares, as debootstrap
just gave us a base system to boot from.
You might want to dpkg-reconfigure locales
before installing the softwares.
tasksel install standard
does a great job here.
This could also be done in aarch64 environment emulated by qemu with /
chroot
ed.
References
- Kernel · yangxuan8282/phicomm-n1 Wiki – GitHub
- c6x: Makefile: Add -D__linux__ 546682 diffmboxseries
- ARM/RootfsFromScratch/QemuDebootstrap – Ubuntu Wiki
- Initial Ramdisk – linux-sunxi.org
- D.3. Installing Debian GNU/Linux from a Unix/Linux System
Credits to them. Really appreciated.
Cross build Debian 9 for N1
This is what the box finally looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | $ ssh root@1.1.1.2 Linux n1-box 4.20.0 #2 SMP PREEMPT Mon Dec 31 12:00:00 UTC 2018 aarch64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Mon Dec 31 17:03:06 2018 from 1.1.1.1 [root@n1-box ~]# uname -a Linux n1-box 4.20.0 #2 SMP PREEMPT Mon Dec 31 12:00:00 UTC 2018 aarch64 GNU/Linux [root@n1-box ~]# neofetch _,met$$$$$gg. root@n1-box ,g$$$$$$$$$$$$$$$P. ----------- ,g$$P" """Y$$.". OS: Debian GNU/Linux 9 (stretch) aarch64 ,$$P' `$$$. Model: Phicomm N1 ',$$P ,ggs. `$$b: Kernel: 4.20.0 `d$$' ,$P"' . $$$ Uptime: 3 hours, 55 minutes $$P d$' , $$P Packages: 215 $$: $$. - ,d$$' Shell: bash 4.4.12 $$; Y$b._ _,d$P' CPU: (4) @ 1.5GHz Y$$. `.`"Y$$$$P"' Memory: 67MB / 1986MB `$$b "-.__ `Y$$ ████████████████████████ `Y$$. `$$b. `Y$$b. `"Y$b._ `""" |
It turns out to be quite easy..
Build the kernel
- Download the kernel source.
- Download the cross-compilation toolchain.
- Add the cross-compilation toolchain to
PATH
. - For my N1 box, I also had to add
__linux__
macro manully inarch/arm64/Makefile
(but I was changing variableKBUILD_CFLAGS
instead ofcflags-y
) and move the TEXT_OFFSET higher so that u-boot won’t clash with the kernel. - Build the kernel, dtbs (I still use my customized one though) and modules by
make ARCH=arm64 CROSS_COMPILE=aarch64-elf- Image dtbs modules
. - “Install” (copy, indeed) the kernel and the modules by
make ARCH=arm64 CROSS_COMPILE=aarch64-elf- INSTALL_PATH=/path/to/kernel-install INSTALL_MOD_PATH=/path/to/modules-install install modules_install dtbs_install
. - Once the installtion finished,
vmlinuz
may be used to replacezImage
. The modules will be used later.
Debootstrap
the rootfs
Before deboostrap
ping the rootfs, we will need qemu-user-static
for emulating aarch64 environment.
debootstrap
ping an aarch64 rootfs on x86/64 would be a 2 stage process.
- We first download the packages by
sudo debootstrap --arch=arm64 --verbose --foreign stretch rootfs [mirror]
in the x86/64 world. - Then we “enter” the aarch64 world by
sudo chroot rootfs /bin/bash
, and finish thedebootstrap
ping by/debootstrap/debootstrap --second-stage
.
We might also install some package (openssh-server
, net-tools
, just to name a few) / add configs we think useful at this moment.
root’s password might also be set now by executing passwd
.
To be able to connect to the box through ethernet, I also added /etc/network/interfaces.d/eth0
:
1 2 | allow-hotplug eth0 iface eth0 inet dhcp |
… and enabled PermitRootLogin yes
in /etc/ssh/sshd_config
.
Create initramfs
Before we leave the aarch64 world, we would want to create an initramfs for booting.
initramfs-tools
and u-boot-tools
will be needed for this step.
First we have to copy the modules compiled in the first step to /lib/modules/[kernel-version]/
(Keep in mind we’re still in the aarch64 world, with /
being chroot
ed.
The initramfs can then be created by update-initramfs -c -k [kernel-version]
.
But what update-initramfs
creates is a cpio archive, and is not directly usable in u-boot environment. To convert it to uInitrd
, which is recognized by u-boot, we need to execute mkimage -A arm64 -T ramdisk -C none -n uInitrd -d /boot/initrd.img /boot/uInitrd
.
Boot the newly built system
Now we may leave the aarch64 world.
We still would like to keep uEnv.ini
/ *_autoscript
(which could also be mkimage
d by us if we want to) and .dtb
s in /boot
(the first partition of the USB drive in my case), but now zImage
could be replaced with our newly built vmlinuz
, and uInitrd
could be replaced by what we made in the previous step. If you’d like to, it’s also possible to use our newly built dtbs, but I kept my old one (with my patches) though. All other files might be deleted now (if you haven’t).
This is what /boot
looks like now (this list is captured after I installed my newly built system onto my EMMC, s905_autoscript
will be used instead if boot from USB drive):
1 2 3 4 5 6 7 8 9 10 11 12 | # find /boot/ /boot/ /boot/config-4.20.0 /boot/dtb /boot/dtb/meson-gxl-s905d-phicomm-n1.dtb /boot/emmc_autoscript /boot/emmc_autoscript.cmd /boot/initrd.img-4.20.0 /boot/System.map-4.20.0 /boot/uEnv.ini /boot/uInitrd /boot/zImage |
As for the rootfs, we could simply rm -rf ./*
the old one, and rsync -a /path/to/rootfs /path/to/root-partition (which is the second partition of the USB drive in my case)
.
It’s also possible to pack these files into boot.tar.gz
and rootfs.tar.gz
individually, if you’d like to.
Having done all of these, we could now try to boot from the system we newly built (the USB drive in my case).
If all goes well, our newly built system should boot without errors.
Install to EMMC
It would be straight forward to install it to EMMC.
After booting from the USB drive with the system we newly made, we just have to remove the old files in EMMC, and copy (or preferrably, rsync -a
, to keep ownerships / permissions / …) the files in /dev/sda1
(the first partition of the USB drive) / /dev/sda2
(the second partition) into /dev/mmcblk1p1
(the first partiiton in EMMC) / /dev/mmcblk1p2
individually, and we’re done.
Install “standard” softwares
After rebooting from EMMC, we might want to install some “standard” softwares, as debootstrap
just gave us a base system to boot from.
You might want to dpkg-reconfigure locales
before installing the softwares.
tasksel install standard
does a great job here.
This could also be done in aarch64 environment emulated by qemu with /
chroot
ed.
References
- Kernel · yangxuan8282/phicomm-n1 Wiki – GitHub
- c6x: Makefile: Add -D__linux__ 546682 diffmboxseries
- ARM/RootfsFromScratch/QemuDebootstrap – Ubuntu Wiki
- Initial Ramdisk – linux-sunxi.org
- D.3. Installing Debian GNU/Linux from a Unix/Linux System
Credits to them. Really appreciated.