-
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 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 [email protected] "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 [email protected] "cd rpi-build-archive; tar zxvf -"
Target 'transfer' done
sshpass -e ssh -o LogLevel=quiet -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no [email protected] "stat --printf=%Y /usr/bin/rpi-update"
sshpass -e ssh -o LogLevel=quiet -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no [email protected] "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://[email protected]':
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 <[email protected]>
Date: Thu Jun 12 16:11:45 2014 +0200
Linux kernel with builtin IPv6 support
Based on the offical kernel.
commit 459cda3d5607b237ebbb4daf8438824a42f8d396
Author: notro <[email protected]>
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://[email protected]':
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 <[email protected]>
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()