mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
qemu: 9p host guest directory sharing
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,6 +9,7 @@
|
||||
.tmp_versions
|
||||
/rootfs_overlay/etc/init.d/S99
|
||||
/rootfs_overlay/ignore.sh
|
||||
/9p
|
||||
Module.symvers
|
||||
README.html
|
||||
modules.order
|
||||
|
||||
252
README.adoc
252
README.adoc
@@ -342,49 +342,6 @@ When dealing with real boards, extra command line options are provided on some m
|
||||
* GRUB configuration files: https://askubuntu.com/questions/19486/how-do-i-add-a-kernel-boot-parameter
|
||||
* Raspberry pi `/boot/cmdline.txt` on a magic partition: https://raspberrypi.stackexchange.com/questions/14839/how-to-change-the-kernel-commandline-for-archlinuxarm-on-raspberry-pi-effectly
|
||||
|
||||
=== QEMU GUI is unresponsive
|
||||
|
||||
Sometimes in Ubuntu 14.04, after the QEMU SDL GUI starts, it does not get updated after keyboard strokes, and there are artifacts like disappearing text.
|
||||
|
||||
We have not managed to track this problem down yet, but the following workaround always works:
|
||||
|
||||
....
|
||||
Ctrl + Shift + U
|
||||
Ctrl + C
|
||||
root
|
||||
....
|
||||
|
||||
This started happening when we switched to building QEMU through Buildroot, and has not been observed on later Ubuntu.
|
||||
|
||||
Using text mode is another workaround if you don't need GUI features.
|
||||
|
||||
=== Debug QEMU
|
||||
|
||||
When you start interacting with QEMU hardware, it is useful to see what is going on inside of QEMU itself.
|
||||
|
||||
This is of course trivial since QEMU is just an userland program on the host, but we make it a bit easier with:
|
||||
|
||||
....
|
||||
./run -D
|
||||
....
|
||||
|
||||
Then you could:
|
||||
|
||||
....
|
||||
b edu_mmio_read
|
||||
c
|
||||
....
|
||||
|
||||
And in QEMU:
|
||||
|
||||
....
|
||||
/pci.sh
|
||||
....
|
||||
|
||||
Just make sure that you never click inside the QEMU window when doing that, otherwise you mouse gets captured forever, and the only solution I can find is to go to a TTY with Ctrl + Alt + F1 and `kill` QEMU.
|
||||
|
||||
You can still send key presses to QEMU however even without the mouse capture, just either click on the title bar, or alt tab to give it focus.
|
||||
|
||||
=== What command was actually run?
|
||||
|
||||
When asking for help on upstream repositories outside of this repository, you will need to provide the commands that you are running in detail without referencing our scripts.
|
||||
@@ -1433,47 +1390,6 @@ TODO: what do `+` and `!` mean?
|
||||
|
||||
Each `enable` under the `events/` tree enables a certain set of functions, the higher the `enable` more functions are enabled.
|
||||
|
||||
== QEMU user mode
|
||||
|
||||
This has nothing to do with the Linux kernel, but it is cool:
|
||||
|
||||
....
|
||||
sudo apt-get install qemu-user
|
||||
./build -a arm
|
||||
cd buildroot/output.arm~/target
|
||||
qemu-arm -L . bin/ls
|
||||
....
|
||||
|
||||
This uses QEMU's user-mode emulation mode that allows us to run cross-compiled userland programs directly on the host.
|
||||
|
||||
The reason this is cool, is that `ls` is not statically compiled, but since we have the Buildroot image, we are still able to find the shared linker and the shared library at the given path.
|
||||
|
||||
In other words, much cooler than:
|
||||
|
||||
....
|
||||
arm-linux-gnueabi-gcc -o hello -static hello.c
|
||||
qemu-arm hello
|
||||
....
|
||||
|
||||
It is also possible to compile QEMU user mode from source with `BR2_PACKAGE_HOST_QEMU_LINUX_USER_MODE=y`, but then your compilation will likely fail with:
|
||||
|
||||
....
|
||||
package/qemu/qemu.mk:110: *** "Refusing to build qemu-user: target Linux version newer than host's.". Stop.
|
||||
....
|
||||
|
||||
since we are using a bleeding edge kernel, which is a sanity check in the Buildroot QEMU package.
|
||||
|
||||
Anyways, this warns us that the userland emulation will likely not be reliable, which is good to know. TODO: where is it documented the host kernel must be as new as the target one?
|
||||
|
||||
GDB step debugging is also possible with:
|
||||
|
||||
....
|
||||
qemu-arm -g 1234 -L . bin/ls
|
||||
../host/usr/bin/arm-buildroot-linux-uclibcgnueabi-gdb -ex 'target remote localhost:1234'
|
||||
....
|
||||
|
||||
TODO: find source. Lazy now.
|
||||
|
||||
== Snapshot
|
||||
|
||||
https://stackoverflow.com/questions/40227651/does-qemu-emulator-have-checkpoint-function/48724371#48724371
|
||||
@@ -1549,7 +1465,161 @@ This is useful to learn:
|
||||
* how to create new hardware models for QEMU. Overview: https://stackoverflow.com/questions/28315265/how-to-add-a-new-device-in-qemu-source-code
|
||||
* how the Linux kernel interacts with hardware
|
||||
|
||||
To get started, have a look at the "Hardware device drivers" secion under link:kernel_module/README.adoc[], and try to run those modules, and then grep the QEMU source code.
|
||||
To get started, have a look at the "Hardware device drivers" section under link:kernel_module/README.adoc[], and try to run those modules, and then grep the QEMU source code.
|
||||
|
||||
== QEMU
|
||||
|
||||
Some QEMU specific features to play with and limitations to cry over.
|
||||
|
||||
=== 9P
|
||||
|
||||
https://superuser.com/questions/628169/how-to-share-a-directory-with-the-host-without-networking-in-qemu
|
||||
|
||||
With networking, it's boring, we can just use any of the old tools like sshfs and NFS.
|
||||
|
||||
As usual, we have already set everything up for you. On host:
|
||||
|
||||
....
|
||||
cd 9p
|
||||
uname -a > host
|
||||
....
|
||||
|
||||
Guest:
|
||||
|
||||
....
|
||||
cd /mnt/9p
|
||||
cat host
|
||||
uname -a > guest
|
||||
....
|
||||
|
||||
Host:
|
||||
|
||||
....
|
||||
cat guest
|
||||
....
|
||||
|
||||
The main ingredients for this are:
|
||||
|
||||
* `9P` settings in our link:kernel_config_fragment[]
|
||||
* `9p` entry on our link:rootfs_overlay/etc/fstab[]
|
||||
+
|
||||
Alternatively, you could also mount your own with:
|
||||
+
|
||||
....
|
||||
mkdir /mnt/my9p
|
||||
mount -t 9p -o trans=virtio,version=9p2000.L host0 /mnt/my9p
|
||||
....
|
||||
* Launch QEMU with `-virtfs` as in your link:run[] script
|
||||
+
|
||||
When we tried:
|
||||
+
|
||||
....
|
||||
security_model=mapped
|
||||
....
|
||||
+
|
||||
writes from guest failed due to user mismatch problems: https://serverfault.com/questions/342801/read-write-access-for-passthrough-9p-filesystems-with-libvirt-qemu
|
||||
|
||||
The feature is documented at: https://wiki.qemu.org/Documentation/9psetup
|
||||
|
||||
TODO: not working on `arm`, manual mount failed with:
|
||||
|
||||
....
|
||||
mount: mounting host0 on /mnt/my9p failed: No such file or directory
|
||||
....
|
||||
|
||||
and on `aarch64`:
|
||||
|
||||
....
|
||||
mount: mounting host0 on /mnt/my9p failed: Invalid argument
|
||||
....
|
||||
|
||||
A few hits:
|
||||
|
||||
* https://superuser.com/questions/502205/libvirt-9p-kvm-mount-in-fstab-fails-to-mount-at-boot-time
|
||||
|
||||
=== QEMU user mode
|
||||
|
||||
This has nothing to do with the Linux kernel, but it is cool:
|
||||
|
||||
....
|
||||
sudo apt-get install qemu-user
|
||||
./build -a arm
|
||||
cd buildroot/output.arm~/target
|
||||
qemu-arm -L . bin/ls
|
||||
....
|
||||
|
||||
This uses QEMU's user-mode emulation mode that allows us to run cross-compiled userland programs directly on the host.
|
||||
|
||||
The reason this is cool, is that `ls` is not statically compiled, but since we have the Buildroot image, we are still able to find the shared linker and the shared library at the given path.
|
||||
|
||||
In other words, much cooler than:
|
||||
|
||||
....
|
||||
arm-linux-gnueabi-gcc -o hello -static hello.c
|
||||
qemu-arm hello
|
||||
....
|
||||
|
||||
It is also possible to compile QEMU user mode from source with `BR2_PACKAGE_HOST_QEMU_LINUX_USER_MODE=y`, but then your compilation will likely fail with:
|
||||
|
||||
....
|
||||
package/qemu/qemu.mk:110: *** "Refusing to build qemu-user: target Linux version newer than host's.". Stop.
|
||||
....
|
||||
|
||||
since we are using a bleeding edge kernel, which is a sanity check in the Buildroot QEMU package.
|
||||
|
||||
Anyways, this warns us that the userland emulation will likely not be reliable, which is good to know. TODO: where is it documented the host kernel must be as new as the target one?
|
||||
|
||||
GDB step debugging is also possible with:
|
||||
|
||||
....
|
||||
qemu-arm -g 1234 -L . bin/ls
|
||||
../host/usr/bin/arm-buildroot-linux-uclibcgnueabi-gdb -ex 'target remote localhost:1234'
|
||||
....
|
||||
|
||||
TODO: find source. Lazy now.
|
||||
|
||||
=== Debug QEMU
|
||||
|
||||
When you start interacting with QEMU hardware, it is useful to see what is going on inside of QEMU itself.
|
||||
|
||||
This is of course trivial since QEMU is just an userland program on the host, but we make it a bit easier with:
|
||||
|
||||
....
|
||||
./run -D
|
||||
....
|
||||
|
||||
Then you could:
|
||||
|
||||
....
|
||||
b edu_mmio_read
|
||||
c
|
||||
....
|
||||
|
||||
And in QEMU:
|
||||
|
||||
....
|
||||
/pci.sh
|
||||
....
|
||||
|
||||
Just make sure that you never click inside the QEMU window when doing that, otherwise you mouse gets captured forever, and the only solution I can find is to go to a TTY with Ctrl + Alt + F1 and `kill` QEMU.
|
||||
|
||||
You can still send key presses to QEMU however even without the mouse capture, just either click on the title bar, or alt tab to give it focus.
|
||||
|
||||
=== QEMU GUI is unresponsive
|
||||
|
||||
Sometimes in Ubuntu 14.04, after the QEMU SDL GUI starts, it does not get updated after keyboard strokes, and there are artifacts like disappearing text.
|
||||
|
||||
We have not managed to track this problem down yet, but the following workaround always works:
|
||||
|
||||
....
|
||||
Ctrl + Shift + U
|
||||
Ctrl + C
|
||||
root
|
||||
....
|
||||
|
||||
This started happening when we switched to building QEMU through Buildroot, and has not been observed on later Ubuntu.
|
||||
|
||||
Using text mode is another workaround if you don't need GUI features.
|
||||
|
||||
== gem5
|
||||
|
||||
@@ -2614,12 +2684,14 @@ Philosophy:
|
||||
|
||||
This project should be called "Linux kernel playground", like: https://github.com/Fuzion24/AndroidKernelExploitationPlayground maybe I'll rename it some day. Would semi conflict with: http://copr-fe.cloud.fedoraproject.org/coprs/jwboyer/kernel-playground/ though.
|
||||
|
||||
History:
|
||||
==== Fairy tale
|
||||
|
||||
____
|
||||
Once upon a time, there was a boy called Linus. Linus made a super fun toy, and since he was not very humble, decided to call it Linux.
|
||||
Once upon a time, there was a boy called Linus.
|
||||
|
||||
Linux was great, but it had one big problem: it was very difficult to learn how to play with it!
|
||||
Linus made a super fun toy, and since he was not very humble, decided to call it Linux.
|
||||
|
||||
Linux was an awesome toy, but it had one big problem: it was very difficult to learn how to play with it!
|
||||
|
||||
As a result, only some weird kids who were very bored ended up playing with Linux, and everyone thought those kids were very cool, in their own weird way.
|
||||
|
||||
@@ -2629,7 +2701,9 @@ A few years later, Ciro had grown up a bit, and by chance came across a very coo
|
||||
|
||||
Ciro noticed that if you used Buildroot together with Linux, Linux suddenly became very fun to play with!
|
||||
|
||||
So Ciro decided to explain to as many kids as possible how to use Buildroot to play with Linux, and everyone was happy.
|
||||
So Ciro decided to explain to as many kids as possible how to use Buildroot to play with Linux.
|
||||
|
||||
And so everyone was happy. Except some of the old weird kernel hackers who wanted to keep their mystique, but so be it.
|
||||
|
||||
THE END
|
||||
____
|
||||
|
||||
1
build
1
build
@@ -110,6 +110,7 @@ fi
|
||||
|
||||
cd "${root_dir}/kernel_module"
|
||||
./make-host.sh -j "$j" clean
|
||||
mkdir -p 9p
|
||||
cd "${buildroot_dir}"
|
||||
# HOST_QEMU_OPTS is a hack that happens to work because the QEMU package luckly uses += at all times.
|
||||
# It shouldn't be necessary in the first place: https://bugs.busybox.net/show_bug.cgi?id=9936
|
||||
|
||||
@@ -60,6 +60,13 @@ CONFIG_SCHED_TRACER=y
|
||||
CONFIG_STACK_TRACER=y
|
||||
CONFIG_TRACER_SNAPSHOT=y
|
||||
|
||||
# 9P
|
||||
CONFIG_9P_FS=y
|
||||
CONFIG_9P_FS_POSIX_ACL=y
|
||||
CONFIG_NET_9P=y
|
||||
CONFIG_NET_9P_DEBUG=y
|
||||
CONFIG_NET_9P_VIRTIO=y
|
||||
|
||||
## Networking
|
||||
|
||||
# Will everything blow up?
|
||||
|
||||
@@ -7,3 +7,4 @@ tmpfs /tmp tmpfs mode=1777 0 0
|
||||
tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0
|
||||
sysfs /sys sysfs defaults 0 0
|
||||
debugfs /sys/kernel/debug debugfs defaults 0 0
|
||||
host0 /mnt/9p 9p trans=virtio,version=9p2000.L 0 0
|
||||
|
||||
@@ -18,3 +18,4 @@ shift $(($OPTIND - 1))
|
||||
if ! "$net"; then
|
||||
rm -f "${target_dir}/etc/init.d/"S*network
|
||||
fi
|
||||
mkdir -p "${target_dir}/mnt/9p"
|
||||
|
||||
1
run
1
run
@@ -114,6 +114,7 @@ $buildroot_out_dir/host/usr/bin/qemu-system-${arch} \
|
||||
-monitor telnet::45454,server,nowait \
|
||||
-netdev user,hostfwd=tcp::45455-:45455,id=net0 \
|
||||
-smp $cpus \
|
||||
-virtfs local,path=9p,mount_tag=host0,security_model=mapped,id=host0 \
|
||||
"
|
||||
if $initrd; then
|
||||
extra_flags="$extra_flags -initrd '${images_dir}/rootfs.cpio'"
|
||||
|
||||
Reference in New Issue
Block a user