-
Notifications
You must be signed in to change notification settings - Fork 1
Custom OS
This entry will explain the general approach for creating a custom OS, that can be provisioned using NOOBS4IoT. Since most Raspberry Pi OS are provided as images, which the user needs to dd
onto the SD Card of the Raspberry Pi, it is not trivial to adopt them for the NOOBS4IoT layout.
We will show the process along the (tested) example of Ubuntu Mate using any Linux based PC to create the files, however the process should be adoptable to all Raspberry Pi image files (especially if they are Linux based and have only two partitions).
A list of predefined OS is available from the Raspberry Pi Foundation, an adopted list can be found in this wiki.
This article is based on an entry from the NOOBS Wiki.
- Get the image file for the Raspberry Pi and extract it, depending on its compression format:
# Downloading file
wget https://ubuntu-mate.org/raspberry-pi/ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img.xz
# Extarction creates "ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img" file that we will work on
unxz ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img.xz
- Mount the image file using
kpartx
, in order to access its content
# Create loopback device for mounting
sudo kpartx -av ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img
# The output will be something like:
# add map loop0p1 (254:0): 0 129024 linear 7:0 2048
# add map loop0p2 (254:1): 0 9633792 linear 7:0 131072
# where loop0p1 and loop0p2 are the partitions that we want to mount (make sure that the mountpoint directories exist):
sudo mount /dev/mapper/loop0p1 /mnt/boot
sudo mount /dev/mapper/loop0p2 /mnt/root
- Create tar files of both partitions, note the size of the uncompressed tarballs for later (
ls
command output)
# Processing boot archive
cd /mnt/boot
tar -cpf /tmp/boot.tar
ls /tmp/boot.tar -l --block-size=1MB
xz -9 -e /tmp/boot.tar
# Processing root archive (tar must be executed as root)
cd /mnt/root
sudo tar -cpf /tmp/root.tar . --exclude=proc/* --exclude=sys/* --exclude=dev/pts/*
ls /tmp/root.tar -l --block-size=1MB
xz -9 -e /tmp/root.tar
- Unmount and remove loopback device
umount /mnt/root
umount /mnt/boot
sudo kpartx -dv ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img
- Finally move the tar.xz files to the webserver path, where you want to provide them. We will asume the following root address where the
tar
files are direct accessible for the next steps:http://somehost.com/ubuntu_mate/
This file contains general information about the OS that will be installed. Most important is the supported_hex_revisions
part. You need to make sure that one of the revision is mentioned in the /proc/device-tree/model
of your target Pi (and make sure that the downloaded image is actually compatible with your Pi.
{
"name": "Ubuntu_Mate",
"version": "16.04.2 LTS",
"release_date": "2015-02-17",
"kernel": "4.8",
"description": "Ubuntu MATE for the Raspberry Pi 2",
"url": "https://ubuntu-mate.org/raspberry-pi/",
"supported_hex_revisions": "1040,1041",
"feature_level": 0
}
This file contains the list of partitions, that the OS needs, with their respective size and filesystem type.
First we need to gather the missing file sizes. uncompressed_tarball_size
was the output of step three in "Partition archives". partition_size_nominal
can be obtained throug the following command:
sudo parted -s ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img print
# The output will look like this
# Model: (file)
# Disk /var/www/default/ubuntu_mate/ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img: 5000MB
# Sector size (logical/physical): 512B/512B
# Partition Table: msdos
# Disk Flags:
#
# Number Start End Size Type File system Flags
# 1 1049kB 67.1MB 66.1MB primary fat16 lba
# 2 67.1MB 5000MB 4933MB primary ext4
# We will use the rounded up "Size" column
Resulting in the following file:
{
"partitions": [
{
"label": "boot",
"filesystem_type": "FAT",
"partition_size_nominal": 68,
"want_maximised": false,
"uncompressed_tarball_size": 22
},
{
"label": "root",
"filesystem_type": "ext4",
"partition_size_nominal": 4933,
"want_maximised": true,
"mkfs_options": "-O ^huge_file",
"uncompressed_tarball_size": 3458
}
]
}
Finally we need to add the post install script. This file will set the correct partitions after installation in the fstab
and commandline.txt
file, in order to properly boot. Depending on your OS and the amount of partitions, this file needs to be adopted. $part1
, part2
, ... contain the partition device NOOBS created and filed using the above created tarballs.
#!/bin/sh
set -ex
if [ -z "$part1" ] || [ -z "$part2" ]; then
printf "Error: missing environment variable part1 or part2\n" 1>&2
exit 1
fi
mkdir -p /tmp/1 /tmp/2
mount "$part1" /tmp/1
mount "$part2" /tmp/2
sed /tmp/1/cmdline.txt -i -e "s|root=/dev/[^ ]*|root=${part2}|"
sed /tmp/2/etc/fstab -i -e "s|^.* / |${part2} / |"
sed /tmp/2/etc/fstab -i -e "s|^.* /boot |${part1} /boot |"
umount /tmp/1
umount /tmp/2
Finally we need to specify the JSON request file. We will keep it simple:
{
"description": "Ubuntu MATE for the Raspberry Pi",
"os_info": "http://somehost.com/ubuntu_mate/os.json",
"os_name": "Ubuntu MATE 16.04.2 LTS",
"partition_setup": "http://somehost.com/ubuntu_mate/partition_setup.sh",
"partitions_info": "http://somehost.com/ubuntu_mate/partitions.json",
"release_date": "2017-02-17",
"supported_hex_revisions": "1040,1041",
"supported_models": [
"Pi 2",
"Pi 3"
],
"tarballs": [
"http://somehost.com/ubuntu_mate/boot.tar.xz",
"http://somehost.com/ubuntu_mate/root.tar.xz"
]
}
NOOBS4IoT Documentation by Frank Steiler is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. Based on the work at the NOOBS4IoT Github Repository.