2017-01-20 17:29:01 +00:00
# pi-gen
2017-05-06 23:16:00 +00:00
2017-01-20 17:29:01 +00:00
_Tool used to create the raspberrypi.org Raspbian images_
2016-04-11 06:25:30 +00:00
2017-05-06 23:16:00 +00:00
2017-01-20 17:29:01 +00:00
## Dependencies
2016-04-11 06:25:30 +00:00
2017-12-15 11:31:40 +00:00
pi-gen runs on Debian based operating systems. Currently it is only supported on
2019-07-23 13:43:07 +00:00
either Debian Buster or Ubuntu Xenial and is known to have issues building on
2019-02-17 16:27:43 +00:00
earlier releases of these systems. On other Linux distributions it may be possible
to use the Docker build described below.
2017-12-15 11:31:40 +00:00
To install the required dependencies for pi-gen you should run:
2017-05-06 23:16:00 +00:00
```bash
2019-03-11 11:49:04 +00:00
apt-get install coreutils quilt parted qemu-user-static debootstrap zerofree zip \
2020-01-24 12:48:57 +00:00
dosfstools bsdtar libcap2-bin grep rsync xz-utils file git curl bc
2017-05-06 23:16:00 +00:00
```
The file `depends` contains a list of tools needed. The format of this
package is `<tool>[:<debian-package>]` .
2016-09-05 04:02:39 +00:00
2017-01-20 17:29:01 +00:00
## Config
2016-09-05 04:02:39 +00:00
Upon execution, `build.sh` will source the file `config` in the current
working directory. This bash shell fragment is intended to set needed
environment variables.
The following environment variables are supported:
2016-10-05 21:56:45 +00:00
* `IMG_NAME` **required** (Default: unset)
The name of the image to build with the current stage directories. Setting
`IMG_NAME=Raspbian` is logical for an unmodified RPi-Distro/pi-gen build,
but you should use something else for a customized version. Export files
in stages may add suffixes to `IMG_NAME` .
2020-02-26 13:36:39 +00:00
* `RELEASE` (Default: buster)
The release version to build images against. Valid values are jessie, stretch
buster, bullseye, and testing.
2016-10-05 21:56:45 +00:00
* `APT_PROXY` (Default: unset)
If you require the use of an apt proxy, set it here. This proxy setting
will not be included in the image, making it safe to use an `apt-cacher` or
similar package for development.
2017-07-17 10:17:15 +00:00
If you have Docker installed, you can set up a local apt caching proxy to
like speed up subsequent builds like this:
docker-compose up -d
echo 'APT_PROXY=http://172.17.0.1:3142' >> config
2017-05-06 23:16:00 +00:00
* `BASE_DIR` (Default: location of `build.sh` )
**CAUTION** : Currently, changing this value will probably break build.sh
Top-level directory for `pi-gen` . Contains stage directories, build
scripts, and by default both work and deployment directories.
* `WORK_DIR` (Default: `"$BASE_DIR/work"` )
Directory in which `pi-gen` builds the target system. This value can be
changed if you have a suitably large, fast storage location for stages to
be built and cached. Note, `WORK_DIR` stores a complete copy of the target
system for each build stage, amounting to tens of gigabytes in the case of
Raspbian.
2019-10-26 10:49:30 +00:00
2017-09-28 12:29:04 +00:00
**CAUTION** : If your working directory is on an NTFS partition you probably won't be able to build. Make sure this is a proper Linux filesystem.
2017-05-06 23:16:00 +00:00
* `DEPLOY_DIR` (Default: `"$BASE_DIR/deploy"` )
Output directory for target system images and NOOBS bundles.
2019-01-30 18:09:36 +00:00
* `DEPLOY_ZIP` (Default: `1` )
Setting to `0` will deploy the actual image (`.img`) instead of a zipped image (`.zip`).
2017-09-07 21:47:35 +00:00
* `USE_QEMU` (Default: `"0"` )
2018-03-19 19:17:58 +00:00
Setting to '1' enables the QEMU mode - creating an image that can be mounted via QEMU for an emulated
environment. These images include "-qemu" in the image file name.
2017-09-07 21:47:35 +00:00
2019-08-14 10:26:55 +00:00
* `LOCALE_DEFAULT` (Default: "en_GB.UTF-8" )
Default system locale.
2019-12-05 16:25:18 +00:00
* `TARGET_HOSTNAME` (Default: "raspberrypi" )
2019-10-26 10:49:30 +00:00
Setting the hostname to the specified value.
2019-08-14 10:26:55 +00:00
* `KEYBOARD_KEYMAP` (Default: "gb" )
Default keyboard keymap.
2019-10-13 17:57:50 +00:00
To get the current value from a running system, run `debconf-show
keyboard-configuration` and look at the
`keyboard-configuration/xkb-keymap` value.
2019-08-14 10:26:55 +00:00
* `KEYBOARD_LAYOUT` (Default: "English (UK)" )
Default keyboard layout.
2019-10-13 17:57:50 +00:00
To get the current value from a running system, run `debconf-show
keyboard-configuration` and look at the
`keyboard-configuration/variant` value.
2019-08-14 10:26:55 +00:00
* `TIMEZONE_DEFAULT` (Default: "Europe/London" )
Default keyboard layout.
2019-10-13 17:57:50 +00:00
To get the current value from a running system, look in
`/etc/timezone` .
2018-12-09 22:52:03 +00:00
* `FIRST_USER_NAME` (Default: "pi" )
Username for the first user
* `FIRST_USER_PASS` (Default: "raspberry")
Password for the first user
2017-05-06 23:16:00 +00:00
2018-12-17 00:01:04 +00:00
* `WPA_ESSID` , `WPA_PASSWORD` and `WPA_COUNTRY` (Default: unset)
2020-01-08 11:55:34 +00:00
If these are set, they are use to configure `wpa_supplicant.conf` , so that the Raspberry Pi can automatically connect to a wifi network on first boot. If `WPA_ESSID` is set and `WPA_PASSWORD` is unset an unprotected wifi network will be configured. If set, `WPA_PASSWORD` must be between 8 and 63 characters.
2018-12-17 00:01:04 +00:00
2018-12-18 18:32:06 +00:00
* `ENABLE_SSH` (Default: `0` )
2020-01-08 11:55:34 +00:00
Setting to `1` will enable ssh server for remote log in. Note that if you are using a common password such as the defaults there is a high risk of attackers taking over you Raspberry Pi.
2018-12-18 18:32:06 +00:00
2019-01-06 22:37:44 +00:00
* `STAGE_LIST` (Default: `stage*` )
2019-05-30 10:07:16 +00:00
If set, then instead of working through the numeric stages in order, this list will be followed. For example setting to `"stage0 stage1 mystage stage2"` will run the contents of `mystage` before stage2. Note that quotes are needed around the list. An absolute or relative path can be given for stages outside the pi-gen directory.
2019-01-06 22:37:44 +00:00
2016-09-05 04:02:39 +00:00
A simple example for building Raspbian:
```bash
IMG_NAME='Raspbian'
```
2018-12-18 21:06:18 +00:00
The config file can also be specified on the command line as an argument the `build.sh` or `build-docker.sh` scripts.
```
2019-01-20 19:28:50 +00:00
./build.sh -c myconfig
2018-12-18 21:06:18 +00:00
```
This is parsed after `config` so can be used to override values set there.
2017-05-06 23:16:00 +00:00
2017-12-15 11:31:40 +00:00
## How the build process works
The following process is followed to build images:
* Loop through all of the stage directories in alphanumeric order
* Move on to the next directory if this stage directory contains a file called
"SKIP"
* Run the script ```prerun.sh``` which is generally just used to copy the build
directory between stages.
* In each stage directory loop through each subdirectory and then run each of the
install scripts it contains, again in alphanumeric order. These need to be named
with a two digit padded number at the beginning.
There are a number of different files and directories which can be used to
control different parts of the build process:
2018-03-24 18:10:47 +00:00
- **00-run.sh** - A unix shell script. Needs to be made executable for it to run.
2017-12-15 11:31:40 +00:00
- **00-run-chroot.sh** - A unix shell script which will be run in the chroot
of the image build directory. Needs to be made executable for it to run.
- **00-debconf** - Contents of this file are passed to debconf-set-selections
to configure things like locale, etc.
- **00-packages** - A list of packages to install. Can have more than one, space
separated, per line.
- **00-packages-nr** - As 00-packages, except these will be installed using
2018-03-24 18:10:47 +00:00
the ```--no-install-recommends -y``` parameters to apt-get.
2017-12-15 11:31:40 +00:00
2018-03-24 18:10:47 +00:00
- **00-patches** - A directory containing patch files to be applied, using quilt.
If a file named 'EDIT' is present in the directory, the build process will
be interrupted with a bash session, allowing an opportunity to create/revise
the patches.
2017-12-15 11:31:40 +00:00
* If the stage directory contains files called "EXPORT_NOOBS" or "EXPORT_IMAGE" then
add this stage to a list of images to generate
* Generate the images for any stages that have specified them
It is recommended to examine build.sh for finer details.
2017-01-23 12:44:03 +00:00
## Docker Build
2019-02-17 16:27:43 +00:00
Docker can be used to perform the build inside a container. This partially isolates
the build from the host system, and allows using the script on non-debian based
2020-01-14 21:18:36 +00:00
systems (e.g. Fedora Linux). The isolation is not complete due to the need to use
2019-02-17 16:27:43 +00:00
some kernel level services for arm emulation (binfmt) and loop devices (losetup).
To build:
2017-01-23 12:44:03 +00:00
```bash
vi config # Edit your config file. See above.
./build-docker.sh
```
2017-05-06 23:16:00 +00:00
2017-01-23 12:44:03 +00:00
If everything goes well, your finished image will be in the `deploy/` folder.
2017-05-17 15:36:04 +00:00
You can then remove the build container with `docker rm -v pigen_work`
2016-09-05 04:02:39 +00:00
2017-01-23 12:44:03 +00:00
If something breaks along the line, you can edit the corresponding scripts, and
continue:
2017-02-08 16:10:11 +00:00
2017-05-06 23:16:00 +00:00
```bash
2017-01-23 12:44:03 +00:00
CONTINUE=1 ./build-docker.sh
```
2016-09-05 04:02:39 +00:00
2019-02-17 16:27:43 +00:00
To examine the container after a failure you can enter a shell within it using:
```bash
sudo docker run -it --privileged --volumes-from=pigen_work pi-gen /bin/bash
```
2018-03-05 15:35:11 +00:00
After successful build, the build container is by default removed. This may be undesired when making incremental changes to a customized build. To prevent the build script from remove the container add
```bash
PRESERVE_CONTAINER=1 ./build-docker.sh
```
2017-05-06 23:16:00 +00:00
There is a possibility that even when running from a docker container, the
installation of `qemu-user-static` will silently fail when building the image
because `binfmt-support` _must be enabled on the underlying kernel_ . An easy
fix is to ensure `binfmt-support` is installed on the host machine before
starting the `./build-docker.sh` script (or using your own docker build
solution).
2017-02-08 16:10:11 +00:00
2017-01-23 12:44:03 +00:00
## Stage Anatomy
2016-09-05 04:02:39 +00:00
2017-01-20 17:29:01 +00:00
### Raspbian Stage Overview
2016-09-05 04:02:39 +00:00
The build of Raspbian is divided up into several stages for logical clarity
and modularity. This causes some initial complexity, but it simplifies
2020-01-14 21:18:36 +00:00
maintenance and allows for easier customization.
2016-09-05 04:02:39 +00:00
2017-01-20 17:36:29 +00:00
- **Stage 0** - bootstrap. The primary purpose of this stage is to create a
2016-09-05 04:02:39 +00:00
usable filesystem. This is accomplished largely through the use of
`debootstrap` , which creates a minimal filesystem suitable for use as a
base.tgz on Debian systems. This stage also configures apt settings and
installs `raspberrypi-bootloader` which is missed by debootstrap. The
minimal core is installed but not configured, and the system will not quite
boot yet.
2017-01-20 17:36:29 +00:00
- **Stage 1** - truly minimal system. This stage makes the system bootable by
2016-09-05 04:02:39 +00:00
installing system files like `/etc/fstab` , configures the bootloader, makes
the network operable, and installs packages like raspi-config. At this
stage the system should boot to a local console from which you have the
means to perform basic tasks needed to configure and install the system.
This is as minimal as a system can possibly get, and its arguably not
really usable yet in a traditional sense yet. Still, if you want minimal,
this is minimal and the rest you could reasonably do yourself as sysadmin.
2017-01-20 17:36:29 +00:00
- **Stage 2** - lite system. This stage produces the Raspbian-Lite image. It
2016-09-05 04:02:39 +00:00
installs some optimized memory functions, sets timezone and charmap
defaults, installs fake-hwclock and ntp, wifi and bluetooth support,
dphys-swapfile, and other basics for managing the hardware. It also
creates necessary groups and gives the pi user access to sudo and the
standard console hardware permission groups.
2020-01-14 21:21:28 +00:00
There are a few development tools here that may not make a whole lot
of sense on a minimal system. These tools include basic Python and Lua
2016-09-05 04:02:39 +00:00
packages as well as the `build-essential` package. They are lumped right
in with more essential packages presently, though they need not be with
2020-01-14 21:21:28 +00:00
pi-gen. They are understandable for Raspbian's target audience, but if
2017-07-27 10:11:07 +00:00
you were looking for something between truly minimal and Raspbian-Lite,
2016-09-05 04:02:39 +00:00
here's where you start trimming.
2017-01-20 17:36:29 +00:00
- **Stage 3** - desktop system. Here's where you get the full desktop system
2016-09-05 04:02:39 +00:00
with X11 and LXDE, web browsers, git for development, Raspbian custom UI
enhancements, etc. This is a base desktop system, with some development
tools installed.
2019-12-09 11:57:26 +00:00
- **Stage 4** - Normal Raspbian image. System meant to fit on a 4GB card. This is the
stage that installs most things that make Raspbian friendly to new
users like system documentation.
2017-06-27 12:16:41 +00:00
2019-12-09 11:57:26 +00:00
- **Stage 5** - The Raspbian Full image. More development
tools, an email client, learning tools like Scratch, specialized packages
2020-01-14 21:21:28 +00:00
like sonic-pi, office productivity, etc.
2017-05-06 23:16:00 +00:00
2017-01-20 17:36:29 +00:00
### Stage specification
2017-05-06 23:16:00 +00:00
If you wish to build up to a specified stage (such as building up to stage 2
for a lite system), place an empty file named `SKIP` in each of the `./stage`
directories you wish not to include.
2017-01-20 17:36:29 +00:00
2019-11-27 16:11:20 +00:00
Then add an empty file named `SKIP_IMAGES` to `./stage4` and `./stage5` (if building up to stage 2) or
2018-03-13 10:20:22 +00:00
to `./stage2` (if building a minimal system).
2017-05-06 23:16:00 +00:00
```bash
2017-01-20 17:36:29 +00:00
# Example for building a lite system
2017-05-17 11:27:57 +00:00
echo "IMG_NAME='Raspbian'" > config
touch ./stage3/SKIP ./stage4/SKIP ./stage5/SKIP
2018-03-13 10:20:22 +00:00
touch ./stage4/SKIP_IMAGES ./stage5/SKIP_IMAGES
2017-05-17 11:27:57 +00:00
sudo ./build.sh # or ./build-docker.sh
2017-01-23 12:44:03 +00:00
```
2017-05-06 23:16:00 +00:00
If you wish to build further configurations upon (for example) the lite
system, you can also delete the contents of `./stage3` and `./stage4` and
replace with your own contents in the same format.
2017-12-15 11:31:40 +00:00
## Skipping stages to speed up development
If you're working on a specific stage the recommended development process is as
follows:
2018-01-03 12:48:31 +00:00
* Add a file called SKIP_IMAGES into the directories containing EXPORT_* files
(currently stage2, stage4 and stage5)
2017-12-15 11:31:40 +00:00
* Add SKIP files to the stages you don't want to build. For example, if you're
basing your image on the lite image you would add these to stages 3, 4 and 5.
* Run build.sh to build all stages
* Add SKIP files to the earlier successfully built stages
* Modify the last stage
* Rebuild just the last stage using ```sudo CLEAN=1 ./build.sh```
2018-01-03 12:48:31 +00:00
* Once you're happy with the image you can remove the SKIP_IMAGES files and
2017-12-15 11:31:40 +00:00
export your image to test
2018-08-03 08:08:25 +00:00
# Troubleshooting
2019-06-28 11:40:06 +00:00
## `64 Bit Systems`
Please note there is currently an issue when compiling with a 64 Bit OS. See https://github.com/RPi-Distro/pi-gen/issues/271
2018-08-03 08:08:25 +00:00
## `binfmt_misc`
Linux is able execute binaries from other architectures, meaning that it should be
possible to make use of `pi-gen` on an x86_64 system, even though it will be running
ARM binaries. This requires support from the [`binfmt_misc` ](https://en.wikipedia.org/wiki/Binfmt_misc )
kernel module.
You may see the following error:
```
update-binfmts: warning: Couldn't load the binfmt_misc module.
```
To resolve this, ensure that the following files are available (install them if necessary):
```
/lib/modules/$(uname -r)/kernel/fs/binfmt_misc.ko
/usr/bin/qemu-arm-static
```
You may also need to load the module by hand - run `modprobe binfmt_misc` .