-
Notifications
You must be signed in to change notification settings - Fork 9
Home
Discontinued
2015-02-11
I haven't got the time to maintain this anymore. If anyone want's to pick it up, please do.
rpi-build is a tool to build, install and release Linux kernels for the Raspberry Pi.
This can be done on the Raspberry Pi itself, or on another build machine.
rpi-update<
8000
/a> is used to install the resulting kernel.
The resulting firmware can be installed directly from the build directory, or from github like the official Raspberry Pi kernel.
sudo wget https://raw.githubusercontent.com/notro/rpi-build/master/rpi-build -O /usr/bin/rpi-build && sudo chmod +x /usr/bin/rpi-build
# the first run checks dependencies and installs all files
$ rpi-build
Missing dependencies:
- bc
- ncurses library (used by make menuconfig)
- sshpass
sudo apt-get --yes install bc libncurses5-dev sshpass
Install dependencies? [Y/n]
[...]
The following NEW packages will be installed:
bc libncurses5-dev libtinfo-dev sshpass
[...]
Installing rpi-build to /home/pi/rpi-build:
[...]
$ rpi-build [option tasks] release target
The libraries are a good place to see how to make packages
- Standard library
-
FBTFT library
rpi-build admin addlib[notro/fbtft-build]
Output and logs are filtered to highlight important commands.
This takes ~3.5 hours
I'm not sure if video works though. I used a serial console. There is USB and networking support now.
(more)
$ rpi-build use[stdlib] linux install
Workdir: /home/pi/workdir
mkdir: created directory `/home/pi/workdir'
mkdir: created directory `/home/pi/rpi-build/downloads'
(in /home/pi/rpi-build/stdlib)
KERNEL_ORG_VERSION = 3.15
Release: linux
Package: issue106
Package: raspberrypi_tools
Package: raspberrypi_firmware
Package: uboot_bcm2835
Package: uboot_arm
Package: kernelorg_linux
wget --progress=dot:mega -O '/home/pi/rpi-build/downloads/raspberrypi-firmware-b0fc17c2368ec1db930fa8c62ee1c2b8e0b87706.tar.gz' 'https://github.com/raspberrypi/firmware/archive/b0fc17c2368ec1db930fa8c62ee1c2b8e0b87706.tar.gz'
wget --progress=dot:mega -O '/home/pi/rpi-build/downloads/git.denx.de--p-u-boot-u-boot-arm.git-0a26e1d6c394aacbf1153977b7348d1dff85db3f.tar.bz2' 'http://git.denx.de/?p=u-boot/u-boot-arm.git;a=snapshot;h=0a26e1d6c394aacbf1153977b7348d1dff85db3f;sf=tbz2'
wget --progress=dot:mega -O '/home/pi/rpi-build/downloads/linux-3.15.tar.xz' 'https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.15.tar.xz'
Target 'fetch' done
tar -x --checkpoint=100 --checkpoint-action=dot -C /home/pi/workdir -f /home/pi/rpi-build/downloads/raspberrypi-firmware-b0fc17c2368ec1db930fa8c62ee1c2b8e0b87706.tar.gz
tar -x --checkpoint=100 --checkpoint-action=dot -C /home/pi/workdir -f /home/pi/rpi-build/downloads/git.denx.de--p-u-boot-u-boot-arm.git-0a26e1d6c394aacbf1153977b7348d1dff85db3f.tar.bz2
tar -x --checkpoint=100 --checkpoint-action=dot -C /home/pi/workdir -f /home/pi/rpi-build/downloads/linux-3.15.tar.xz
Target 'unpack' done
Linux kernel version: 3.15
Target 'patch' done
cd /home/pi/workdir/linux && ARCH=arm make bcm2835_defconfig
cp /home/pi/workdir/linux/.config /home/pi/workdir/linux/.config.defconfig
cd /home/pi/workdir/linux && scripts/config --enable CONFIG_IKCONFIG
cd /home/pi/workdir/linux && scripts/config --enable CONFIG_IKCONFIG_PROC
cd /home/pi/workdir/linux && yes "" | ARCH=arm make oldconfig
cd /home/pi/workdir/linux && scripts/config --enable PROC_DEVICETREE
cd /home/pi/workdir/linux && yes "" | ARCH=arm make oldconfig
Target 'config' done
cd /home/pi/workdir/linux && ARCH=arm make -j2
cd /home/pi/workdir/u-boot && ./MAKEALL --continue rpi_b
/home/pi/workdir/u-boot/tools/mkimage -T script -d /home/pi/workdir/boot.scr /home/pi/workdir/boot.scr.uimg
Target 'kbuild' done
mkdir /home/pi/workdir/modules
Loadable kernel module support is disabled
mkdir -p /home/pi/workdir/modules/lib/modules
touch /home/pi/workdir/modules/lib/modules/dummy
cd /home/pi/workdir/linux && ARCH=arm make INSTALL_MOD_PATH=/home/pi/workdir/modules firmware_install
Target 'kmodules' done
Target 'external' done
rm -rf /home/pi/workdir/out
mkdir -p /home/pi/workdir/out
Target 'build' done
sudo UPDATE_SELF=0 SKIP_BACKUP=1 SKIP_REPODELETE=1 SKIP_DOWNLOAD=1 FW_REPOLOCAL=/home/pi/workdir/out rpi-update '2014-06-11 20:14:20 +0000'
*** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
*** Running pre-install script
Work around rpi-update issue #106
*** Updating firmware
*** Updating kernel modules
*** Updating VideoCore libraries
*** Using HardFP libraries
*** Updating SDK
*** Running ldconfig
*** Storing current firmware revision
*** Running post-install script
/lib/firmware
*** Deleting downloaded files
*** Syncing changes to disk
*** If no errors appeared, your firmware was successfully updated to 2014-06-11 20:14:20 +0000
*** A reboot is needed to activate the new firmware
Target 'install' done
$ sudo reboot
$ uname -a
Linux raspberrypi 3.15.0 #1 Wed Jun 11 20:03:03 UTC 2014 armv6l GNU/Linux
The result is in workdir/out
Install the default rpi Linux with IPv6 support built into the kernel proper (kernel.img)
It will download the kernel source that matches the latest raspberrypi/firmware release.
Start menuconfig and change: Networking support --> Networking options --> The IPv6 protocol : Press y which makes the M a star, then Exit
$ rpi-build use[stdlib] rpi_linux menuconfig
Show the configuration changes
$ rpi-build use[stdlib] rpi_linux diffconfig
IPV6 m -> y
Build and install (this takes ~11 hours)
$ rpi-build use[stdlib] rpi_linux install
$ sudo reboot
$ uname -a
Linux raspberrypi 3.12.21+ #1 PREEMPT Thu Jun 12 09:18:29 UTC 2014 armv6l GNU/Linux
$ ping6 -c1 ::1 | grep from
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.177 ms
Task: Release a kernel based on the offical one with IPv6 built into the kernel proper.
Building takes ~40mins on my old quad core machine.
Install ruby: sudo apt-get install ruby1.9.1
Install rpi-build and run it to install dependencies.
Configure git:
git config --global user.name "your name"
git config --global user.email "your email"
Create a github repo with a README so it can be cloned (Initialize this repository with a README).
Used in this example: https://github.com/notro/rpi-build-test
Create a release directory
mkdir ipv6; cd ipv6
Clone the firmware repo (the name 'rpi-firmware' let's rpi-build pick it up automatically as FW_REPO)
git clone https://github.com/notro/rpi-build-test rpi-firmware
Create file: Rakefile
require 'stdlib/rpi-linux'
package :ipv6 do
# use late variable expansion, because 'KERNEL_RELEASE' is set during the build target
Readme.desc { "Linux kernel release #{VAR['KERNEL_RELEASE']} with builtin IPv6 support for the Raspberry Pi." }
# IPV6 builtin
config 'IPV6', :enable
end
release :ipv6_linux => [:rpi_linux_common, :ipv6] do
Readme.body = """
Changelog
---------
No changes, first release.
"""
# used by the commit target
# single empty line between subject and body (if a body is needed).
# Formatting suggestion: http://stackoverflow.com/questions/2290016/git-commit-messages-50-72-formatting
ENV['COMMIT_MESSAGE'] = """Linux kernel with builtin IPv6 support
Based on the offical kernel.
"""
end
Build
$ rpi-build log ipv6_linux build
Temporary logfile: /tmp/rpi-build20140603-7377-ebrpf5.log
$ head workdir/build.log
Start: 2014-06-12 15:23:04 +0200
Commandline arguments: log ipv6_linux build
Workdir: /home/pi/ipv6/workdir
$ tail workdir/build.log
Target 'build' done
End: 2014-06-12 15:59:53 +0200
Then we test the kernel before we release it:
$ rpi-build ipv6_linux install SSHIP=<ip address of Raspberry Pi>
cd /home/pi/ipv6/workdir/out; tar -zcf /home/pi/ipv6/workdir/archive.tar.gz *
Target 'archive' done
sshpass -e ssh -o LogLevel=quiet -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no pi@192.168.10.162 "rm -rf rpi-build-archive; mkdir rpi-build-archive"
cat /home/pi/ipv6/workdir/archive.tar.gz | sshpass -e ssh -o LogLevel=quiet -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no pi@192.168.10.162 "cd rpi-build-archive; tar zxvf -"
Target 'transfer' done
sshpass -e ssh -o LogLevel=quiet -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no pi@192.168.10.162 "stat --printf=%Y /usr/bin/rpi-update"
sshpass -e ssh -o LogLevel=quiet -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no pi@192.168.10.162 "sudo UPDATE_SELF=0 SKIP_BACKUP=1 SKIP_REPODELETE=0 SKIP_DOWNLOAD=1 FW_REPOLOCAL=rpi-build-archive rpi-update '2014-06-12 13:41:53 +0200' 1>&2"
*** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
*** Running pre-install script
Work around rpi-update issue #106
*** Updating firmware
*** Updating kernel modules
*** depmod 3.12.21+
*** Updating VideoCore libraries
*** Using HardFP libraries
*** Updating SDK
*** Running ldconfig
*** Storing current firmware revision
*** Running post-install script
/lib/firmware
*** Deleting downloaded files
*** Syncing changes to disk
*** If no errors appeared, your firmware was successfully updated to 2014-06-12 13:41:53 +0200
*** A reboot is needed to activate the new firmware
Target 'install' done
On the Pi:
$ cat /boot/.firmware_revision
2014-06-12 16:09:13 +0200
$ sudo reboot
$ uname -a
Linux raspberrypi 3.12.21+ #1 PREEMPT Thu Jun 12 15:56:02 CEST 2014 armv6l GNU/Linux
Release it
$ rpi-build ipv6_linux commit
Workdir: /home/pi/ipv6/workdir
Target 'readme' done
rm -rf /home/pi/ipv6/rpi-firmware/*
cp -a /home/pi/ipv6/workdir/out/* /home/pi/ipv6/rpi-firmware
rm -rf /home/pi/ipv6/rpi-firmware/modules/*/{source,build}
cp /home/pi/ipv6/workdir/build.log /home/pi/ipv6/rpi-firmware
cd /home/pi/ipv6/rpi-firmware && git checkout -q master
cd /home/pi/ipv6/rpi-firmware && git add .
cd /home/pi/ipv6/rpi-firmware && git commit -a -m "Linux kernel with builtin IPv6 support
Based on the offical kernel.
"
Target 'commit' done
$ rpi-build ipv6_linux push
Workdir: /home/pi/ipv6/workdir
cd /home/pi/ipv6/rpi-firmware && git checkout -q master
cd /home/pi/ipv6/rpi-firmware && git rev-parse --abbrev-ref HEAD
cd /home/pi/ipv6/rpi-firmware && git push origin master
Username for 'https://github.com': notro
Password for 'https://notro@github.com':
To https://github.com/notro/rpi-build-test
459cda3..9e2d5cd master -> master
Target 'push' done
$ cd rpi-firmware
$ git status
# On branch master
nothing to commit (working directory clean)
$ git log
commit 9e2d5cd1eefaf0673fde1ae0204f1af5fd1a7df9
Author: notro <notro@tronnes.org>
Date: Thu Jun 12 16:11:45 2014 +0200
Linux kernel with builtin IPv6 support
Based on the offical kernel.
commit 459cda3d5607b237ebbb4daf8438824a42f8d396
Author: notro <notro@tronnes.org>
Date: Thu Jun 12 15:13:33 2014 +0200
Initial commit
Then as a last test on the Pi:
$ sudo REPO_URI=https://github.com/notro/rpi-build-test rpi-update
$ cat /boot/.firmware_revision
9e2d5cd1eefaf0673fde1ae0204f1af5fd1a7df9
$ sudo reboot
$ uname -a
Linux raspberrypi 3.12.21+ #1 PREEMPT Thu Jun 12 15:56:02 CEST 2014 armv6l GNU/Linux
Here we build on the previous example and add a 'latest' branch to our firmware repo.
Add to Rakefile
release :ipv6_linux_latest => [:rpi_linux_common, :ipv6] do
VAR['RASPBERRYPI_LINUX_BRANCH'] = raspberrypi_linux_latest
info "RASPBERRYPI_LINUX_BRANCH = #{ENV['RASPBERRYPI_LINUX_BRANCH']}"
# notro/rpi-build-test branch
VAR['FW_BRANCH'] = 'latest'
Readme.body = """
Changelog
---------
No changes, first release.
"""
# use late variable expansion, KERNEL_RELEASE is not set yet
VAR.default('COMMIT_MESSAGE') { """Linux kernel with builtin IPv6 support
Based on the offical kernel #{VAR['KERNEL_RELEASE']}
""" }
end
Clean (delete workdir), build and commit
$ rpi-build log ipv6_linux_latest commit clean
RASPBERRYPI_LINUX_BRANCH = rpi-3.15.y
Push
$ rpi-build ipv6_linux_latest push
cd /home/pi/ipv6/rpi-firmware && git push origin latest
Username for 'https://github.com': notro
Password for 'https://notro@github.com':
To https://github.com/notro/rpi-build-test
* [new branch] latest -> latest
Target 'push' done
$ cd rpi-firmware
$ git branch
* latest
master
$ git log -1
commit 793e1819ebe37b6e13dc24b7cdedf8e0e897ae2e
Author: notro <notro@tronnes.org>
Date: Thu Jun 12 16:53:32 2014 +0200
Linux kernel with builtin IPv6 support
Based on the offical kernel 3.15.0+
Install on the Pi
$ sudo REPO_URI=https://github.com/notro/rpi-build-test BRANCH=latest rpi-update
$ cat /boot/.firmware_revision
793e1819ebe37b6e13dc24b7cdedf8e0e897ae2e
$ sudo reboot
$ uname -a
Linux raspberrypi 3.15.0+ #1 PREEMPT Thu Jun 12 16:50:44 CEST 2014 armv6l GNU/Linux
In this example I will show how to use the diff target.
Rakefile
require 'stdlib/rpi-linux'
release :hello_linux => :rpi_linux_common do
# This can be used instead of the diffprep task
# ENV['DIFFPREP'] = 'linux'
# When doing a lot of building, I don't want to unpack tools everytime, so I have unpacked it elsewhere
ENV['CROSS_COMPILE'] = '/home/pi/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-'
target :patch do
insert_before workdir('linux/arch/arm/mach-bcm2708/bcm2708.c'), ' vc_cma_early_init();', <<'EOM'
printk("Hello from %s()\n", __func__);
EOM
end
end
Fetch, unpack, patch and prepare for diff
$ rpi-build hello_linux diffprep patch
Add to workdir/linux/arch/arm/mach-bcm2708/bcm2708.c in bcm2708_init_led()
printk("Hello from %s()\n", __func__);
diff against 'unpack'
$ rpi-build hello_linux diff
Show
$ cat workdir/linux-unpack.patch
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 95a47fa..5fb7a9e 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -778,6 +778,7 @@ void __init bcm2708_init(void)
int i;
#if defined(CONFIG_BCM_VC_CMA)
+ printk("Hello from %s()\n", __func__);
vc_cma_early_init();
#endif
printk("bcm2708.uart_clock = %d\n", uart_clock);
@@ -983,6 +984,7 @@ static struct platform_device bcm2708_led_device = {
static void __init bcm2708_init_led(void)
{
+ printk("Hello from %s()\n", __func__);
bcm2708_leds[0].gpio = disk_led_gpio;
bcm2708_leds[0].active_low = disk_led_active_low;
platform_device_register(&bcm2708_led_device);
diff against 'patch'
$ rpi-build hello_linux diff[patch]
Show
$ cat workdir/linux-patch.patch
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 99f511d..5fb7a9e 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -984,6 +984,7 @@ static struct platform_device bcm2708_led_device = {
static void __init bcm2708_init_led(void)
{
+ printk("Hello from %s()\n", __func__);
bcm2708_leds[0].gpio = disk_led_gpio;
bcm2708_leds[0].active_low = disk_led_active_low;
platform_device_register(&bcm2708_led_device);
Install
$ rpi-build hello_linux install SSHIP=<ip>
Result
$ dmesg | grep Hello
[ 0.031375] Hello from bcm2708_init()
[ 0.031980] Hello from bcm2708_init_led()