-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 040241f
Showing
10 changed files
with
467 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
A framework for generating raspberryPi rootfs trees. | ||
|
||
SOME ASSEMBLY REQUIRED. BATTERIES NOT INCLUDED. | ||
|
||
I AM NOT RESPONSIBLE IF THESE SCRIPTS WIPE YOUR MACHINE, SET FIRE TO | ||
YOUR HOUSE, EMAIL YOUR BANKING PASSWORD TO CRIMINAL GANGS OR PRECIPITATE | ||
GLOBAL THERMONUCLEAR WAR. | ||
|
||
Given that you will need to run some of these scripts under sudo, the | ||
first is a distinctly non-zero possibility. If you are worried about | ||
this, you could probably build yourself a basic ubuntu VM to run this in | ||
so you don't hose stuff if things go wrong. | ||
|
||
WHAT YOU WILL NEED: | ||
|
||
* A machine running a debian derivative (eg debian itself, ubuntu, etc). | ||
|
||
* A recent version of multistrap. | ||
At time of writing, ubuntu ships 2.1.6ubuntu3 which is too old. | ||
I installed 2.1.20 from debian; it is pretty much a standalone | ||
package so this is reasonably safe. | ||
|
||
* A qemu-static binary appropriate for your target architecture. | ||
Which I'm assuming is a raspberry Pi, but could be anything. | ||
Ideally, it would match exactly. In practice, | ||
/usr/bin/qemu-arm-static on my ubuntu system is armv7, but | ||
everything still seems to work OK. I suspect it is possible | ||
that some packages which compile stuff at install time | ||
might generate code that wouldn't actually run on the pi, | ||
but I haven't hit that in my experiments. If someone could build | ||
a qemu static binary which more closely matches the pi, that | ||
would be cool. | ||
|
||
* An SD card (assuming a Pi) | ||
|
||
HOW TO USE IT | ||
|
||
To get started, customize the list of packages in the [raspbian] section | ||
of multistrap.conf, check all the points marked "FIXME" in | ||
configscript.sh, and run something like: | ||
|
||
sudo multistrap -a armhf -d pi-root-tree -f multistrap.conf | ||
|
||
(where pi-root-tree is the name of the target directory, which ideally | ||
should be non-existant or empty). | ||
|
||
A few minutes later (about 5 on my machine), it will finish, hopefully | ||
with no errors. You will now have a directory tree under the target | ||
directory which looks like the filesystem of a raspberry pi. | ||
|
||
Now you need to format your SD card appropriately and mount it | ||
somewhere. My example configscript.sh assumes that your card has a vfat | ||
partition 1, swap space on partition 2, and everything else in an ext4 | ||
partition 3. Partition your card with fdisk, create appropriate | ||
filesystems on the first and third partitions, mkswap the second one. | ||
Now mount the third partition somewhere (eg /mnt), create the boot | ||
directory (eg mkdir /mnt/boot), and then mount the first partition on | ||
that point. Now do something like: | ||
sudo rsync -nav --delete --numeric-ids --exclude=lost+found --modify-window=1 pi-root-tree/ /mnt/ | ||
|
||
Unmount the card (you'll need to umount /mnt/boot before /mnt), remove | ||
it from the host machine and plug it into the Pi - and hopefully it will | ||
boot. | ||
|
||
In theory you could avoid the rsync step by mounting up your SD card as | ||
above before building the tree, and then running multistrap with the | ||
root of the SD card as the target directory, but this will involve doing | ||
a lot of IO to the SD card, so this will probably be extremely slow. | ||
|
||
Of course, if you are building this for something other then a raspberry | ||
Pi, you'll need to know how to convert this directory tree into a root | ||
fs image for whatever you are targeting. | ||
|
||
HOW IT WORKS: | ||
|
||
Multistrap is the engine that drives most of this. | ||
|
||
The multistrap.conf file contains enough to build a very basic install | ||
for a pi. | ||
|
||
The [General] section at the top has a couple of keywords worth looking | ||
at. | ||
|
||
debconfseed=preseed | ||
This causes the file called 'preseed' to get copied into | ||
/tmp/preseeds under the chroot, and used to answer config questions with | ||
predefined values rather than interactive prompts. The included example | ||
sets the timezone, the default locale, and says to use /bin/dash as | ||
/bin/sh. If you include other packages which need configuration you may | ||
need to add stuff to this file. | ||
|
||
configscript=configscript.sh | ||
This causes the file 'configscript.sh' to get copied into the | ||
chroot. We execute this in chroot context from a hook later. | ||
|
||
hookdir=zzz-hooks | ||
This points to a directory containing hook scripts which get | ||
executed at various points. We use one of these to execute the | ||
configscript.sh later. | ||
|
||
The [raspbian] and [pi] sections define sets of packages to be | ||
installed. All packages defined as 'required' will be installed anyway. | ||
You could in fact remove all the packages= lines under the | ||
[raspbian] section and get an even more stripped out image, but that | ||
would remove, for example, networking. However you should definitely | ||
review these packages lines to add tools you like to always have | ||
available or remove any you know you wouldn't use (eg wpasupplicant, | ||
wireless tools and iw if you never expect to be using wifi for | ||
networking). | ||
|
||
The configscript.sh file is run in chroot context under qemu after the | ||
packages are unpacked by multistrap (and after any other hook scripts | ||
defined in other multistrap configuration files). Quite a few things | ||
will probably need fixing in there for your environment; look for the | ||
string "FIXME" to see where I think you'll need to look at it. | ||
Near the bottom, it runs any other scripts found in /tmp/hook-scripts; | ||
so other variants (see below) can simply put scripts here in the chroot | ||
for them to be executed in chroot context later. | ||
Finally there's a section which removes the temporary stuff, including | ||
configscript.sh itself and the qemu binary. | ||
|
||
zzz-hooks/completion-zzz-final-hook.sh is the script which actually does | ||
the qemu work. | ||
|
||
multistrap-mpd.conf is an example of a cascaded multistrap configuration | ||
which extends the base system built by the multistrap.conf above. The | ||
[General] section has an 'include=multistrap.conf' line which causes it | ||
to pick up the base stuff. It defines its own hookdir with some | ||
additional scripts, and an extra package section where it installs more | ||
packages (note that the source, suite and omitdebsrc lines are the same | ||
as the [raspbian] section in the main file). | ||
|
||
mpd-hooks/completion-copy-wolfson-kernel.sh copies a tarball of the | ||
custom kernel needed for the wolfson audio card into the chroot | ||
|
||
mpd-hooks/completion-create-scripts.sh mostly just creates a script | ||
under /tmp/hook-scripts in the chroot, which will get executed near the | ||
bottom of configscript.sh. | ||
|
||
mpd-hooks/completion-patch-base-files-postinst.sh corrects an issue in | ||
the postinst of the base-files package which breaks things if packages | ||
create new directories under /var/run (which mpd does). | ||
|
||
If for some reason you want to get into the chroot and do something | ||
after multistrap has finished running (eg install an extra package you | ||
forgot), just copy qemu-arm-static into /usr/bin under the chroot, and | ||
chroot into it. You'll probably need to create an /etc/resolv.conf if | ||
you want to install anything, and if it is a daemon you would probably | ||
want to do the trick with the fake scripts at the top of configscript.sh | ||
so you don't end up with the daemon being started under qemu in the | ||
chroot! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- base-files-6.5ubuntu3/debian/postinst.in 2011-07-13 17:20:35.000000000 -0300 | ||
+++ helio-base/debian/postinst.in 2012-01-23 15:07:18.150498042 -0200 | ||
@@ -25,6 +25,13 @@ | ||
|
||
migrate_directory() { | ||
if [ ! -L $1 ]; then | ||
+ if [ ! -z "`ls -A $1/`" ]; then | ||
+ for x in $1/* $1/.[!.]* $1/..?*; do | ||
+ if [ -e "$x" ]; then | ||
+ mv -- "$x" $2/ | ||
+ fi | ||
+ done | ||
+ fi | ||
rmdir $1 | ||
ln -s $2 $1 | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
#!/bin/bash | ||
|
||
# This script will be run in chroot context probably under qemu. | ||
|
||
# FIXME Variables you can mess with | ||
HOSTNAME=pi-base | ||
MYUSERNAME=myuser | ||
|
||
|
||
export LC_ALL=C LANGUAGE=C LANG=C | ||
export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true | ||
|
||
# This stops things trying to start daemons inside the chroot. | ||
mkdir /tmp/fake | ||
for i in initctl invoke-rc.d restart start stop start-stop-daemon service | ||
do | ||
ln -s /bin/true /tmp/fake/$i | ||
done | ||
export PATH=/tmp/fake:$PATH | ||
cat > /etc/resolv.conf <<EOF | ||
# FIXME | ||
# Contents of a valid resolv.conf file here | ||
# This is only used during the build process | ||
# and is removed in the cleanup phase at the end; | ||
# it is assumed dhcp will configure this at runtime. | ||
# For static IP, put the right bits here and fix the | ||
# cleanup section at the end of the file | ||
EOF | ||
|
||
# FIXME replace with your syslog host | ||
sed -i 's/^SYSLOG_OPTS=.*$/SYSLOG_OPTS="-R syslog.my.domain"/' /etc/default/busybox-syslogd | ||
|
||
# Dash needs special handling | ||
/var/lib/dpkg/info/dash.preinst install | ||
|
||
# Preseed files can pre-configure packages. | ||
if [ -d /tmp/preseeds/ ]; then | ||
for file in `ls -1 /tmp/preseeds/*`; do | ||
debconf-set-selections $file | ||
done | ||
fi | ||
|
||
# Actually configure the unpackage packages | ||
dpkg --configure -a | ||
|
||
ln -s /proc/mounts /etc/mtab | ||
|
||
# FIXME you may need to change the root location and fstab contents if you format your SD card differently | ||
echo 'dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p3 rootfstype=ext4 rootwait' > /boot/cmdline.txt | ||
|
||
cat > /etc/fstab << EOF | ||
/dev/mmcblk0p3 / ext4 errors=remount-ro,noatime 0 1 | ||
/dev/mmcblk0p1 /boot vfat utf8 0 2 | ||
/dev/mmcblk0p2 none swap sw 0 0 | ||
tmpfs /tmp tmpfs mode=1777,size=25%,noatime 0 0 | ||
EOF | ||
|
||
# FIXME this should be the hash of the desired root password | ||
echo 'root:$6$XXXXXXXX$YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY' | chpasswd -e | ||
|
||
# FIXME with an appropriate hashed password for your non-root account | ||
# You may also want to tailor the set of groups | ||
groupadd ${MYUSERNAME} | ||
useradd -c "My Name" -d /home/${MYUSERNAME} -m -g ${MYUSERNAME} -G adm,dialout,cdrom,floppy,audio,dip,video,plugdev -s /bin/bash -p '$6$ZZZZZZZZ$WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' ${MYUSERNAME} | ||
|
||
# FIXME put your SSH public key here if you want | ||
mkdir /home/${MYUSERNAME}/.ssh | ||
cat > /home/${MYUSERNAME}/.ssh/authorized_keys << EOF | ||
ssh-dss stuff........ | ||
EOF | ||
|
||
# FIXME grant yourself sudo access | ||
echo "${MYUSERNAME} ALL=(ALL) ALL" >> /etc/sudoers | ||
|
||
|
||
# This adds the key 7FA3303E: public key "Raspberry Pi Archive Signing Key" | ||
# Needed for archive.raspberrypi.org/debian repo which doesn't seem to have | ||
# a keyring package | ||
apt-key add - << EOF | ||
-----BEGIN PGP PUBLIC KEY BLOCK----- | ||
Version: GnuPG v1.4.12 (GNU/Linux) | ||
mQENBE/d7o8BCACrwqQacGJfn3tnMzGui6mv2lLxYbsOuy/+U4rqMmGEuo3h9m92 | ||
30E2EtypsoWczkBretzLUCFv+VUOxaA6sV9+puTqYGhhQZFuKUWcG7orf7QbZRuu | ||
TxsEUepW5lg7MExmAu1JJzqM0kMQX8fVyWVDkjchZ/is4q3BPOUCJbUJOsE+kK/6 | ||
8kW6nWdhwSAjfDh06bA5wvoXNjYoDdnSZyVdcYCPEJXEg5jfF/+nmiFKMZBraHwn | ||
eQsepr7rBXxNcEvDlSOPal11fg90KXpy7Umre1UcAZYJdQeWcHu7X5uoJx/MG5J8 | ||
ic6CwYmDaShIFa92f8qmFcna05+lppk76fsnABEBAAG0IFJhc3BiZXJyeSBQaSBB | ||
cmNoaXZlIFNpZ25pbmcgS2V5iQE4BBMBAgAiBQJP3e6PAhsDBgsJCAcDAgYVCAIJ | ||
CgsEFgIDAQIeAQIXgAAKCRCCsSmSf6MwPk6vB/9pePB3IukU9WC9Bammh3mpQTvL | ||
OifbkzHkmAYxzjfK6D2I8pT0xMxy949+ThzJ7uL60p6T/32ED9DR3LHIMXZvKtuc | ||
mQnSiNDX03E2p7lIP/htoxW2hDP2n8cdlNdt0M9IjaWBppsbO7IrDppG2B1aRLni | ||
uD7v8bHRL2mKTtIDLX42Enl8aLAkJYgNWpZyPkDyOqamjijarIWjGEPCkaURF7g4 | ||
d44HvYhpbLMOrz1m6N5Bzoa5+nq3lmifeiWKxioFXU+Hy5bhtAM6ljVb59hbD2ra | ||
X4+3LXC9oox2flmQnyqwoyfZqVgSQa0B41qEQo8t1bz6Q1Ti7fbMLThmbRHiuQEN | ||
BE/d7o8BCADNlVtBZU63fm79SjHh5AEKFs0C3kwa0mOhp9oas/haDggmhiXdzeD3 | ||
49JWz9ZTx+vlTq0s+I+nIR1a+q+GL+hxYt4HhxoA6vlDMegVfvZKzqTX9Nr2VqQa | ||
S4Kz3W5ULv81tw3WowK6i0L7pqDmvDqgm73mMbbxfHD0SyTt8+fk7qX6Ag2pZ4a9 | ||
ZdJGxvASkh0McGpbYJhk1WYD+eh4fqH3IaeJi6xtNoRdc5YXuzILnp+KaJyPE5CR | ||
qUY5JibOD3qR7zDjP0ueP93jLqmoKltCdN5+yYEExtSwz5lXniiYOJp8LWFCgv5h | ||
m8aYXkcJS1xVV9Ltno23YvX5edw9QY4hABEBAAGJAR8EGAECAAkFAk/d7o8CGwwA | ||
CgkQgrEpkn+jMD5Figf/dIC1qtDMTbu5IsI5uZPX63xydaExQNYf98cq5H2fWF6O | ||
yVR7ERzA2w33hI0yZQrqO6pU9SRnHRxCFvGv6y+mXXXMRcmjZG7GiD6tQWeN/3wb | ||
EbAn5cg6CJ/Lk/BI4iRRfBX07LbYULCohlGkwBOkRo10T+Ld4vCCnBftCh5x2OtZ | ||
TOWRULxP36y2PLGVNF+q9pho98qx+RIxvpofQM/842ZycjPJvzgVQsW4LT91KYAE | ||
4TVf6JjwUM6HZDoiNcX6d7zOhNfQihXTsniZZ6rky287htsWVDNkqOi5T3oTxWUo | ||
m++/7s3K3L0zWopdhMVcgg6Nt9gcjzqN1c0gy55L/g== | ||
=mNSj | ||
-----END PGP PUBLIC KEY BLOCK----- | ||
EOF | ||
|
||
chown -R ${MYUSERNAME}: /home/${MYUSERNAME}/.ssh | ||
chmod -R go= /home/${MYUSERNAME}/.ssh | ||
|
||
# FIXME you'll want to change the wlan config | ||
cat > /etc/network/interfaces << EOF | ||
# interfaces(5) file used by ifup(8) and ifdown(8) | ||
auto lo | ||
iface lo inet loopback | ||
allow-hotplug eth0 | ||
iface eth0 inet dhcp | ||
allow-hotplug wlan0 | ||
iface wlan0 inet dhcp | ||
wpa-ssid MY-SSID | ||
wpa-psk MY-PSK-PASSWORD | ||
EOF | ||
chmod 600 /etc/network/interfaces | ||
|
||
echo $HOSTNAME > /etc/hostname | ||
|
||
# This is a hack. I'm not sure why, but on the initial unpack/configure | ||
# /boot ends up empty; this solves the issue. | ||
apt-get -y update < /dev/null | ||
apt-get -y install --reinstall raspberrypi-bootloader < /dev/null | ||
|
||
# Run the other bits | ||
run-parts -v /tmp/hook-scripts | ||
|
||
# cleanup | ||
apt-get clean | ||
rm /etc/resolv.conf | ||
rm -rf /tmp/* | ||
exec rm /configscript.sh /usr/bin/qemu-arm-static |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/bin/bash | ||
|
||
# This one simply copies tar balls of the wolfson kernel and scripts into place in the chroot | ||
cp ~/pi-roots/wolfson-kernel.tar ~/pi-roots/wolfson-scripts.tar $1/tmp/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#!/bin/bash | ||
|
||
# This runs in host context. | ||
# I just create a script which will be run later in chroot context. | ||
# This then does various things including unpacking the wolfson | ||
# tarballs we placed in the chroot earlier | ||
|
||
TDIR=$1 | ||
mkdir -p $TDIR/tmp/hook-scripts | ||
cat > $TDIR/tmp/hook-scripts/mpd << EOF | ||
#!/bin/bash | ||
# FIXME where is your audio stash? | ||
cat >> /etc/fstab << EO2F | ||
server:/audio /var/lib/mpd/music nfs ro,nolock,bg 0 0 | ||
server:/playlists /var/lib/mpd/playlists nfs ro,nolock,bg 0 0 | ||
EO2F | ||
# I used a hacked kernel to handle the wolfson audio card | ||
rm -rf /lib/modules /lib/firmware /boot/kernel.img | ||
tar xCvf / /tmp/wolfson-kernel.tar | ||
tar xCvf / /tmp/wolfson-scripts.tar | ||
# Modified mpd.conf. Note this puts the state file in /var/run | ||
# which means it won't persist over reboots, this may not be what | ||
# you want (default is /var/lib/mpd/state). | ||
cat > /etc/mpd.conf << EO2F | ||
music_directory "/var/lib/mpd/music" | ||
playlist_directory "/var/lib/mpd/playlists" | ||
db_file "/var/lib/mpd/tag_cache" | ||
log_file "syslog" | ||
pid_file "/var/run/mpd/pid" | ||
state_file "/var/run/mpd/state" | ||
sticker_file "/var/lib/mpd/sticker.sql" | ||
zeroconf_name "Unnamed Music Player" | ||
user "mpd" | ||
input { | ||
plugin "curl" | ||
} | ||
audio_output { | ||
type "alsa" | ||
name "My ALSA Device" | ||
device "hw:0,0" # optional | ||
mixer_device "default" # optional | ||
mixer_control "HPOUT2 Digital" # optional | ||
mixer_index "0" # optional | ||
} | ||
filesystem_charset "UTF-8" | ||
id3v1_encoding "UTF-8" | ||
EO2F | ||
# This is some stuff I run on startup to clear any mpd state, | ||
# configure the audio card, and set the volume to something sane. | ||
# First we remove the "exit 0" at the end of the file | ||
sed -i 's/^exit 0$//' /etc/rc.local | ||
# Then add our stuff | ||
cat >> /etc/rc.local << EO2F | ||
mpc clear | ||
mpc update | ||
/usr/local/bin/Reset_paths.sh | ||
/usr/local/bin/Playback_to_Lineout.sh | ||
mpc volume 40 | ||
EO2F | ||
# Customize the hostname appropriately | ||
echo "test-mpd" > /etc/hostname | ||
EOF | ||
|
||
chmod 755 $TDIR/tmp/hook-scripts/mpd |
Oops, something went wrong.