-
Notifications
You must be signed in to change notification settings - Fork 495
FBTFT shield image build process
This is the receipe used to build the custom FBTFT image for shields.
The first part is done on the Raspberry Pi itself.
Start with a fresh image: 2014-01-07-wheezy-raspbian
List of things to fix in the next release.
- Remove bash_history
sudo rm /media/rootfs/root/.bash_history
Expand root file system size.
sudo raspi-config
# Expand Filesystem
Packages
sudo apt-get update && sudo apt-get -y install zip kpartx cmake
Update rpi-update
sudo wget https://raw.github.com/Hexxeh/rpi-update/master/rpi-update -O /usr/bin/rpi-update && sudo chmod +x /usr/bin/rpi-update
Set variables
IMAGE=2014-01-07-wheezy-raspbian
FBTFT=2014-02-03-fbtft
Get and prepare image
cd && scp pi@192.168.10.92:/home/pi/images/$IMAGE.zip .
unzip $IMAGE.zip && mv $IMAGE.img $IMAGE-$FBTFT.img
Mount image partitions
sudo mkdir -p /media/{bootfs,rootfs}
sudo losetup /dev/loop0 $IMAGE-$FBTFT.img
sudo kpartx -a /dev/loop0
sudo mount /dev/mapper/loop0p1 /media/bootfs
sudo mount /dev/mapper/loop0p2 /media/rootfs
Expand filesystem on first boot if /boot/expand_rootfs exists
Don't start raspi-config on the console (doesn't fit small displays)
cat <<EOF | sudo tee /media/bootfs/expand_rootfs
Delete this file to prevent filesystem expansion on first boot
EOF
cat <<EOF | sudo tee /media/rootfs/etc/profile.d/raspi-config.sh
rm -f /etc/profile.d/raspi-config.sh
if [ ! -e /boot/expand_rootfs ]; then
exit 0
fi
printf "Expanding filesystem...\n\n"
rm -f /boot/expand_rootfs
raspi-config --expand-rootfs
sed -i /etc/inittab \
-e "s/^#\(.*\)#\s*RPICFG_TO_ENABLE\s*/\1/" \
-e "/#\s*RPICFG_TO_DISABLE/d"
telinit q
sync
reboot
EOF
Update rpi-update
sudo cp -a /usr/bin/rpi-update /media/rootfs/usr/bin/rpi-update
Set evironment variables for rpi-update
cat <<EOF | sudo tee /media/rootfs/etc/profile.d/rpi-update.sh
export REPO_URI=https://github.com/notro/rpi-firmware
export BRANCH=builtin
EOF
# Let the environment variables pass through when using sudo
cat <<EOF | sudo tee /media/rootfs/etc/sudoers.d/rpi-update
Defaults env_keep += "REPO_URI BRANCH"
EOF
sudo chmod 0440 /media/rootfs/etc/sudoers.d/rpi-update
Install kernel and modules.
sudo rm -rf /media/rootfs/lib/modules/*
sudo BRANCH=builtin UPDATE_SELF=0 ROOT_PATH=/media/rootfs BOOT_PATH=/media/bootfs WORK_PATH=~/rpi-firmware REPO_URI=https://github.com/notro/rpi-firmware rpi-update
# /boot/.firmware_revision and /root/.rpi-firmware/bootcode.bin is needed to determine if a update is needed
sudo mkdir /media/rootfs/root/.rpi-firmware && sudo touch /media/rootfs/root/.rpi-firmware/bootcode.bin
sudo rm -rf /media/bootfs.bak /media/rootfs/lib/modules.bak
Install fbcp
cd && git clone https://github.com/tasanakorn/rpi-fbcp
mkdir -p rpi-fbcp/build && cd rpi-fbcp/build
cmake .. && make
sudo install fbcp /media/rootfs/usr/local/bin/fbcp
fbcp service
sudo nano /media/rootfs/etc/init.d/fbcp
content
#!/bin/sh
### BEGIN INIT INFO
# Provides: fbcp
# Required-Start: $local_fs $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Framebuffer copy daemon fb0->fb1
### END INIT INFO
# Author: Noralf Tronnes <notro@tronnes.org>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Framebuffer copy daemon"
NAME=fbcp
DAEMON=/usr/local/bin/fbcp
DAEMON_ARGS=""
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x $DAEMON ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
rm -f $PIDFILE
return "$RETVAL"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
restart|reload|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2
exit 3
;;
esac
:
Make script executable
sudo chmod +x /media/rootfs/etc/init.d/fbcp
Add gpio utility
cd && git clone git://git.drogon.net/wiringPi
cd wiringPi
cd wiringPi && make && sudo make install
cd ../devLib && make && sudo make install
cd ../gpio && make && sudo make install
DESTDIR=/media/rootfs
PREFIX=/usr/local
cd ..
cd wiringPi && sudo make DESTDIR=${DESTDIR} PREFIX=${PREFIX} install
cd ../devLib && sudo make DESTDIR=${DESTDIR} PREFIX=${PREFIX} install
cd ../gpio && sudo make DESTDIR=${DESTDIR} PREFIX=${PREFIX} install
sudo ldconfig -r /media/rootfs
Install xinput_calibrator
sudo apt-get -y install autoconf libx11-dev libxext-dev libxi-dev x11proto-input-dev
cd && git clone https://github.com/tias/xinput_calibrator
cd xinput_calibrator
# First run fails: configure.ac:34: error: possibly undefined macro: AC_PROG_LIBTOOL
./autogen.sh -h
./autogen.sh --prefix=/media/rootfs && make && sudo make install
Install packages
sudo chroot /media/rootfs
mount -t proc none /proc/ && mount -t sysfs none /sys/
apt-get update && apt-get -y install \
tslib libts-bin evtest \
xinput \
python-pip
# Ignore this: Can not write log, openpty() failed (/dev/pts not mounted?)
# Disable this package as it contains a kernel, and thus removes the FBTFT drivers
apt-mark hold raspberrypi-bootloader
# clean up
apt-get clean && apt-get autoremove
rm -rf /tmp/*
umount /proc && umount /sys
exit
Fix X windows issue
sudo nano /media/rootfs/usr/share/X11/xorg.conf.d/99-fbturbo.conf
disable fbdev option
# Option "fbdev" "/dev/fb0"
Let startx by default come up on /dev/fb1
cat <<EOF | sudo tee /media/rootfs/etc/profile.d/startx_fb1.sh
export FRAMEBUFFER=/dev/fb1
EOF
cat <<EOF | sudo tee /media/rootfs/etc/sudoers.d/startx
Defaults env_keep += "FRAMEBUFFER"
EOF
sudo chmod 0440 /media/rootfs/etc/sudoers.d/startx
Add udev symlink rule: /dev/input/touchscreen
cat <<EOF | sudo tee /media/rootfs/etc/udev/rules.d/95-ads7846.rules
SUBSYSTEM=="input", KERNEL=="event[0-9]*", ATTRS{name}=="ADS7846*", SYMLINK+="input/touchscreen"
EOF
Set tslib environment variables
cat <<EOF | sudo tee /media/rootfs/etc/profile.d/tslib.sh
export TSLIB_TSDEVICE=/dev/input/touchscreen
export TSLIB_FBDEVICE=/dev/fb1
EOF
cat <<EOF | sudo tee /media/rootfs/etc/sudoers.d/tslib
Defaults env_keep += "TSLIB_TSDEVICE TSLIB_FBDEVICE"
EOF
sudo chmod 0440 /media/rootfs/etc/sudoers.d/tslib
Set SDL environment variables
cat <<EOF | sudo tee /media/rootfs/etc/profile.d/sdl.sh
export SDL_VIDEODRIVER=fbcon
export SDL_FBDEV=/dev/fb1
export SDL_MOUSEDRV=TSLIB
export SDL_MOUSEDEV=/dev/input/touchscreen
EOF
cat <<EOF | sudo tee /media/rootfs/etc/sudoers.d/sdl
Defaults env_keep += "SDL_VIDEODRIVER SDL_FBDEV SDL_MOUSEDRV SDL_MOUSEDEV"
EOF
sudo chmod 0440 /media/rootfs/etc/sudoers.d/sdl
Touch calibration startup script (X windows)
sudo wget -O /media/rootfs/etc/X11/Xsession.d/xinput_calibrator_pointercal https://raw.github.com/tias/xinput_calibrator/master/scripts/xinput_calibrator_pointercal.sh
cat <<EOF | sudo tee -a /media/rootfs/etc/xdg/lxsession/LXDE/autostart
sudo /bin/sh /etc/X11/Xsession.d/xinput_calibrator_pointercal
EOF
Unmount partitions
sudo umount /media/bootfs
sudo umount /media/rootfs
sudo kpartx -d /dev/loop0
sudo losetup -d /dev/loop0
Push the image to a faster machine
cd && scp $IMAGE-$FBTFT.img pi@192.168.10.92:/home/pi/images
This is done on a faster machine
Prepare
cd ~/images
mkdir -p {bootfs,rootfs}
Build the various images
sudo ./stage2 <image produced further up>
Script: stage2
#!/bin/bash
set -e
function mount_image {
losetup /dev/loop0 $1
kpartx -a /dev/loop0
mount /dev/mapper/loop0p1 bootfs
mount /dev/mapper/loop0p2 rootfs
}
function umount_image {
umount bootfs
umount rootfs
kpartx -d /dev/loop0
losetup -d /dev/loop0
}
# make_image SRC SHIELD KCMD MOD
function make_image {
echo
echo
echo Shield: $2
echo Source: $1
dst=$(basename $1 .img)-$2.img
echo Destination: $dst
echo Add to kernel command line: $3
echo Add to /etc/modules: $4
echo Copy image
sudo -u pi cp -v $1 $dst
echo Mount image
mount_image $dst
curr=$(cat bootfs/cmdline.txt)
echo "${curr} ${3}" > bootfs/cmdline.txt
echo -e $4 >> rootfs/etc/modules
echo umount image
umount_image
echo Zip up image
sudo -u pi zip -v $(basename $dst .img).zip $dst
# rm $dst
}
SRC=$1
make_image $SRC \
builtin \
"fbtft_device.name=list fbtft_device.rotate=0 fbtft_device.debug=0 fbtft_device.verbose=0" \
""
# DMA doesn't with RPi-Display because fbtft_write_spi_emulate_9() doesn't support DMA
make_image $SRC \
RPi-Display \
"fbtft_device.name=mi0283qt-9a fbtft_device.rotate=270 fbtft_device.gpios=reset:23,led:18 fbtft_device.debug=0 fbtft_device.verbose=0 fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo" \
"ads7846_device swap_xy=1 model=7846 cs=1 speed=2000000 gpio_pendown=25 pressure_max=255 x_plate_ohms=60"
make_image $SRC \
hy28a \
"fbtft.dma fbtft_device.name=hy28a fbtft_device.rotate=270 fbtft_device.speed=48000000 fbtft_device.fps=50 fbtft_device.debug=0 fbtft_device.verbose=0 fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo" \
"ads7846_device swap_xy=1 gpio_pendown=17 x_plate_ohms=100 pressure_max=255"
make_image $SRC \
hy28b \
"fbtft.dma fbtft_device.name=hy28b fbtft_device.rotate=90 fbtft_device.speed=48000000 fbtft_device.fps=50 fbtft_device.debug=0 fbtft_device.verbose=0 fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo" \
"ads7846_device swap_xy=1 gpio_pendown=17 x_plate_ohms=100 pressure_max=255"
make_image $SRC \
tinylcd35 \
"fbtft.dma fbtft_device.name=tinylcd35 fbtft_device.rotate=270 fbtft_device.speed=48000000 fbtft_device.fps=50 fbtft_device.debug=0 fbtft_device.verbose=0 fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo" \
"gpio_mouse_device pulldown polarity=0 up=17 down=22 left=27 right=23 bleft=4"