Ubuntu、Debian之類的不同的發(fā)行版,其實(shí)就是不同的rootfs
。Debian系的發(fā)行版有個工具叫debootstrap
,可以從源
那里下載最小的根文件系統(tǒng)。Arch相應(yīng)的工具則是packstrap
。
下完根文件系統(tǒng)之后chroot
進(jìn)去進(jìn)行相應(yīng)的配置,為了chroot到一個ARM的rootfs,我們需要用qemu-arm-static
。進(jìn)去之后apt-get
你想要安裝的東西。配完了之后燒進(jìn)sd卡,通過內(nèi)核參數(shù)root=xxxx
告訴內(nèi)核要掛載哪個rootfs,即可啟動了。
要制作一個叉叉派的鏡像都是這樣的套路:bootstrap一個最小系統(tǒng),安裝內(nèi)核模塊,安裝必要的應(yīng)用程序,然后安裝不同的桌面環(huán)境,最后打包。于是就制作出各種水果派的n多鏡像,像Ubuntu core、Ubuntu mate、xubuntu、lubuntu、Debian,Arch等等,應(yīng)有盡有。。
然而這些大型發(fā)行版的“最小系統(tǒng)”都相當(dāng)?shù)拇螅瑤装僬椎臉幼?,而我們的EBAZ4205只有128M的nand flash,所以只好從sd卡啟動才能維持得了生活。
我們先在一臺Ubuntu主機(jī)上安裝qemu-user-static
、debootstrap
,然后繼續(xù)。后文一些命令如果沒有安裝,隨時apt-get一下。
我們dd
一個3.7G的空白鏡像,這樣可以燒錄進(jìn)一個標(biāo)明4G的SD卡。姑且叫它ubuntu1804.img
吧:
dd if=/dev/zero of=ubuntu1804.img bs=1M count=3500
然后我們將它掛載為loop
設(shè)備:
sudo losetup -f --show ubuntu1804.img
如果你之前沒有掛過別的回環(huán)設(shè)備的話,一般它會掛在/dev/loop0
。
然后我們給它分區(qū)。可以用圖形界面的工具如gparted
,也可以用命令行工具如parted
、fdisk
等。比方說我們用fdisk。
sudo fdisk /dev/loop0
用n
來添加新分區(qū)。順著它的指示走下去即可。
文件系統(tǒng) | 大小 | |
---|---|---|
啟動分區(qū) | vfat | 256MB就夠了 |
文件系統(tǒng) | ext4 | 3.2G |
同步這些分區(qū)。這樣會在/dev/mapper/
下面生成對應(yīng)的節(jié)點(diǎn):
sudo kpartx -av /dev/loop0
格式化它們:
sudo mkfs.vfat /dev/mapper/loop0p1sudo mkfs.ext4 /dev/mapper/loop0p2
掛載它們:
mkdir boot rootfssudo mount /dev/mapper/loop0p1 bootsudo mount /dev/mapper/loop0p2 rootfs
我們要修改uboot環(huán)境變量,讓它從SD卡里面讀取內(nèi)核和設(shè)備樹。不過zc702工程的默認(rèn)啟動設(shè)備就是sd卡,我們只需要留意sdboot
這個環(huán)境變量以及各種地址就好了:
- "kernel_load_address=0x2080000\0" + "kernel_load_address=0x8000\0" ...- "devicetree_image=devicetree.dtb\0" - "devicetree_load_address=0x2000000\0" + "devicetree_image=zynq-zc702.dtb\0" + "devicetree_load_address=0x0\0" ... "sdboot=if mmcinfo; then " - "run uenvboot; " "echo Copying Linux from SD to RAM... && " "load mmc 0 ${kernel_load_address} ${kernel_image} && " "load mmc 0 ${devicetree_load_address} ${devicetree_image} && " - "load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && " - "bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " + "bootm ${kernel_load_address} - ${devicetree_load_address}; " "fi\0"
我們還要修改設(shè)備樹,添加啟動參數(shù),讓內(nèi)核掛載Ubuntu文件系統(tǒng)。其中rootwait
這個參數(shù)表示需要等待根文件系統(tǒng)的掛載,不然內(nèi)核啟動很快,一看還沒有掛上文件系統(tǒng)就會kernel panic了:
chosen {- bootargs = "";+ bootargs = "root=/dev/mmcblk0p2 rw rootwait"; stdout-path = "serial0:115200n8"; };
將BOOT.bin
、uImage
、zynq-zc702.dtb
放進(jìn)啟動分區(qū)。
接著就可以愉快地debootstrap了。不過可惜的是,國內(nèi)Ubuntu源都沒有同步armhf
的port,只有x86的,所以只能用官方源了。
sudo debootstrap --arch=armhf --foreign bionic ./rootfs
但是國內(nèi)的Debian就同步了arm的分支,比方說清華源:
sudo debootstrap --arch=armhf --foreign stretch ./rootfs https://mirrors.tuna.tsinghua.edu.cn/debian/
等一段時間下完基本系統(tǒng),然后拷貝qemu
進(jìn)去:
sudo cp -av /usr/bin/qemu-arm-static rootfs/usr/bin/
還需要拷貝resolv.conf
,以便聯(lián)網(wǎng):
sudo cp /run/systemd/resolve/stub-resolv.conf rootfs/etc/resolv.conf
然后chroot
進(jìn)去:
sudo chroot ./rootfs
在里面進(jìn)行second-stage
:
# chroot環(huán)境下面:export LANG=C/debootstrap/debootstrap --second-stage
安裝完成之后,補(bǔ)全/etc/apt/source.list
:
deb http://ports.ubuntu.com/ubuntu-ports bionic main restricted universe multiversedeb http://ports.ubuntu.com/ubuntu-ports bionic-security main restricted universe multiversedeb http://ports.ubuntu.com/ubuntu-ports bionic-updates main restricted universe multiversedeb http://ports.ubuntu.com/ubuntu-ports bionic-proposed main restricted universe multiversedeb http://ports.ubuntu.com/ubuntu-ports bionic-backports main restricted universe multiversedeb-src http://ports.ubuntu.com/ubuntu-ports bionic main restricted universe multiversedeb-src http://ports.ubuntu.com/ubuntu-ports bionic-security main restricted universe multiversedeb-src http://ports.ubuntu.com/ubuntu-ports bionic-updates main restricted universe multiversedeb-src http://ports.ubuntu.com/ubuntu-ports bionic-proposed main restricted universe multiversedeb-src http://ports.ubuntu.com/ubuntu-ports bionic-backports main restricted universe multiverse
然后裝一些基本的軟件:
apt-get updateapt-get install sudo ifupdown net-tools ethtool udev wireless-tools iputils-ping resolvconf wget apt-utils wpasupplicant vim git gcc build-essential openssh-server
新建用戶,就叫它ubuntu吧,密碼也是ubuntu:
useradd -G sudo -m -s /bin/bash ubuntuecho ubuntu:ubuntu | chpasswd
更改root密碼:
passwd root
設(shè)置主機(jī)名為armhf
:
echo armhf > /etc/hostname
設(shè)置網(wǎng)絡(luò),改/etc/network/interfaces
文件:
auto loiface lo inet loopbackallow-hotplug eth0iface eth0 inet dhcp
終端配色:將/home/ubuntu/.bashrc
里面的force_color_prompt=yes
注釋刪掉即可。
設(shè)置默認(rèn)掛載目錄:改/etc/fstab
,將啟動分區(qū)掛載到/boot
目錄上:
/dev/mmcblk0p1 /boot vfat defaults 0 0
如果沒什么別的想要配置的話,就可以exit
退出了。
注意,因?yàn)閄ilinx的內(nèi)核配置默認(rèn)將所有驅(qū)動都直接編譯進(jìn)內(nèi)核,所以不需要將模塊安裝到文件系統(tǒng)中,就一個放在啟動分區(qū)的內(nèi)核就夠了。
我們將鏡像文件卸載:
sudo umount ./bootsudo umount ./rootfssudo kpartx -d /dev/loop0sudo losetup -d /dev/loop0
我們看到這個鏡像文件有3.7G那么大,但是世界上它占用的磁盤空間沒那么大,它是個sparse file
,將它打包壓縮之后就沒看上去那么大了。可以用ls -s
來看到它實(shí)際上多大:
$ ls -sh ubuntu1804.img 1.2G ubuntu1804.img
現(xiàn)在我們直接將這個文件dd到一張SD卡里面:
dd if=ubuntu1804.img of=/dev/sd某
如果你的SD卡不只有4G,那么可以通過像gparted
、parted
、fdisk
等等的分區(qū)工具將第二個分區(qū)拉大,然后resize2fs
重新設(shè)置分區(qū)大小。gparted一般會自動幫你resize2fs。
可以從串口看到完整的啟動過程:uboot、kernel、systemd,然后是login:
U-Boot 2018.01 (Apr 24 2019 - 00:24:09 +0800) Xilinx Zynq ZC702Model: Zynq ZC702 Development BoardBoard: Xilinx ZynqSilicon: v3.1I2C: readyDRAM: ECC disabled 256 MiBNAND: 128 MiB...## Booting kernel from Legacy Image at 00008000 ... Image Name: Linux-4.19.0-xilinx Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 4322424 Bytes = 4.1 MiB Load Address: 00008000 Entry Point: 00008000 Verifying Checksum ... OK## Flattened Device Tree blob at 00000000 Booting using the fdt blob at 0x000000 Loading Kernel Image ... OK Loading Device Tree to 0eafd000, end 0eb037a6 ... OKStarting kernel ...Booting Linux on physical CPU 0x0Linux version 4.19.0-xilinx (hyq@ict) (gcc version 6.2.1 20161114 (Linaro GCC Snapshot 6.2-2016.11))#19 SMP PREEMPT Wed Apr 24 21:55:25 CST 2019CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387dCPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cacheOF: fdt: Machine model: Xilinx ZC702 board...VFS: Mounted root (ext4 filesystem) on device 179:2.devtmpfs: mountedFreeing unused kernel memory: 1024KRun /sbin/init as init processrandom: fast init donesystemd[1]: System time before build time, advancing clock.systemd[1]: Failed to insert module 'autofs4': No such file or directorysystemd[1]: systemd 237 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT+UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2default-hierarchy=hybrid)systemd[1]: Detected architecture arm.Welcome to Ubuntu 18.04 LTS!systemd[1]: Set hostname to <armhf>.systemd[1]: File /lib/systemd/system/systemd-journald.service:36 configures an IP firewall (IPAddressDeny=any), but the local system does not support BPF/cgroup based firewalling.systemd[1]: Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)random: systemd: uninitialized urandom read (16 bytes read)systemd[1]: Reached target Swap.[ OK ] Reached target Swap....[ OK ] Started resolvconf-pull-resolved.service.Ubuntu 18.04 LTS armhf ttyPS0armhf login: ubuntuPassword:Last login: Fri Apr 26 17:35:14 UTC 2019 on ttyPS0Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.19.0-xilinx armv7l)* Documentation: https://help.ubuntu.com* Management: https://landscape.canonical.com* Support: https://ubuntu.com/advantageubuntu@armhf:~$
跑個screenfetch來看看:
gcc真的能用。。但是真是慢。。