在树莓派4上安装了ubuntu core 20, 走马观花看看文件目录
scp看到的根文件系统如下
最明显的是多了一个snap. 这里是安装的snap包。包括如下子目录
- /snap/bin - Symlinks to snap applications.
- /snap// - Mountpoint for snap content.
- /snap//current - Symlink to current revision, if enabled.
ssh登陆看到的snap list 如下
对应的snap 目录如下
ubuntu core 由4 类snap 构成,gadget snap, kernel snap , core snap , app snaps。
- gadget snap 是包含了uboot image,系统镜像的布局,IO 接口的权限,系统的默认属性设定(usb 自动挂载属性等),gadget snap 描述了这个设备几乎所有的属性。
- kernel snap 包含kernel & ubuntu core 所需要的initrd 的snap。
- core snap 包含ubuntu core rootfs 的snap 包
- app snap 关于包含app 的snap。
gadget snap
pi 是gadget snap. gadget snap负责定义和配置特定于一个或多个设备的系统属性。
gadget元数据和内容定义包括:
- 设备存储和映像的“Volume”的布局
- 配置bootloader。gadget还附带引导加载程序本身和其他引导资产。
- 安装snap时使用的默认配置选项。
- 在connections中配置的接口: 连接只在设备的第一次启动时执行。稍后对本节的更改(即在运行时通过gadget刷新添加到设备的更改)不会应用。
- 可选钩子被调用来控制和定制设备生命周期的行为,例如安装,初始化和建立设备标识,工厂重置。
打开pi目录
gadget.yaml 如下。
可以看到,gadget snap 中包含了uboot 镜像,以及生成的sdcard 镜像的分区定义,以及分区的放置内容, 设备接口的访问权限… 等功能
volumes:
pi:
schema: mbr
bootloader: u-boot
structure:
- name: ubuntu-seed
role: system-seed
filesystem: vfat
type: 0C
size: 1200M
content:
- source: $kernel:dtbs/dtbs/
target: /
- source: boot-assets/
target: /
- name: ubuntu-boot
role: system-boot
filesystem: vfat
type: 0C
# whats the appropriate size?
size: 750M
content:
# TODO:UC20: install the boot.sel via snapd instead of via the gadget
- source: boot.sel
target: uboot/ubuntu/boot.sel
# NOTE: ubuntu-save is optional for unencrypted devices like the pi, so
# this structure can be dropped in favor of a different partition for
# users who wish to instead use a different partition, since with MBR we
# are limited to only 4 primary partitions.
# TODO: look into switching over to GPT, the pi bootloader firmware now
# has support for this
- name: ubuntu-save
role: system-save
filesystem: ext4
type: 83,0FC63DAF-8483-4772-8E79-3D69D8477DE4
size: 16M
- name: ubuntu-data
role: system-data
filesystem: ext4
type: 83,0FC63DAF-8483-4772-8E79-3D69D8477DE4
# XXX: make auto-grow to partition
size: 1500M
snapcraft.yaml
name: pi
version: 20-1
summary: Raspberry Pi gadget
description: |
Support files for booting Raspberry Pi.
This gadget snap supports the Raspberry Pi 2B, 3B, 3A+, 3B+, 4B, Compute
Module 3, and the Compute Module 3+ universally.
type: gadget
base: core20
assumes: [kernel-assets]
architectures:
- build-on: [amd64, armhf]
run-on: armhf
confinement: strict
grade: stable
parts:
add-ppa:
plugin: nil
build-packages:
- software-properties-common
override-pull: |
sudo add-apt-repository --yes ppa:snappy-dev/image
sudo apt update
gadget:
after: [add-ppa]
plugin: nil
source: .
override-build: |
set -x
# unconditionally set the arch-triplet since this snapcraft.yaml will
# always be used to produce an armhf snap
BUILD_ARCH_TRIPLET=arm-linux-gnueabihf
OPTIONAL_ARGS="SOURCES_HOST=\"./helpers/cross-sources.list\" SOURCES_D_HOST=\"./helpers\""
make -C $SNAPCRAFT_PART_SRC core \
DESTDIR=${SNAPCRAFT_PART_INSTALL} \
ARCH="$(dpkg-architecture -t $BUILD_ARCH_TRIPLET -q DEB_HOST_ARCH)" \
${OPTIONAL_ARGS:-}
prime:
- boot-assets/*
- uboot.conf
- boot.sel
build-packages:
- u-boot-tools
- lsb-release
- dpkg-dev
- make
psplash-local:
after: [add-ppa]
plugin: dump
prime: [-*]
source: .
stage: [psplash]
psplash:
after: [psplash-local]
source: git://git.yoctoproject.org/psplash
source-commit: 2015f7073e98dd9562db0936a254af5ef56356cf
plugin: nil
override-build: |
set -x
if [ "$SNAPCRAFT_ARCH_TRIPLET" = "x86_64-linux-gnu" ] || [ -z "$SNAPCRAFT_ARCH_TRIPLET" ]; then
# manually set since new snapcraft doesn't like --target-arch when
# building with lxd/multipass
BUILD_ARCH_TRIPLET=arm-linux-gnueabihf
else
BUILD_ARCH_TRIPLET=$SNAPCRAFT_ARCH_TRIPLET
fi
export TREE="${SNAPCRAFT_STAGE:-.}/psplash"
. ${TREE}/config
if ! $(echo "$FONT" | grep -q ^/); then
FONT="${TREE}/${FONT}"
fi
if ! $(echo "$SPLASH" | grep -q ^/); then
SPLASH="${TREE}/${SPLASH}"
fi
git apply ${TREE}/psplash.patch
${TREE}/font-gen.sh "$FONT"
./make-image-header.sh "$SPLASH" CORE psplash-core
aclocal
autoreconf --install
if ! dpkg-architecture -t "${SNAPCRAFT_ARCH_TRIPLET}" -e \
$(dpkg-architecture -q DEB_BUILD_ARCH)
then
export CROSS_COMPILE=$(dpkg-architecture \
-t "${BUILD_ARCH_TRIPLET}" -q DEB_HOST_GNU_TYPE)-
else
export CROSS_COMPILE=
fi
./configure --build=$(dpkg-architecture -q DEB_BUILD_GNU_TYPE) \
--host=${BUILD_ARCH_TRIPLET} CC=${CROSS_COMPILE}gcc || cat config.log
ARCH=$(dpkg-architecture -t "${BUILD_ARCH_TRIPLET}" -q DEB_HOST_ARCH) make
rm -rf $SNAPCRAFT_PART_INSTALL/usr
cp -a $TREE/initrd .
mkdir -p initrd/bin
cp psplash initrd/bin
mkdir -p $SNAPCRAFT_PART_INSTALL/boot-assets
cd initrd && find . | cpio --quiet -o -H newc | lz4 -9 -l >> \
"${SNAPCRAFT_PART_INSTALL}/boot-assets/psplash.img"
build-packages:
- libgdk-pixbuf2.0-dev
- automake
- autoconf
- gcc
- otf2bdf
- libbogl-dev
- ttf-ubuntu-font-family
- cpio
- findutils
- liblz4-tool
- libc-dev
- try:
- gcc-aarch64-linux-gnu:amd64
- libc6-dev-armhf-cross:amd64
slots:
bcm-gpio-0:
interface: gpio
number: 0
bcm-gpio-1:
interface: gpio
number: 1
bcm-gpio-2:
interface: gpio
number: 2
bcm-gpio-3:
interface: gpio
number: 3
bcm-gpio-4:
interface: gpio
number: 4
bcm-gpio-5:
interface: gpio
number: 5
bcm-gpio-6:
interface: gpio
number: 6
bcm-gpio-7:
interface: gpio
number: 7
bcm-gpio-8:
interface: gpio
number: 8
bcm-gpio-9:
interface: gpio
number: 9
bcm-gpio-10:
interface: gpio
number: 10
bcm-gpio-11:
interface: gpio
number: 11
bcm-gpio-12:
interface: gpio
number: 12
bcm-gpio-13:
interface: gpio
number: 13
bcm-gpio-14:
interface: gpio
number: 14
bcm-gpio-15:
interface: gpio
number: 15
bcm-gpio-16:
interface: gpio
number: 16
bcm-gpio-17:
interface: gpio
number: 17
bcm-gpio-18:
interface: gpio
number: 18
bcm-gpio-19:
interface: gpio
number: 19
bcm-gpio-20:
interface: gpio
number: 20
bcm-gpio-21:
interface: gpio
number: 21
bcm-gpio-22:
interface: gpio
number: 22
bcm-gpio-23:
interface: gpio
number: 23
bcm-gpio-24:
interface: gpio
number: 24
bcm-gpio-25:
interface: gpio
number: 25
bcm-gpio-26:
interface: gpio
number: 26
bcm-gpio-27:
interface: gpio
number: 27
i2c-0:
interface: i2c
path: /dev/i2c-0
i2c-1:
interface: i2c
path: /dev/i2c-1
i2c-2:
interface: i2c
path: /dev/i2c-2
bt-serial:
interface: serial-port
path: /dev/ttyAMA0
spidev0:
interface: spi
path: /dev/spidev0.0
spidev1:
interface: spi
path: /dev/spidev0.1
snap.yaml
每个snap包都包含一个元/快照。保存快照的基本元数据的Yaml文件。
请注意这一重要区别:
- snap.yaml存在于每个snap包中,通过snapd读取
- snapcraft.yaml包含创建snap包的指令,由用于构建snap的snapcraft命令读取
snap.yaml支持的大部分元数据是可选的。事实上,最简单的snap.yaml可以包含以下内容:
name: simplest
version: 1.0
pi gadget 的snap.yaml 如下
name: pi
version: 20-1
summary: Raspberry Pi gadget
description: |
Support files for booting Raspberry Pi.
This gadget snap supports the Raspberry Pi 2B, 3B, 3A+, 3B+, 4B, Compute
Module 3, and the Compute Module 3+ universally.
architectures:
- armhf
assumes:
- kernel-assets
base: core20
confinement: strict
grade: stable
slots:
bcm-gpio-0:
interface: gpio
number: 0
bcm-gpio-1:
interface: gpio
number: 1
bcm-gpio-10:
interface: gpio
number: 10
bcm-gpio-11:
interface: gpio
number: 11
bcm-gpio-12:
interface: gpio
number: 12
bcm-gpio-13:
interface: gpio
number: 13
bcm-gpio-14:
interface: gpio
number: 14
bcm-gpio-15:
interface: gpio
number: 15
bcm-gpio-16:
interface: gpio
number: 16
bcm-gpio-17:
interface: gpio
number: 17
bcm-gpio-18:
interface: gpio
number: 18
bcm-gpio-19:
interface: gpio
number: 19
bcm-gpio-2:
interface: gpio
number: 2
bcm-gpio-20:
interface: gpio
number: 20
bcm-gpio-21:
interface: gpio
number: 21
bcm-gpio-22:
interface: gpio
number: 22
bcm-gpio-23:
interface: gpio
number: 23
bcm-gpio-24:
interface: gpio
number: 24
bcm-gpio-25:
interface: gpio
number: 25
bcm-gpio-26:
interface: gpio
number: 26
bcm-gpio-27:
interface: gpio
number: 27
bcm-gpio-3:
interface: gpio
number: 3
bcm-gpio-4:
interface: gpio
number: 4
bcm-gpio-5:
interface: gpio
number: 5
bcm-gpio-6:
interface: gpio
number: 6
bcm-gpio-7:
interface: gpio
number: 7
bcm-gpio-8:
interface: gpio
number: 8
bcm-gpio-9:
interface: gpio
number: 9
bt-serial:
interface: serial-port
path: /dev/ttyAMA0
i2c-0:
interface: i2c
path: /dev/i2c-0
i2c-1:
interface: i2c
path: /dev/i2c-1
i2c-2:
interface: i2c
path: /dev/i2c-2
spidev0:
interface: spi
path: /dev/spidev0.0
spidev1:
interface: spi
path: /dev/spidev0.1
type: gadget
kernel snap
pi-kernel是kernel snap。 目录如下
可以看到这里包括了initrd和kernel镜像。
snapcraft.yaml 如下
name: pi-kernel
version: 5.4.0-1038.41
summary: The Canonical Raspberry Pi kernel
description: The Canonical Raspberry Pi kernel
type: kernel
confinement: strict
assumes:
- kernel-assets
parts:
kernel:
source: git://git.launchpad.net/~canonical-kernel-snaps/+git/kernel-snaps-uc20
source-type: git
source-branch: master
plugin: make
make-parameters:
- KERNEL_SOURCE=focal:linux-raspi
- KERNEL=linux-image-raspi
- PKGS=bluez-firmware linux-firmware-raspi2
- PROPOSED=true
build-packages:
- debootstrap
- lsb-release
core snap
core20是core snap, 为ubuntu cored的rootfs。可以看到根目录下的子项几乎都在这里。
snapcraft.yaml
name: core20
# version: "20"
adopt-info: bootstrap
summary: Runtime environment based on Ubuntu 20.04
description: |
The base snap based on the Ubuntu 20.04 release.
confinement: strict
type: base
build-base: core20
parts:
consoleconf-deb:
plugin: nil
source: https://github.com/CanonicalLtd/subiquity.git
source-type: git
source-branch: core/focal
override-pull: |
snapcraftctl pull
# install build dependencies
export DEBIAN_FRONTEND=noninteractive
export DEBCONF_NONINTERACTIVE_SEEN=true
sudo -E apt-get build-dep -y ./
override-build: |
# unset the LD_FLAGS and LD_LIBRARY_PATH vars that snapcraft sets for us
# as those will point to the $SNAPCRAFT_STAGE which on re-builds will
# contain things like libc and friends that confuse the debian package
# build system
# TODO: should we unset $PATH to not include $SNAPCRAFT_STAGE too?
unset LD_FLAGS
unset LD_LIBRARY_PATH
# run the real build (but just build the binary package, and don't
# bother compressing it too much)
dpkg-buildpackage -b -uc -us -Zgzip -zfast
cp ../console-conf_*.deb ../subiquitycore_*.deb $SNAPCRAFT_PART_INSTALL
stage:
- -console-conf_*.deb
- -subiquitycore_*.deb
# XXX: Dirty hacks to enable building core20 on non-focal systems.
# See below for details.
override-prime: |
unset LD_LIBRARY_PATH;
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
# ensure snapcraftctl is found, see
# https://github.com/snapcore/snapcraft/pull/2251
export PATH="$PATH:/snap/snapcraft/current/bin/scriptlet-bin"
snapcraftctl prime
avahi-daemon-equiv-deb:
plugin: nil
build-packages:
- equivs
override-build: |
cat > avahi-daemon.control << \EOF
Section: misc
Priority: optional
Standards-Version: 3.9.2
Architecture: all
Package: avahi-daemon
Version: 1000
Multi-Arch: foreign
Description: A dummy version of avahi-daemon
EOF
unset LD_FLAGS LD_LIBRARY_PATH
equivs-build avahi-daemon.control
cp avahi-daemon_*.deb $SNAPCRAFT_PART_INSTALL
stage:
- -avahi-daemon_*.deb
bootstrap:
after:
- consoleconf-deb
- avahi-daemon-equiv-deb
plugin: make
source: .
build-packages:
- shellcheck
- wget
- distro-info
# XXX: Dirty hacks to enable building core20 on non-focal systems.
# Without these overrides both the PATH and LD_LIBRARY_PATH contain paths
# in the part's install directory which binaries can be incompatible with
# the ones running on our system. We don't need those while running stage
# and prime anyway.
override-pull: |
unset LD_LIBRARY_PATH;
snapcraftctl set-version "$(/bin/date +%Y%m%d)"
snapcraftctl pull
override-stage: |
unset LD_LIBRARY_PATH;
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
# ensure snapcraftctl is found, see
# https://github.com/snapcore/snapcraft/pull/2251
export PATH="$PATH:/snap/snapcraft/current/bin/scriptlet-bin"
snapcraftctl stage
override-prime: |
unset LD_LIBRARY_PATH;
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
# ensure snapcraftctl is found, see
# https://github.com/snapcore/snapcraft/pull/2251
export PATH="$PATH:/snap/snapcraft/current/bin/scriptlet-bin"
snapcraftctl prime
# ensure build-in tests are run
cd ${SNAPCRAFT_PART_SRC} && make test TESTDIR=${SNAPCRAFT_PRIME}