RPi (Raspbian arm) chroot on x86 Linux
Different architecture system chroot using qemu-user-static and binfmt hooks is a common way to do (faster) native development of embedded system on desktop/server grade equipment. Did it several times with several platforms, should be the same with RPi. Raspbian is Debian, host machine is also Debian. We can use 2 scenarios:
Official Raspbian image approach
I'm on a x86_64 Debian Wheezy
# uname -a
Linux lab0 3.14.16 #1 SMP Sat Aug 9 23:54:07 EEST 2014 x86_64 GNU/Linux
Instal prerequisites:
# apt-get install qemu-user-static kpartx
binfmt-support is installed as a dependancy to qemu-user-static.
Get the latest official raspbian image:
# wget -c http://downloads.raspberrypi.org/raspbian/images/raspbian-2014-12-25/2014-12-24-wheezy-raspbian.zip
# unzip 2014-12-24-wheezy-raspbian.zip
Image has multiple partitions in it, so we need kpartx to operate them:
# kpartx -a -v 2014-12-24-wheezy-raspbian.img
add map loop0p1 (254:7): 0 114688 linear /dev/loop0 8192
add map loop0p2 (254:8): 0 6277120 linear /dev/loop0 122880
Create chroot directory:
# mkdir -p /data/lab/pi/emu/wheezy-raspbian-img
Mount image partitions:
# mount /dev/mapper/loop0p2 /data/lab/pi/emu/wheezy-raspbian-img/
# mount /dev/mapper/loop0p1 /data/lab/pi/emu/wheezy-raspbian-img/boot/
Mount service partitions from host system into chroot directory:
# for d in dev proc sys dev/pts; do mount -o bind /${d} /data/lab/pi/emu/wheezy-raspbian-img/${d}; done
Create a list of relevant mounted filesystems (so we can use df
for example):
# egrep "rootfs|boot" /etc/mtab | sed 's/\/data\/lab\/pi\/emu\/wheezy-raspbian-img//' > /data/lab/pi/emu/wheezy-raspbian-img/etc/mtab
Chroot into it:
# chroot /data/lab/pi/emu/wheezy-raspbian-img/
Validate setup (note the architecture change):
# uname -a
Linux lab0 3.14.16 #1 SMP Sat Aug 9 23:54:07 EEST 2014 armv7l GNU/Linux
From within chroot try some stuff:
# apt-get update
qemu: uncaught target signal 4 (Illegal instruction) - core dumped
Illegal instruction
According this
and this
culprit is /etc/ld.so.preload . Comment out "/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so"
line:
#/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
After that everyting works. But we are limited to the partition size of the image:
# df -h
Filesystem Size Used Avail Use% Mounted on
rootfs 2.9G 2.2G 533M 81% /
/dev/mapper/loop0p1 56M 9.7M 47M 18% /boot
We want to resize/expand rootfs. First - cleanup:
# umount /data/lab/pi/emu/wheezy-raspbian-img/{proc,sys,dev/pts,dev,boot,.}
# kpartx -d 2014-12-24-wheezy-raspbian.img
Add 5 more gigs to the image (should be enough):
# qemu-img resize 2014-12-24-wheezy-raspbian.img +5G
Image resized.
Rotfs is ext4, not supported by the parted at the moment, so, the only way to resize partition is delete it via fdisk, and reate a new one with the same start boundaries, but different size. We can run fdisk directly on an image:
# fdisk 2014-12-24-wheezy-raspbian.img
Command (m for help): p
Disk 2014-12-24-wheezy-raspbian.img: 8645 MB, 8645509120 bytes
255 heads, 63 sectors/track, 1051 cylinders, total 16885760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c45c9
Device Boot Start End Blocks Id System
2014-12-24-wheezy-raspbian.img1 8192 122879 57344 c W95 FAT32 (LBA)
2014-12-24-wheezy-raspbian.img2 122880 6399999 3138560 83 Linux
Command (m for help): d
Partition number (1-4): 2
Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p): p
Partition number (1-4, default 2):
Using default value 2
First sector (63-16885759, default 63): 122880
Last sector, +sectors or +size{K,M,G} (122880-16885759, default 16885759):
Using default value 16885759
Command (m for help): p
Disk 2014-12-24-wheezy-raspbian.img: 8645 MB, 8645509120 bytes
255 heads, 63 sectors/track, 1051 cylinders, total 16885760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c45c9
Device Boot Start End Blocks Id System
2014-12-24-wheezy-raspbian.img1 8192 122879 57344 c W95 FAT32 (LBA)
Partition 1 does not end on cylinder boundary.
2014-12-24-wheezy-raspbian.img2 122880 16885759 8381440 83 Linux
Command (m for help): w
The partition table has been altered!
Syncing disks.
Resize the actuall filesystem (you need to map it to the loop device again):
# kpartx -a -v 2014-12-24-wheezy-raspbian.img
# e2fsck -f /dev/mapper/loop0p2
# resize2fs /dev/mapper/loop0p2
Mount it back and use as per above.
Debootstrap approach
Raspbian is Debian, and we can use debootstrap to create a directory tree for chroot - in this case we are not limited to any image size.
# apt-get install debootstrap
# mkdir raspbian-armhf
# wget http://archive.raspbian.org/raspbian.public.key -O - | apt-key add -
# qemu-debootstrap --keyring /etc/apt/trusted.gpg --arch armhf wheezy raspbian-armhf http://archive.raspbian.org/raspbian
The rest is the same as above. Mount:
# for d in dev proc sys dev/pts; do mount -o bind /${d} /data/lab/pi/emu/raspbian-armhf/${d}; done
Chroot:
# chroot raspbian-armhf
Validate:
# uname -a
Linux dom0 3.14.16 #1 SMP Sat Aug 9 23:54:07 EEST 2014 armv7l GNU/Linux
Tune:
# echo "deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi" > /etc/apt/sources.list
# wget http://archive.raspbian.org/raspbian.public.key -O - | apt-key add -
# apt-get update
# apt-get upgrade