samedi 6 juin 2015

[android] Building the android kernel for the x86_64 emulator

See previous post for more details: Here

my avd is Nexus_5_API_22
export my_avd=Nexus_5_API_22
What is the version of linux running on the x86_64 emulator ?
adb shell dmesg| grep "Linux version"

<5>[    0.000000] Linux version 3.10.0+ (tic@debian) (gcc version 4.9.2 (Debian 4.9.2-10) ) #2 PREEMPT Fri Jun 5 15:07:50 CEST 2015
Oh it's a more recent one than the i386 version!
git checkout remotes/origin/android-goldfish-3.10 -b emu_x86_64
ls arch/x86/configs
i386_defconfig      i386_ranchu_defconfig  x86_64_emu_defconfig
i386_emu_defconfig  x86_64_defconfig       x86_64_ranchu_defconfig
There are more config than before, great it means it is actively developped :)

Ranchu is the successor of goldfish, based on a more resent version of qemu. Linaro team is working on it, It should replace Goldfish in due time. (It even support the android arm64 platform :) )

But for now the emulator which ships with android is goldfish so let's stay with that.
ARCH=x86_64
make x86_64_emu_defconfig
make -j`nproc`
Give it a try:
emulator -kernel arch/x86/bzImage -avd $my_avd -qemu -enable-kvm
I couldn't get it to work with this exact commandline, so I used
emulator64-x86 -kernel arch/x86/boot/bzImage -avd $my_avd -gpu off -qemu --enable-kvm 
That's all! Now developp you own modules ;)

[android] Building the android kernel for the i386 emulator

To build for x86-64, check this article:
http://tic-le-polard.blogspot.fr/2015/06/android-building-android-kernel-for_6.html

Get the goldfish kernel.
git clone https://android.googlesource.com/kernel/goldfish
The master branch is empty, you need to find a commit where arch/x86/configs/goldfish_defconfig exist because the CONFIG options you need to build the kernel correctly for the emulation platform are in it.
Let's list all the different branch of the kernel
git branch -a 
 
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/android-3.10
  remotes/origin/android-3.4
  remotes/origin/android-goldfish-2.6.29
  remotes/origin/android-goldfish-3.10
  remotes/origin/android-goldfish-3.4
  remotes/origin/linux-goldfish-3.0-wip
  remotes/origin/master

Now check what version of the kernel the emulator is running:
Follow the android guide to get android studio : http://developer.android.com/tools/studio/index.html

Create a hello world app and run it in the emulator and create an x86 avd.
(You can also directly use the sdk tools to create them, but here everything is pretty much automated and the configuration is done for you.)

Use adb to connect to the emulator.
Add to your path the platform-tools and tools directory from the sdk directory.
adb devices # list all emulator instances
adb shell dmesg| grep "Linux version"

<5>[    0.000000] Linux version 3.4.67+ (digit@tyrion.par.corp.google.com) (gcc version 4.8 (GCC) ) #3 PREEMPT Tue Sep 16 19:46:22 CEST 2014
Let's get the 3.4 version of the goldfish kernel. It is proved to work :)
git checkout remotes/origin/android-goldfish-3.4 -b emu_x86

ls arch/x86/configs
goldfish_defconfig  i386_defconfig  x86_64_defconfig
Yeah, there is a goldfish config
export ARCH=x86
make goldfish_defconfig
make -j`nproc`
That's it you should have a working kernel for the emulator to test it:
emulator -list-avds
emulator -kernel arch/x86/bzImage -avd $your_avd -qemu -enable-kvm
You are now using your own kernel, you can compile your own modules for it, etc.

samedi 18 avril 2015

[qemu] Spice your qemu up

Spice is a free and open-source alternative to the VNC protocol. It is actually faster and safer. It enables you to use a remote viewer on your application.

In the host:
apt-get install virt-viewer
This will install remote-viewer, don't use spicec as it is deprecated.

In the guest VM:
apt-get install spice-vdagent
Now let's boot our VM using spice for the display.
qemu-system-x86_64 -drive file=debian_bootstrap2.qcow2,cache=none,if=virtio \ 
--enable-kvm \ 
-net nic,model=virtio,macaddr=52:54:00:12:34:58 \ 
-net vde,sock=/tmp/switch1.ctl -cpu host \ 
-smp 4 -m 2G \ 
-vga qxl -spice port=5900,addr=127.0.0.1,disable-ticketing \ 
-device virtio-serial-pci \ 
-device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 \ 
-chardev spicevmc,id=spicechannel0,name=vdagent
There is a lot to process here. all the options before the -vga are my usual options, enabling the net via vde (see my post on this here) and enabling virtio for everything.

The -smp 4 option tell kvm to use 4 cores on my computer.

I use -cpu host because I don't want some feature to disappear in the emulation, also It might be faster.

The -vga qxl is the recommanded vga for use with the spice protocol.

The -spice gives the Qemu integrated spice server its configuration. Here we specify the port and the adress of the server. As this is a local setup, we don't need a certified connection, so I disabled the ticketing.

If your VM is on your server, you might want to reconsider this choice as anyone can hijack the connection if you are not careful. Hackers are hardcore people, they are waiting for you in the internet, wearing ski masks and typing in the most awkward position. So encrypt your communications if you don't want to be a victim of these kind of people.






I will describe the use of spice with certificates in another article as you need to set up a CA to get it working.

With these options, you can already use the spice procol to get your virtual machine exported display. In fact you don't need to install the spice-vdagent for that.

But you can get more: copy and paste between the host and the vm and automatic resizing of X.

The -device virtio-serial-pci is the bus where all the virtserialport are plugged, so you need it to declare the use of a virtserialport device.

The -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 is the actual port plugged in the virtio serial bus. its name enable the guest agent to connect to it.

The -chardev spicevmc,id=spicechannel0,name=vdagent is the character device to which the spice client will connect to communicate with guest agent using the virtio serial bus.

Now you can connect to your VM using:
remote-viever spice://127.0.0.1:5900
Have fun :)

Links

http://www.linux-kvm.org/page/SPICE
https://wiki.archlinux.org/index.php/QEMU#Spice_support

mardi 14 avril 2015

[System] Patching an initramfs


Extract the cpio filesystem in a directory, create or modify files, recreate a new cpio archive.

CPIO_FILE="rootfs.cpio"
CPIO_DIR="/tmp/yourCpioDir"
#Extract the cpio archive in the CPIO_DIR
mkdir $CPIO_DIR
pushd $CPIO_DIR
fakeroot cpio -i < $CPIO_FILE
#Apply your changes
#Recreate the cpio archive
find . | cpio --create --format='newc' > $CPIO_FILE 

lundi 13 avril 2015

[System] Use buildroot to create an embedded distribution

Get the buildroot git repository:
git clone git://git.buildroot.net/buildroot
Follow blindly the README sacred words.
make list-defconfigs
Let's start with a defconfig of the vexpress arm machine
make qemu_arm_vexpress_defconfig
The versatile defconfig doesn't support device tree, and it's a pain in the ass to make it work, moreover the vexpress board support is better in qemu.

launch the build:
make
Build an awesome card castle.
Come back when it's finished.

Read the readme.txt at board/qemu/arm_vexpress
Do what you are told to do.
qemu-system-arm -M vexpress-a9 -kernel output/images/zImage -drive file=output/images/rootfs.ext2,if=sd -append "console=ttyAMA0,115200 root=/dev/mmcblk0" -serial stdio -net nic,model=lan9118 -net user

Thanks the creator of buildroot in your mind because this commandline is difficult to find on first try. Tweak it to make it work for you. You can add the -nographic option if you don't want the framebuffer to show.

That's it you've created a complete and minimal embedded system. Now you will want to customize it, change the kernel options to use the device tree for example or add the openssh server package to your rootfs. Explore your options using the make menuconfig  command.

[Trivia] Visualize your git history with gource

Find the source here:
https://github.com/acaudwell/Gource

The compilation is pretty straight forward:

./autogen
./configure
# fix the dependencies which are missing, probably sdl2.
make -j `nproc`
make install

That's it.

Go in your git repository (or svn, bazar?, whatever)
gource

You can now see your project grow up, get his first girlfriend, move out of your computer, buy a new repository at github city, etc.

A snapshot of the buildroot project

dimanche 12 avril 2015

[qemu] Create a complete system image without booting in the emulator

Create an empty disk image:
qemu-img create -f qcow2 debian_bootstrap.qcow2 10G
Use the nbd kernel module (Network Block Device) to create and acceed partitions on the qcow2 disk image.
modinfo nbd

filename:       /lib/modules/3.18.4-1-ARCH/kernel/drivers/block/nbd.ko.gz
license:        GPL
description:    Network Block Device
depends:      
intree:         Y
vermagic:       3.18.4-1-ARCH SMP preempt mod_unload modversions
parm:           nbds_max:number of network block devices to initialize (default: 16) (int)
parm:           max_part:number of partitions per device (default: 0) (int)
parm:           debugflags:flags for controlling debug output (int)

sudo modprobe nbd max_part=16 
Associate the qcow2 disk image to the /dev/nbd0 disk node.
sudo qemu-nbd -c /dev/nbd0 debian_bootstrap.qcow2 
Create your partitions:
sudo parted /dev/nbd0
Or to get a swap + rootfs partition scheme, you can use:
sfdisk /dev/nbd0 -D -uM << EOF
,512,82
;
EOF
If you used parted with gpt partitions, you need to set up the first partition as a 2MB partition with the bios_grub flag set If no new disk file nbd0p1 shows up, you can usethe following command to force then to appear.
 partx -a /dev/nbd0
Format your partitions with the filesystems of your choice. (You can also do this in parted if you wish)
mkswap /dev/nbd0p1
mkfs.ext4 /dev/nbd0p2
Mount your root file system, you are almost ready to bootstrap a new debian in your qcow2 disk image.
mount /dev/nbd0p2 /mnt/
That's it, debootstrap this little rootfs ! (Choose the closest ftp to you to speed up the download)
debootstrap --include=less,locales-all,vim,sudo,openssh-server stable /mnt http://ftp.us.debian.org/debian
chroot in your new debian rootfs:
mount --bind /dev/ /mnt/dev
LANG=C chroot /mnt/ /bin/bash
mount -t proc none /proc
mount -t sysfs none /sys
You might need to set the path correctly if your host distribution doesn't use the same binaries path
PATH=$PATH:/bin:/sbin:/usr/sbin:/usr/bin
Install the latest kernel and grub-pc (beware, you want to install grub2 and not grub legacy)
apt-get install linux-image-amd64 grub-pc
When installing grub, choose the /dev/nbp0p2, you wouldn't want to install it on your own disk.
# To be sure grub is installed ^^
grub-install /dev/nbd0
update-grub
Set a passwd for root
passwd root
exit the chroot
umount /proc/ /sys/ /dev/
exit
# Some say you can fix the grub installation with those commands. Didn't work for me.
grub-install /dev/nbd0 --root-directory=/mnt --modules="biosdisk part_msdos" 
sed -e 's/nbd0p2/sda2/g' boot/grub/grub.cfg > boot/grub/grub.cfg
# I think if you want to have a working grub, just write the configuration yourself, 
# I fix this by hand at the first boot.
If you have other partition than the rootfs, you will need to edit your fstab.conf accordingly.
You are finished, clean your mess.
umount /mnt
qemu-nbd -d /dev/nbd0 
Start your VM You might get the grub console instead of a beautiful grub menu because the grub configuration is still broken! To launch linux you can do:
ls
#identify the rootfs partition
ls (hd0,gpt2)
ls (hd0,gpt2)/
#You should see your filesystem here, names can change
set root = (hd0,gpt2)
linux /boot/vmlinux-... root=/dev/sda2 # very important, specify your rootfs partition here
initrd boot/initrd-...
boot
Launch your newly created VM ! update-grub inside to fix the grub, this will eventually fix your grub.