Changes between Version 29 and Version 30 of ubuntu


Ignore:
Timestamp:
10/17/2023 10:41:31 PM (7 months ago)
Author:
Tim Harvey
Comment:

added rootfs generation sections

Legend:

Unmodified
Added
Removed
Modified
  • ubuntu

    v29 v30  
    1414 * [wiki:ventana/ubuntu Ventana Ubuntu Page]
    1515[[Image(ubuntufocalwithversion.png,300px)]]
     16
     17== Ubuntu root filesystem
     18Creating a root filesystem comprised of Canonical built packages can be done in a couple of ways:
     19 * download a pre-built rootfs tarball
     20 * create one using deboostrap
     21 * create one using qemu/chroot
     22
     23This refers to the rootfs only. To easily build an entire system image, including the boot firmware and Ubuntu, look at the BSP for the various product families:
     24 * [wiki:malibu/bsp Malibu BSP]
     25 * [wiki:venice/bsp Venice BSP]
     26 * [wiki:newport/bsp Newport BSP]
     27
     28=== Downloading pre-built rootfs tarball
     29Gateworks has pre-built Ubuntu based rootfs tarballs at http://dev.gateworks.com/ubuntu/ that are created with the [https://github.com/gateworks/ubuntu-rootfs ubuntu-rootfs script].
     30
     31[=#qemu-chroot]
     32=== Creating Ubuntu rootfs using qemu and chroot
     33You can use qemu to create an Ubuntu based rootfs with very little in the way of dependencies. To do this you must boot a virtual machine for your architecture therefore you will need a kernel and a minimal root filesystem which can be easily built using buildroot.
     34
     35Example:
     36* aarch64 rootfs:
     371. Start by defining some parameters
     38{{{#!bash
     39IMG=ubuntu.ext4
     40SIZE=500M
     41UBUNTU=22.04
     42UBUNTU_REL=.3
     43}}}
     441. Create a ramdisk based image (similar concept as rescue image but we add a file here via BR2_ROOTFS_OVERLAY)
     45{{{#!bash
     46sudo apt install build-essential git
     47git clone http://github.com/buildroot/buildroot.git
     48cd buildroot
     49cat << EOF > configs/buildroot_defconfig
     50BR2_aarch64=y
     51BR2_cortex_a72=y
     52BR2_TOOLCHAIN_BUILDROOT_GLIBC=y
     53BR2_TOOLCHAIN_BUILDROOT_CXX=y
     54BR2_TARGET_GENERIC_HOSTNAME="localhost"
     55BR2_ROOTFS_OVERLAY="overlay/"
     56BR2_LINUX_KERNEL=y
     57BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG=y
     58BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y
     59BR2_PACKAGE_E2FSPROGS=y
     60# BR2_PACKAGE_E2FSPROGS_FSCK is not set
     61BR2_PACKAGE_I2C_TOOLS=y
     62BR2_PACKAGE_RNG_TOOLS=y
     63BR2_PACKAGE_BASH=y
     64BR2_PACKAGE_TAR=y
     65BR2_PACKAGE_UTIL_LINUX_HWCLOCK=y
     66BR2_TARGET_ROOTFS_CPIO=y
     67BR2_TARGET_ROOTFS_CPIO_GZIP=y
     68EOF
     69# create init script
     70mkdir -p overlay/etc/init.d
     71cat <<EOF > overlay/etc/init.d/S99boostrap-ubuntu.sh
     72#!/bin/sh
     73
     74if [ "\$1" != "start" ]; then
     75    exit
     76fi
     77
     78# setup
     79mkfs.ext4 -F /dev/vda -b 4096
     80mount /dev/vda /mnt
     81cd /mnt/
     82udhcpc -i eth0
     83# install base rootfs from release tarball
     84wget -c -P /tmp/ http://cdimage.ubuntu.com/ubuntu-base/releases/${UBUNTU}/release/ubuntu-base-${UBUNTU}${UBUNTU_REL}-base-arm64.tar.gz
     85tar zxf /tmp/ubuntu-base-${UBUNTU}${UBUNTU_REL}-base-arm64.tar.gz -C /mnt
     86# setup chroot environment
     87mount -o bind /proc /mnt/proc/
     88mount -o bind /sys/ /mnt/sys/
     89mount -o bind /dev/ /mnt/dev/
     90mount -o bind /dev/pts /mnt/dev/pts
     91mount -t tmpfs tmpfs /mnt/var/lib/apt/
     92mount -t tmpfs tmpfs /mnt/var/cache/apt/
     93echo "nameserver 8.8.8.8" > /mnt/etc/resolv.conf
     94echo "localhost" > /mnt/etc/hostname
     95echo "127.0.0.1 localhost" > /mnt/etc/hosts
     96export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C
     97# install additional packages
     98chroot /mnt apt update
     99chroot /mnt apt upgrade -y
     100chroot /mnt apt install --no-install-recommends -y \
     101     apt-utils locales less wget procps \
     102     psmisc less sudo kmod rng-tools \
     103     ifupdown net-tools isc-dhcp-client ntpdate \
     104     openssh-server iproute2 iptables iputils-ping \
     105     i2c-tools can-utils usbutils pciutils \
     106     screen picocom \
     107     vim nano
     108# set root password
     109echo -e "root\nroot" | chroot /mnt passwd
     110# teardown chroot env
     111umount /mnt/var/lib/apt/
     112umount /mnt/var/cache/apt
     113chroot /mnt apt clean
     114chroot /mnt apt autoclean
     115reboot
     116EOF
     117chmod +x overlay/etc/init.d/S99boostrap-ubuntu.sh
     118make buildroot_defconfig
     119make -j8
     120}}}
     121 * generic aarch64 kernel Image and rootfs.cpio.gz will be in output/images
     122
     1232. Use qemu to kick off a virtual aarch64 machine which will run the init script and  create root filesystem on a virtual disk
     124{{{#!bash
     125apt install qemu-system-arm
     126truncate -s $SIZE $IMG
     127qemu-system-aarch64 -m 1G -M virt -cpu cortex-a57 -nographic -smp 1 -no-reboot \
     128   -device virtio-net-device,netdev=eth0 -netdev user,id=eth0 \
     129   -device virtio-blk-device,drive=hd0 -drive file=$IMG,if=none,format=raw,id=hd0 \
     130   -append "console=ttyAMA0 ip=dhcp" \
     131   -kernel output/images/Image \
     132   -initrd output/images/rootfs.cpio.gz
     133}}}
     134 * ubuntu.ext4 contains your rootfs - add desired changes to the setup script
     135
     136
     137[=#debootstrap]
     138=== Creating Ubuntu rootfs using deboostrap
     139A popular way to create an Ubuntu root filesystem is to use the {{{deboostrap}}} utility on a Debian or Ubuntu host. This tool provides a 2-stage install where the second stage is within a chroot environment using qemu.
     140
     141Gateworks uses a script to do this which you may find at http://github.com/Gateworks/ubuntu-rootfs
     142
     143Requirements:
     144- Linux Ubuntu or Debian System with network connection and sudo permissions
     145
     146Important notes:
     147 * We set and use '''target''' and '''distro''' env variables in step 2 and use those env variables in the remaining steps to make this tutorial more version-agnostic. Please be aware of this and do not deviate from the steps unless or until you completely understand what you are doing.
     148 * These steps are not always exactly what we do in our script but give you an idea of how you would go about doing it yourself if you wanted to customize something
     149
     150Steps:
     1511. Install pre-requisites:
     152{{{
     153#!bash
     154sudo apt-get install qemu-user-static debootstrap binfmt-support
     155}}}
     156
     1572. Perform first stage install of minimal filesystem for {{{arm64}}} architecture:
     158{{{#!bash
     159distro=focal
     160arch=arm64
     161target=${distro}-${arch}
     162qemu_arch=aarch64
     163sudo debootstrap --arch=$arch --foreign $distro $target
     164# copy qemu binary for the binfmt packages to find it and copy in resolv.conf from host
     165sudo cp /usr/bin/qemu-${qemu_arch}-static $target/usr/bin
     166}}}
     167 * See http://ports.ubuntu.com/ubuntu-ports/dists/ for a list of current Ubuntu releases: oe 20.04=focal (latest LTS)
     168 * this minimal rootfs is still missing some core packages and configuration before it can be booted. These steps are taken care of in a 2nd stage install within a chroot shell
     169 * the chroot shell below will provide network support (inherited from the host)
     170
     1713. We now have a minimal Ubuntu rootfs - chroot to it and perform the 2nd stage install:
     172{{{
     173#!bash
     174sudo chroot $target
     175# now we are in the chroot - setup env matching the distro above
     176distro=focal
     177export LANG=C
     178# setup second stage
     179/debootstrap/debootstrap --second-stage
     180}}}
     181 * this is the most minimal rootfs we would recommend
     182
     1834. (optional) add additional apt package repos:
     184{{{
     185#!bash
     186cat <<EOT > /etc/apt/sources.list
     187deb http://ports.ubuntu.com/ubuntu-ports $distro main restricted universe multiverse
     188deb http://ports.ubuntu.com/ubuntu-ports $distro-updates main restricted universe multiverse
     189deb http://ports.ubuntu.com/ubuntu-ports $distro-security main restricted universe multiverse
     190EOT
     191}}}
     192 * you may want to customize the above list, depending on your needs. See [#packages below] for more detail on Ubuntu package feeds
     193
     1945. (optional) update package database and setup locales (do not skip this step if you are needing to install any packages for the steps below or otherwise)
     195{{{
     196#!bash
     197apt-get update
     198apt-get -f install # fixup missing package dependencies
     199apt-get install locales dialog
     200dpkg-reconfigure locales
     201}}}
     202
     2036. Set hostname:
     204{{{
     205#!bash
     206echo ${distro}-$(uname -m) > /etc/hostname
     207}}}
     208
     2097. set a root passwd so you can login
     210{{{
     211#!bash
     212passwd
     213}}}
     214 - or consider adding a user via {{{adduser}}}:
     215{{{
     216#!bash
     217adduser myuser
     218usermod -a -G tty myuser # add to tty group for tty access
     219usermod -a -G dialout myuser # add to dialout group for UART access
     220usermod -a -G sudo myuser # add to sudo group for root access
     221}}}
     222
     2238. (optional) configure networking:
     224 - wired ethernet with DHCP on eth0
     225{{{#!bash
     226apt-get install net-tools ifupdown
     227cat <<EOF >> /etc/network/interfaces
     228allow-hotplug eth0
     229auto eth0
     230iface eth0 inet dhcp
     231
     232EOF
     233}}}
     234 - or static IP:
     235{{{#!bash
     236apt-get install net-tools ifupdown
     237cat <<EOF >> /etc/network/interfaces
     238allow-hotplug eth0
     239auto eth0
     240iface eth0 inet static
     241address 192.168.1.1
     242netmask 255.255.255.0
     243gateway 192.168.1.254
     244
     245EOF
     246}}}
     247 - or wireless (requires ~3MB of additional packages):
     248{{{
     249#!bash
     250apt-get install wpasupplicant iw
     251cat << EOF >> /etc/network/interfaces
     252# Wireless interface
     253auto wlan0
     254iface wlan0 inet dhcp
     255        wireless_mode managed
     256        wireless_essid any
     257        wpa-driver nl80211
     258        wpa-conf /etc/wpa_supplicant.conf
     259
     260EOF
     261wpa_passphrase <myssid> <mypass> >> /etc/wpa_supplicant.conf
     262}}}
     263
     2649. (optional) install some useful packages
     265{{{
     266#!bash
     267apt-get install openssh-server # ssh server for remote access
     268apt-get install can-utils i2c-tools usbutils pciutils # cmdline tools for various hardware support
     269}}}
     270 * Note that by default root ssh access is disabled for security. See [wiki:/ubuntu#SSHServer This link] for info on enabling it
     271
     27210. Exit the chroot shell and remove files we no longer need
     273{{{
     274#!bash
     275exit
     276sudo rm $target/usr/bin/qemu-$qemu_arch-static
     277}}}
     278
     279At this point you have a directory containing a root filesystem (without kernel) and likely want to install it onto removable storage or the on-board FLASH of a target board. Some intermediate formats that are useful to keep around would be a tarball, perhaps an ext4 filesystem image, or a compressed disk image suitable for flashing in the U-Boot bootloader.
     280
     281To create a tarball which is the most flexible storage format and can be used for a variety of future installation uses:
     282{{{#!bash
     283sudo tar --keep-directory-symlink -cvJf focal-venice.tar.xz -C rootfs/ .
     284}}}
     285 * '--numeric-owner' is required to store user/group as a number instead of a name, your specific use case may require this switch.
     286 * the '-C rootfs/' is required to eliminate the rootfs directory prefix
     287 * the sudo is needed to be able to read the root owned files
     288 * '--keep-directory-symlink' will preserve symbolic links
     289
     290To create an ext4 filesystem from the directory or tarball requires you choose a size for the filesystem. This size can be increased at runtime using {{{resize2fs}}} as long as the partition table has room for it to grow. The advantage of using an as small as possible size is that the time necessary to flash it onto storage is reduced to a minimum (when flashing you have to write the entire ext4 fs but when formatting or resizing it only has to write periodic markers to FLASH).
     291
     292For a given size (see SIZEMB variable below) you can create a rootfs with:
     293{{{#!bash
     294SIZEMB=1536 # 1.5GB - expandable later with resize2fs
     295OUT=rootfs.ext4
     296# create a file of specific size
     297truncate -s ${SIZEMB}M ${OUT}
     298# format it as an ext4 filesystem
     299mkfs.ext4 -q -F -L rootfs ${OUT}
     300# mount it to a temporary mount point
     301tmp_mnt=$(mktemp -d -p/tmp)
     302mount ${OUT} ${tmp_mnt}
     303# copy files to it
     304cp -rup rootfs/* ${tmp_mnt}
     305# and/or extract files from a tarball
     306tar -C ${tmp_mnt} -xf linux-venice.tar.xz --keep-directory-symlink
     307# unmount temporary mount point
     308umount ${tmp_mnt}
     309sync
     310# compress it
     311gzip -k -f ${OUT}
     312}}}
    16313
    17314== Ubuntu Webmin