Clean/refactor to add raspi2, plus ubuntu-cpc fixes

[ Steve Langasek ]
  * Add hooks to ubuntu-cpc to divert /bin/sync in the chroot and undivert it
    at the end.  This is a general-purpose change that should be applied to
    all flavors and archs, but at the moment it's only needed on armhf+raspi2
    to work around the raspberrypi2-firmware postinst calling sync, which is
    actually warranted in the normal case.
  * If a subarch is specified for a cloud image build, don't build rootfs
    artifacts; these should come from the 'generic' build.
  * Fix architecture handling in hooks.  We know we're always being invoked
    from a launchpad-buildd-like setup, which passes ARCH and SUBARCH in the
    environment, because auto/config and auto/build both rely on this.  So
    don't scatter dpkg --print-architecture calls throughout, especially
    when many of these are not cross-build-aware.
  * Refactor ubuntu-cpc hooks to allow us to handle images where the root
    partition should not be partition 1.

  [ Ben Howard ]
  * ubuntu-cpc: fix hooks/032-disk-image.binary call to
    create_empty_partition, which requires five args due to "-u"
  * ubuntu-cpc: in hooks/030-root-tarball.binary create /lib/modules to fix
    (LP: 1543204).

  [ Steve Langasek ]
  * Refactor ubuntu-cpc hooks to always produce a 'plain' rootfs via
    live-build and reuse this for the tarball, instead of lb_binary_rootfs
    creating some artifact that we ignore / throw away.
  * Initial support for raspi2 subarch.
  * Import live-build/ubuntu-cpc/hooks/raspi2/mkknlimg from
    https://github.com/raspberrypi/linux/blob/rpi-4.1.y/scripts/mkknlimg
    and use it to install a bootable uboot.bin.
ubuntu/trusty
Robert C Jennings 8 years ago
parent cb8ede888f
commit 742985bb4d

35
debian/changelog vendored

@ -1,3 +1,38 @@
livecd-rootfs (2.209.12) trusty; urgency=medium
[ Steve Langasek ]
* Add hooks to ubuntu-cpc to divert /bin/sync in the chroot and undivert it
at the end. This is a general-purpose change that should be applied to
all flavors and archs, but at the moment it's only needed on armhf+raspi2
to work around the raspberrypi2-firmware postinst calling sync, which is
actually warranted in the normal case.
* If a subarch is specified for a cloud image build, don't build rootfs
artifacts; these should come from the 'generic' build.
* Fix architecture handling in hooks. We know we're always being invoked
from a launchpad-buildd-like setup, which passes ARCH and SUBARCH in the
environment, because auto/config and auto/build both rely on this. So
don't scatter dpkg --print-architecture calls throughout, especially
when many of these are not cross-build-aware.
* Refactor ubuntu-cpc hooks to allow us to handle images where the root
partition should not be partition 1.
[ Ben Howard ]
* ubuntu-cpc: fix hooks/032-disk-image.binary call to
create_empty_partition, which requires five args due to "-u"
* ubuntu-cpc: in hooks/030-root-tarball.binary create /lib/modules to fix
(LP: 1543204).
[ Steve Langasek ]
* Refactor ubuntu-cpc hooks to always produce a 'plain' rootfs via
live-build and reuse this for the tarball, instead of lb_binary_rootfs
creating some artifact that we ignore / throw away.
* Initial support for raspi2 subarch.
* Import live-build/ubuntu-cpc/hooks/raspi2/mkknlimg from
https://github.com/raspberrypi/linux/blob/rpi-4.1.y/scripts/mkknlimg
and use it to install a bootable uboot.bin.
-- Robert C Jennings <robert.jennings@canonical.com> Tue, 23 May 2017 22:29:47 -0500
livecd-rootfs (2.209.11) trusty; urgency=medium
[ Steve Langasek ]

6
debian/copyright vendored

@ -1,4 +1,4 @@
live-build/* is copyright (c) 2004-2013 by Canonical Ltd.
live-build/* is copyright (c) 2004-2016 by Canonical Ltd.
These programs are free software; you can redistribute and/or modify
them under the terms of the GNU General Public License as published by
@ -16,3 +16,7 @@ livecd-rootfs source package as the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA.
Files: live-build/ubuntu-cpc/hooks/raspi2/mkknlimg
Copyright: 2009,2010 Dick Streefland <dick@streefland.net>
2014,2015 Raspberry Pi (Trading) Limited <info@raspberrypi.org>
License: GPL-2+

@ -111,6 +111,12 @@ add_binary_hook ()
BINARY_HOOKS="${BINARY_HOOKS:+$BINARY_HOOKS }$1"
}
case $PROJECT in
ubuntu-cpc)
IMAGEFORMAT=plain
;;
esac
case $IMAGEFORMAT in
ext2|ext3|ext4)
OPTS="${OPTS:+$OPTS }--initramfs none --chroot-filesystem $IMAGEFORMAT"
@ -480,6 +486,11 @@ case $ARCH in
echo "linux-firmware-nexus7 shared/nexus7_notice_accepted boolean true" >config/preseed/linux-firmware-nexus7.preseed.chroot
echo "d-i passwd/auto-login boolean true" >config/preseed/autologin.preseed.chroot
;;
raspi2)
COMPONENTS='main restricted universe'
add_package install raspberrypi2-firmware u-boot-rpi flash-kernel u-boot-tools
BINARY_REMOVE_LINUX=false
;;
esac
;;
esac
@ -536,6 +547,80 @@ echo "LB_CHROOT_HOOKS=\"$CHROOT_HOOKS\"" >> config/chroot
echo "LB_BINARY_HOOKS=\"$BINARY_HOOKS\"" >> config/binary
echo "BUILDSTAMP=\"$NOW\"" >> config/binary
case $ARCH+$SUBARCH in
armhf+raspi2)
cat > config/hooks/01-firmware-directory.chroot_early <<EOF
#!/bin/sh -ex
mkdir -p /boot/firmware
EOF
cat > config/hooks/999-raspi2-fixes.chroot <<EOF
#!/bin/sh -ex
cat >> /etc/fstab << EOM
LABEL=system-boot /boot/firmware vfat defaults 0 1
EOM
cat > /boot/firmware/cmdline.txt << EOM
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
EOM
cat > /boot/firmware/config.txt << EOM
# For more options and information see
# http://www.raspberrypi.org/documentation/configuration/config-txt.md
# Some settings may impact device functionality. See link above for details
kernel=uboot.bin
# enable i2c
dtparam=i2c_arm=on
dtparam=spi=on
# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1
# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
#disable_overscan=1
# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16
# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720
# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1
# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1
# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2
# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4
# uncomment for composite PAL
#sdtv_mode=2
#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800
EOM
EOF
;;
*)
;;
esac
case $PROJECT in
ubuntu-server)
cat > config/hooks/100-remove-fstab.chroot <<EOF

@ -41,6 +41,7 @@ mount_image() {
apt-get install -qqy kpartx
trap clean_loops EXIT
backing_img="$1"
local rootpart="$2"
kpartx_mapping="$(kpartx -s -v -a ${backing_img})"
# Find the loop device
@ -52,7 +53,7 @@ mount_image() {
fi
# Find the rootfs location
rootfs_dev_mapper="/dev/mapper/${loop_p1}"
rootfs_dev_mapper="/dev/mapper/${loop_p1%%[0-9]}${rootpart}"
if [ ! -b "${rootfs_dev_mapper}" ]; then
echo "${rootfs_dev_mapper} is not a block device";
exit 1
@ -65,11 +66,9 @@ mount_image() {
return 0
}
mount_partition() {
partition="$1"
mountpoint="$2"
setup_mountpoint() {
local mountpoint="$1"
mount "$partition" "$mountpoint"
mount --bind /dev "$mountpoint/dev"
mount devpts-live -t proc "$mountpoint/dev/pts"
mount proc-live -t proc "$mountpoint/proc"
@ -77,13 +76,22 @@ mount_partition() {
mount -t tmpfs none "$mountpoint/tmp"
mv "$mountpoint/etc/resolv.conf" resolv.conf.tmp
cp /etc/resolv.conf "$mountpoint/etc/resolv.conf"
}
mount_partition() {
partition="$1"
mountpoint="$2"
mount "$partition" "$mountpoint"
setup_mountpoint "$mountpoint"
}
mount_disk_image() {
local disk_image=${1}
local mountpoint=${2}
mount_image ${disk_image}
mount_image ${disk_image} 1
mount_partition "${rootfs_dev_mapper}" $mountpoint
local uefi_dev="/dev/mapper${loop_device///dev/}p15"

@ -0,0 +1,11 @@
#!/bin/sh
set -e
dpkg-divert --quiet --add --divert /bin/sync.REAL --rename /bin/sync
cat > /bin/sync <<'EOF'
#! /bin/sh
echo "$0: diverted by livecd-rootfs" >&2
exit 0
EOF
chmod +x /bin/sync

@ -1,13 +1,13 @@
#!/bin/bash -ex
mkdir binary/boot/filesystem.dir
cp -a chroot/* binary/boot/filesystem.dir
if [ -n "$SUBARCH" ]; then
echo "Skipping rootfs build for subarch flavor build"
exit 0
fi
mount --bind /dev "binary/boot/filesystem.dir/dev"
mount proc-live -t proc "binary/boot/filesystem.dir/proc"
mount sysfs-live -t sysfs "binary/boot/filesystem.dir/sys"
mv "binary/boot/filesystem.dir/etc/resolv.conf" resolv.conf.tmp
cp /etc/resolv.conf "binary/boot/filesystem.dir/etc/resolv.conf"
. /build/config/functions
setup_mountpoint binary/boot/filesystem.dir
chroot binary/boot/filesystem.dir dpkg-divert --local --rename /usr/sbin/grub-probe
chroot binary/boot/filesystem.dir touch /usr/sbin/grub-probe
@ -16,6 +16,7 @@ chroot binary/boot/filesystem.dir chmod +x /usr/sbin/grub-probe
env DEBIAN_FRONTEND=noninteractive chroot binary/boot/filesystem.dir apt-get --purge remove --assume-yes '^linux-.*'
env DEBIAN_FRONTEND=noninteractive chroot binary/boot/filesystem.dir apt-get --purge remove --assume-yes '^grub-.*'
env DEBIAN_FRONTEND=noninteractive chroot binary/boot/filesystem.dir apt-get autoremove --purge --assume-yes
chroot binary/boot/filesystem.dir mkdir /lib/modules
chroot binary/boot/filesystem.dir rm /usr/sbin/grub-probe
chroot binary/boot/filesystem.dir dpkg-divert --remove --local --rename /usr/sbin/grub-probe
@ -23,4 +24,6 @@ chroot binary/boot/filesystem.dir dpkg-divert --remove --local --rename /usr/sbi
mv resolv.conf.tmp "binary/boot/filesystem.dir/etc/resolv.conf"
umount "binary/boot/filesystem.dir/proc"
umount "binary/boot/filesystem.dir/sys"
umount "binary/boot/filesystem.dir/dev/pts"
umount "binary/boot/filesystem.dir/dev"
umount "binary/boot/filesystem.dir/tmp"

@ -3,6 +3,10 @@
#
# Generate the rootfs.tar.gz and manifest
if [ -n "$SUBARCH" ]; then
exit 0
fi
dpkg-query --admindir=binary/boot/filesystem.dir/var/lib/dpkg -W > livecd.ubuntu-cpc.rootfs.manifest
(cd "binary/boot/filesystem.dir/" && tar -c *) | \

@ -1,46 +1,106 @@
#!/bin/bash -eux
architecture=$(chroot chroot dpkg --print-architecture)
if [ "$architecture" = "ppc64el" ]; then
echo "ppc64el disk images are handled separately"
exit 0
fi
#!/bin/bash -ex
. /build/config/functions
create_empty_partition() {
BOOTPART_START=
BOOTPART_END=
BOOT_MOUNTPOINT=
ROOTPART_START=1
case $ARCH:$SUBARCH in
ppc64el:*)
echo "ppc64el disk images are handled separately"
exit 0
;;
armhf:raspi2)
# matches the size of the snappy image
IMAGE_SIZE=$((4*1000*1000*1000))
BOOTPART_START=8192s
BOOTPART_END=138M
BOOT_MOUNTPOINT=/boot/firmware
;;
*)
;;
esac
create_empty_partition_table() {
apt-get install -qqy parted
parted_prefix="parted $1 --script --"
${parted_prefix} mklabel msdos
${parted_prefix} mkpart primary 1 -1
${parted_prefix} set 1 B
parted "$1" --script -- mklabel msdos
}
create_empty_partition() {
local disk="$1"
local part="$2"
local start="$3"
local end="$4"
local type="$5"
local bootable="$6"
parted_prefix="parted $disk --script --"
${parted_prefix} mkpart primary "$type" "$start" "$end"
if [ -n "$bootable" ]; then
${parted_prefix} set "$part" B
fi
${parted_prefix} print
${parted_prefix} align-check opt 1
${parted_prefix} align-check opt "$part"
}
disk_image=binary/boot/disk.ext4
create_empty_disk_image "${disk_image}"
create_empty_partition "${disk_image}"
mount_image "${disk_image}"
create_empty_partition_table "${disk_image}"
ROOTPART=1
ROOT_BOOTABLE=1
if [ -n "$BOOTPART_START" ]; then
ROOTPART=2
ROOTPART_START="$BOOTPART_END"
ROOT_BOOTABLE=
create_empty_partition "$disk_image" 1 "$BOOTPART_START" "$BOOTPART_END" fat32 1
fi
create_empty_partition "${disk_image}" "$ROOTPART" "$ROOTPART_START" -1 ext2 "$ROOT_BOOTABLE"
mount_image "${disk_image}" "$ROOTPART"
# Copy the chroot in to the disk
make_ext4_partition "${rootfs_dev_mapper}"
mkdir mountpoint
mount "${rootfs_dev_mapper}" mountpoint
if [ -n "$BOOT_MOUNTPOINT" ]; then
boot_dev_mapper="${rootfs_dev_mapper%%[0-9]}1"
# assume fat32 for now
mkfs.vfat -n system-boot "$boot_dev_mapper"
mkdir -p "mountpoint/$BOOT_MOUNTPOINT"
mount "$boot_dev_mapper" "mountpoint/$BOOT_MOUNTPOINT"
fi
cp -a chroot/* mountpoint/
umount mountpoint
rmdir mountpoint
case $architecture in
setup_mountpoint mountpoint
case $ARCH:$SUBARCH in
armhf:raspi2)
chroot mountpoint flash-kernel \
--machine "Raspberry Pi 2 Model B"
# not the best place for this, but neither flash-kernel nor
# u-boot have provisions for installing u-boot via maintainer
# script
/build/config/hooks/raspi2/mkknlimg --dtok \
mountpoint/usr/lib/u-boot/rpi_2/u-boot.bin \
mountpoint/boot/firmware/uboot.bin
;;
*) ;;
esac
case $ARCH in
amd64|i386) should_install_grub=1;;
*) should_install_grub=0;;
esac
if [ "${should_install_grub}" -eq 1 ]; then
mkdir mountpoint
mount_partition "${rootfs_dev_mapper}" mountpoint
echo "(hd0) ${loop_device}" > mountpoint/tmp/device.map
chroot mountpoint grub-install ${loop_device}
chroot mountpoint grub-bios-setup \
@ -51,9 +111,14 @@ if [ "${should_install_grub}" -eq 1 ]; then
${loop_device}
rm mountpoint/tmp/device.map
umount_partition mountpoint
rmdir mountpoint
fi
if [ -n "$BOOT_MOUNTPOINT" ]; then
umount "mountpoint/$BOOT_MOUNTPOINT"
fi
umount_partition mountpoint
rmdir mountpoint
clean_loops
trap - EXIT

@ -1,8 +1,12 @@
#!/bin/bash -eux
#!/bin/bash -ex
# vi: ts=4 noexpandtab
#
# Generate a squashfs root and manifest
if [ -n "$SUBARCH" ]; then
exit 0
fi
apt-get -qqy install squashfs-tools
squashfs_f="${PWD}/livecd.ubuntu-cpc.squashfs"

@ -1,11 +1,10 @@
#!/bin/bash -eux
architecture=$(chroot chroot dpkg --print-architecture)
case $architecture in
case $ARCH in
amd64|arm64)
;;
*)
echo "We don't create EFI images for $architecture."
echo "We don't create EFI images for $ARCH."
exit 0
;;
esac
@ -17,7 +16,7 @@ apt-get -qqy install dosfstools gdisk
create_partitions() {
disk_image="$1"
sgdisk "${disk_image}" --zap-all
case $architecture in
case $ARCH in
arm64)
sgdisk "${disk_image}" \
--new=15:0:204800 \
@ -62,7 +61,7 @@ install_grub() {
efi_boot_dir="/boot/efi/EFI/BOOT"
chroot mountpoint mkdir -p "${efi_boot_dir}"
case $architecture in
case $ARCH in
arm64)
chroot mountpoint apt-get -qqy install --no-install-recommends grub-efi-arm64 grub-efi-arm64-bin
grub_modules="part_gpt fat gzio ext2 normal chain boot configfile linux search_fs_uuid search_label terminal serial video video_fb efi_gop"
@ -101,7 +100,7 @@ EOF
chroot mountpoint cp /boot/efi/EFI/BOOT/grub.cfg /boot/efi/boot/grub
fi
if [ $architecture = "amd64" ]; then
if [ "$ARCH" = "amd64" ]; then
# Install the BIOS/GPT bits. Since GPT boots from the ESP partition,
# it means that we just run this simple command and we're done
chroot mountpoint grub-install --target=i386-pc "${loop_device}"
@ -129,7 +128,7 @@ disk_image=binary/boot/disk-uefi.ext4
create_empty_disk_image "${disk_image}"
create_partitions "${disk_image}"
mount_image "${disk_image}"
mount_image "${disk_image}" 1
# Copy the chroot in to the disk
make_ext4_partition "${rootfs_dev_mapper}"

@ -1,6 +1,5 @@
#!/bin/bash -eux
architecture=$(chroot chroot dpkg --print-architecture)
if [ "$architecture" != "ppc64el" ]; then
if [ "$ARCH" != "ppc64el" ]; then
exit 0
fi
@ -59,7 +58,7 @@ disk_image=binary/boot/disk.ext4
create_empty_disk_image "${disk_image}"
create_partitions "${disk_image}"
mount_image "${disk_image}"
mount_image "${disk_image}" 1
# Copy the chroot in to the disk
make_ext4_partition "${rootfs_dev_mapper}"

@ -1,5 +1,15 @@
#!/bin/bash -ex
case $ARCH:$SUBARCH in
# Not sure if any other cloud images use subarch for something that
# should take qcow2 format, so only skipping this on raspi2 for now.
armhf:raspi2)
apt-get install -qqy pxz
pxz -T4 -c binary/boot/disk.ext4 > livecd.ubuntu-cpc.disk1.img.xz
exit 0
;;
esac
apt-get install -qqy qemu-utils
. /build/config/functions

@ -3,13 +3,11 @@
#
# Generate VMDK files
architecture=$(chroot chroot dpkg --print-architecture)
extension="disk1.vmdk"
case ${architecture} in
case $ARCH in
i386|amd64) ;;
*) echo "VMDK images are not supported for ${architecture} yet.";
*) echo "VMDK images are not supported for $ARCH yet.";
exit 0;;
esac

@ -9,18 +9,16 @@
#
# For this step, we re-use the VMDK's made in 040-vmdk-image.binary
architecture=$(chroot chroot dpkg --print-architecture)
case ${architecture} in
case $ARCH in
amd64|i386) ;;
*) echo "OVA images are not supported for ${architecture} yet.";
*) echo "OVA images are not supported for $ARCH yet.";
exit 0;;
esac
cur_d=${PWD}
my_d=$(dirname $(readlink -f ${0}))
base_vmdk="livecd.ubuntu-cpc.disk1.vmdk"
if [ $architecture = "amd64" ]; then
if [ "$ARCH" = "amd64" ]; then
base_vmdk="livecd.ubuntu-cpc.uefi.vmdk"
fi

@ -15,13 +15,16 @@
cur_d=${PWD}
my_d=$(dirname $(readlink -f ${0}))
architecture=$(chroot chroot dpkg --print-architecture)
base_vmdk="livecd.ubuntu-cpc.disk1.vmdk"
if [[ ! "${architecture}" =~ (amd64|i386) ]]; then
echo "Vagrant images are not supported for ${architecture}"
exit 0
elif [ ! -e ${base_vmdk} ]; then
case $ARCH in
amd64|i386) ;;
*)
echo "Vagrant images are not supported for $ARCH"
exit 0
esac
if [ ! -e ${base_vmdk} ]; then
echo "Did not find VMDK to produce Vagrant images."
exit 0
fi

@ -0,0 +1,5 @@
#! /bin/sh
set -e
rm -f /bin/sync
dpkg-divert --quiet --remove --rename /bin/sync

@ -0,0 +1,244 @@
#!/usr/bin/env perl
# ----------------------------------------------------------------------
# mkknlimg by Phil Elwell for Raspberry Pi
# based on extract-ikconfig by Dick Streefland
#
# (c) 2009,2010 Dick Streefland <dick@streefland.net>
# (c) 2014,2015 Raspberry Pi (Trading) Limited <info@raspberrypi.org>
#
# Licensed under the terms of the GNU General Public License.
# ----------------------------------------------------------------------
use strict;
use warnings;
use integer;
my $trailer_magic = 'RPTL';
my $tmpfile1 = "/tmp/mkknlimg_$$.1";
my $tmpfile2 = "/tmp/mkknlimg_$$.2";
my $dtok = 0;
my $is_283x = 0;
while (@ARGV && ($ARGV[0] =~ /^-/))
{
my $arg = shift(@ARGV);
if ($arg eq '--dtok')
{
$dtok = 1;
}
elsif ($arg eq '--283x')
{
$is_283x = 1;
}
else
{
print ("* Unknown option '$arg'\n");
usage();
}
}
usage() if (@ARGV != 2);
my $kernel_file = $ARGV[0];
my $out_file = $ARGV[1];
if (! -r $kernel_file)
{
print ("* File '$kernel_file' not found\n");
usage();
}
my @wanted_strings =
(
'bcm2708_fb',
'brcm,bcm2835-mmc',
'brcm,bcm2835-sdhost',
'brcm,bcm2708-pinctrl',
'brcm,bcm2835-gpio',
'brcm,bcm2835',
'brcm,bcm2836'
);
my $res = try_extract($kernel_file, $tmpfile1);
$res = try_decompress('\037\213\010', 'xy', 'gunzip', 0,
$kernel_file, $tmpfile1, $tmpfile2) if (!$res);
$res = try_decompress('\3757zXZ\000', 'abcde', 'unxz --single-stream', -1,
$kernel_file, $tmpfile1, $tmpfile2) if (!$res);
$res = try_decompress('BZh', 'xy', 'bunzip2', 0,
$kernel_file, $tmpfile1, $tmpfile2) if (!$res);
$res = try_decompress('\135\0\0\0', 'xxx', 'unlzma', 0,
$kernel_file, $tmpfile1, $tmpfile2) if (!$res);
$res = try_decompress('\211\114\132', 'xy', 'lzop -d', 0,
$kernel_file, $tmpfile1, $tmpfile2) if (!$res);
$res = try_decompress('\002\041\114\030', 'xy', 'lz4 -d', 1,
$kernel_file, $tmpfile1, $tmpfile2) if (!$res);
my $append_trailer;
my $trailer;
my $kver = '?';
$append_trailer = $dtok;
if ($res)
{
$kver = $res->{''} || '?';
print("Version: $kver\n");
$append_trailer = $dtok;
if (!$dtok)
{
if (config_bool($res, 'bcm2708_fb') ||
config_bool($res, 'brcm,bcm2835-mmc') ||
config_bool($res, 'brcm,bcm2835-sdhost'))
{
$dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl');
$dtok ||= config_bool($res, 'brcm,bcm2835-gpio');
$is_283x ||= config_bool($res, 'brcm,bcm2835');
$is_283x ||= config_bool($res, 'brcm,bcm2836');
$dtok ||= $is_283x;
$append_trailer = 1;
}
else
{
print ("* This doesn't look like a Raspberry Pi kernel. In pass-through mode.\n");
}
}
}
elsif (!$dtok)
{
print ("* Is this a valid kernel? In pass-through mode.\n");
}
if ($append_trailer)
{
printf("DT: %s\n", $dtok ? "y" : "n");
printf("283x: %s\n", $is_283x ? "y" : "n");
my @atoms;
push @atoms, [ $trailer_magic, pack('V', 0) ];
push @atoms, [ 'KVer', $kver ];
push @atoms, [ 'DTOK', pack('V', $dtok) ];
push @atoms, [ '283x', pack('V', $is_283x) ];
$trailer = pack_trailer(\@atoms);
$atoms[0]->[1] = pack('V', length($trailer));
$trailer = pack_trailer(\@atoms);
}
my $ofh;
my $total_len = 0;
if ($out_file eq $kernel_file)
{
die "* Failed to open '$out_file' for append\n"
if (!open($ofh, '>>', $out_file));
$total_len = tell($ofh);
}
else
{
die "* Failed to open '$kernel_file'\n"
if (!open(my $ifh, '<', $kernel_file));
die "* Failed to create '$out_file'\n"
if (!open($ofh, '>', $out_file));
my $copybuf;
while (1)
{
my $bytes = sysread($ifh, $copybuf, 64*1024);
last if (!$bytes);
syswrite($ofh, $copybuf, $bytes);
$total_len += $bytes;
}
close($ifh);
}
if ($trailer)
{
# Pad to word-alignment
syswrite($ofh, "\x000\x000\x000", (-$total_len & 0x3));
syswrite($ofh, $trailer);
}
close($ofh);
exit($trailer ? 0 : 1);
END {
unlink($tmpfile1) if ($tmpfile1);
unlink($tmpfile2) if ($tmpfile2);
}
sub usage
{
print ("Usage: mkknlimg [--dtok] [--283x] <vmlinux|zImage|bzImage> <outfile>\n");
exit(1);
}
sub try_extract
{
my ($knl, $tmp) = @_;
my $ver = `strings "$knl" | grep -a -E "^Linux version [1-9]"`;
return undef if (!$ver);
chomp($ver);
my $res = { ''=>$ver };
my $string_pattern = '^('.join('|', @wanted_strings).')$';
my @matches = `strings \"$knl\" | grep -E \"$string_pattern\"`;
foreach my $match (@matches)
{
chomp($match);
$res->{$match} = 1;
}
return $res;
}
sub try_decompress
{
my ($magic, $subst, $zcat, $idx, $knl, $tmp1, $tmp2) = @_;
my $pos = `tr "$magic\n$subst" "\n$subst=" < "$knl" | grep -abo "^$subst"`;
if ($pos)
{
chomp($pos);
$pos = (split(/[\r\n]+/, $pos))[$idx];
return undef if (!defined($pos));
$pos =~ s/:.*[\r\n]*$//s;
my $cmd = "tail -c+$pos \"$knl\" | $zcat > $tmp2 2> /dev/null";
my $err = (system($cmd) >> 8);
return undef if (($err != 0) && ($err != 2));
return try_extract($tmp2, $tmp1);
}
return undef;
}
sub pack_trailer
{
my ($atoms) = @_;
my $trailer = pack('VV', 0, 0);
for (my $i = $#$atoms; $i>=0; $i--)
{
my $atom = $atoms->[$i];
$trailer .= pack('a*x!4Va4', $atom->[1], length($atom->[1]), $atom->[0]);
}
return $trailer;
}
sub config_bool
{
my ($configs, $wanted) = @_;
my $val = $configs->{$wanted} || 'n';
return (($val eq 'y') || ($val eq '1'));
}
Loading…
Cancel
Save