mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-26 03:31:36 +01:00
userland: add assembly support
Move arm assembly cheat here, and start some work on x86 cheat as well.
This commit is contained in:
762
README.adoc
762
README.adoc
@@ -422,7 +422,7 @@ index af583ce578..3cc341f303 100644
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
....
|
||||
|
||||
Finally, rebuild Binutils, userland and test our program with <<user-mode-setup>>:
|
||||
Finally, rebuild Binutils, userland and test our program with <<user-mode-simulation>>:
|
||||
|
||||
....
|
||||
./build-buildroot -- host-binutils-rebuild
|
||||
@@ -438,7 +438,7 @@ Tested on b60784d59bee993bf0de5cde6c6380dd69420dda + 1.
|
||||
|
||||
OK, now time to hack GCC.
|
||||
|
||||
For convenience, let's use the <<user-mode-setup>>.
|
||||
For convenience, let's use the <<user-mode-simulation>>.
|
||||
|
||||
If we run the program link:userland/gcc_hack.c[]:
|
||||
|
||||
@@ -929,6 +929,115 @@ sudo rmmod hello.ko
|
||||
dmesg
|
||||
....
|
||||
|
||||
=== Userland setup
|
||||
|
||||
==== About the userland setup
|
||||
|
||||
In order to test the kernel and emulators, userland content in the form of executables and scripts is of course required, and we store it mostly under:
|
||||
|
||||
* link:userland/[]
|
||||
* <<rootfs_overlay>>
|
||||
* <<add-new-buildroot-packages>>
|
||||
|
||||
When we started this repository, it only contained content that interacted very closely with the kernel, or that had required performance analysis.
|
||||
|
||||
However, we soon started to notice that this had an increasing overlap with other userland test repositories: we were duplicating build and test infrastructure and even some examples.
|
||||
|
||||
Therefore, we decided to consolidate other userland tutorials that we had scattered around into this repository.
|
||||
|
||||
Notable userland content included / moving into this repository includes:
|
||||
|
||||
* <<arm-userland>>
|
||||
* <<x86-userland>>
|
||||
* <<c>>
|
||||
* <<cpp>>
|
||||
* <<posix>>
|
||||
* https://github.com/cirosantilli/algorithm-cheat will be good to move here for performance analysis
|
||||
|
||||
==== Userland setup getting started
|
||||
|
||||
There are several ways to run our userland content, notably:
|
||||
|
||||
* natively on the host as shown at: <<userland-setup-getting-started-natively>>
|
||||
+
|
||||
Can only run examples compatible with your host architecture and OS, but has the fastest setup and runtimes.
|
||||
* from user mode simulation as shown at: <<qemu-user-mode-getting-started>>
|
||||
+
|
||||
Can run most examples, with the notable exception of examples that rely on kernel modules.
|
||||
* from full system simulation as shown at: <<qemu-buildroot-setup-getting-started>>.
|
||||
+
|
||||
This is the most reproducible and controlled environment, and all examples work there. But also the slower one to setup.
|
||||
|
||||
===== Userland setup getting started natively
|
||||
|
||||
With this setup, we will use the host toolchain and execute executables directly on the host.
|
||||
|
||||
No installation or toolchain build is reuqired, so you can just jump straight into it.
|
||||
|
||||
Build, run and example, and clean it in-tree with:
|
||||
|
||||
....
|
||||
cd userland
|
||||
./build
|
||||
./c/hello.out
|
||||
./build --clean
|
||||
....
|
||||
|
||||
Source: link:userland/c/hello.c[].
|
||||
|
||||
Or build just one directory:
|
||||
|
||||
....
|
||||
./build c
|
||||
....
|
||||
|
||||
or just one executable:
|
||||
|
||||
....
|
||||
./build c/hello
|
||||
....
|
||||
|
||||
Do a more clean out of tree build and run the program instead:
|
||||
|
||||
....
|
||||
./build-userland --gcc-which host --userland-build-id host
|
||||
"$(./getvar --userland-build-id host userland_build_dir)/hello.out"
|
||||
....
|
||||
|
||||
===== Userland setup getting started full system
|
||||
|
||||
First ensure that <<qemu-buildroot-setup>> is working.
|
||||
|
||||
After doing that setup, you can already execute your userland programs from inside QEMU: the only missing step is how to rebuild executables and run them.
|
||||
|
||||
And the answer is exactly analogous to what is shown at: <<your-first-kernel-module-hack>>
|
||||
|
||||
For example, if we modify link:userland/c/hello.c[] to print out something different, we can just rebuild it with:
|
||||
|
||||
....
|
||||
./build-userland
|
||||
....
|
||||
|
||||
Source: link:build-userland[]. `./build` calls that script automatically for us when doing the initial full build.
|
||||
|
||||
Now, run the program either without rebooting use the <<9p>> mount:
|
||||
|
||||
....
|
||||
/mnt/9p/out_rootfs_overlay/c/hello.out
|
||||
....
|
||||
|
||||
or shutdown QEMU, add the executable to the root filesystem:
|
||||
|
||||
....
|
||||
./build-buildroot
|
||||
....
|
||||
|
||||
reboot and use the root filesystem as usual:
|
||||
|
||||
....
|
||||
/c/hello.out
|
||||
....
|
||||
|
||||
=== Baremetal setup
|
||||
|
||||
==== About the baremetal setup
|
||||
@@ -1076,8 +1185,8 @@ But just stick to newer and better `VExpress_GEM5_V1` unless you have a good rea
|
||||
|
||||
When doing bare metal programming, it is likely that you will want to learn assembly language basics. Have a look at these tutorials for the userland part:
|
||||
|
||||
* https://github.com/cirosantilli/x86-assembly-cheat
|
||||
* https://github.com/cirosantilli/arm-assembly-cheat
|
||||
* <<x86-userland>>
|
||||
* <<arm-userland>>
|
||||
|
||||
For more information on baremetal, see the section: <<baremetal>>.
|
||||
|
||||
@@ -1086,14 +1195,6 @@ The following subjects are particularly important:
|
||||
* <<tracing>>
|
||||
* <<baremetal-gdb-step-debug>>
|
||||
|
||||
=== User mode setup
|
||||
|
||||
Much like <<baremetal-setup>>, this is another fun setup that does not require Buildroot or the Linux kernel.
|
||||
|
||||
Getting started at: <<qemu-user-mode-getting-started>>.
|
||||
|
||||
Introduction at: <<user-mode-simulation>>.
|
||||
|
||||
[[gdb]]
|
||||
== GDB step debug
|
||||
|
||||
@@ -1700,7 +1801,7 @@ since GDB does not know that libc is loaded.
|
||||
|
||||
This is the userland debug setup most likely to work, since at init time there is only one userland executable running.
|
||||
|
||||
For executables from the <<userland-directory>> such as link:userland/count.c[]:
|
||||
For executables from the link:userland/[] directory such as link:userland/count.c[]:
|
||||
|
||||
* Shell 1:
|
||||
+
|
||||
@@ -3288,7 +3389,7 @@ qw er
|
||||
|
||||
`./run --userland` path resolution is analogous to <<baremetal-setup-getting-started,that of `./run --baremetal`>>.
|
||||
|
||||
`./build user-mode-qemu` first builds Buildroot, and then runs `./build-userland`, which is further documented at: <<userland-directory>>. It also builds QEMU. If you ahve already done a <<qemu-buildroot-setup>> previously, this will be very fast.
|
||||
`./build user-mode-qemu` first builds Buildroot, and then runs `./build-userland`, which is further documented at: <<userland-setup>>. It also builds QEMU. If you ahve already done a <<qemu-buildroot-setup>> previously, this will be very fast.
|
||||
|
||||
If you modify the userland programs, rebuild simply with:
|
||||
|
||||
@@ -12033,6 +12134,295 @@ make CROSS_COMPILE_DIR=/usr/bin
|
||||
;
|
||||
....
|
||||
|
||||
== C
|
||||
|
||||
Programs under link:userland/c/[] are examples of link:https://en.wikipedia.org/wiki/ANSI_C[ANSI C] programming.
|
||||
|
||||
[[cpp]]
|
||||
== C++
|
||||
|
||||
Programs under link:userland/cpp/[] are examples of link:https://en.wikipedia.org/wiki/C%2B%2B#Standardization[ISO C] programming.
|
||||
|
||||
== POSIX
|
||||
|
||||
Programs under link:userland/posix/[] are examples of POSIX C programming.
|
||||
|
||||
What is POSIX:
|
||||
|
||||
* https://stackoverflow.com/questions/1780599/what-is-the-meaning-of-posix/31865755#31865755
|
||||
* https://unix.stackexchange.com/questions/11983/what-exactly-is-posix/220877#220877
|
||||
|
||||
== x86 userland
|
||||
|
||||
Programs under link:userland/arch/x86_64/[] are examples of x86 userland assembly programming.
|
||||
|
||||
Those examples are progressively being moved out of: https://github.com/cirosantilli/x86-assembly-cheat
|
||||
|
||||
== arm userland
|
||||
|
||||
Programs under:
|
||||
|
||||
* link:userland/arch/arm/[]
|
||||
* link:userland/arch/aarch64/[]
|
||||
|
||||
are examples of ARM userland assembly programming.
|
||||
|
||||
== Android
|
||||
|
||||
Remember: Android AOSP is a huge undocumented piece of bloatware. It's integration into this repo will likely never be super good.
|
||||
|
||||
Verbose setup description: https://stackoverflow.com/questions/1809774/how-to-compile-the-android-aosp-kernel-and-test-it-with-the-android-emulator/48310014#48310014
|
||||
|
||||
Download, build and run with the prebuilt AOSP QEMU emulator and the AOSP kernel:
|
||||
|
||||
....
|
||||
./build-android \
|
||||
--android-base-dir /path/to/your/hd \
|
||||
--android-version 8.1.0_r60 \
|
||||
download \
|
||||
build \
|
||||
;
|
||||
./run-android \
|
||||
--android-base-dir /path/to/your/hd \
|
||||
--android-version 8.1.0_r60 \
|
||||
;
|
||||
....
|
||||
|
||||
Sources:
|
||||
|
||||
* link:build-android[]
|
||||
* link:run-android[]
|
||||
|
||||
TODO how to hack the AOSP kernel, userland and emulator?
|
||||
|
||||
Other archs work as well as usual with `--arch` parameter. However, running in non-x86 is very slow due to the lack of KVM.
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
=== Android image structure
|
||||
|
||||
https://source.android.com/devices/bootloader/partitions-images
|
||||
|
||||
The messy AOSP generates a ton of images instead of just one.
|
||||
|
||||
When the emulator launches, we can see them through QEMU `-drive` arguments:
|
||||
|
||||
....
|
||||
emulator: argv[21] = "-initrd"
|
||||
emulator: argv[22] = "/data/aosp/8.1.0_r60/out/target/product/generic_x86_64/ramdisk.img"
|
||||
emulator: argv[23] = "-drive"
|
||||
emulator: argv[24] = "if=none,index=0,id=system,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/system-qemu.img,read-only"
|
||||
emulator: argv[25] = "-device"
|
||||
emulator: argv[26] = "virtio-blk-pci,drive=system,iothread=disk-iothread,modern-pio-notify"
|
||||
emulator: argv[27] = "-drive"
|
||||
emulator: argv[28] = "if=none,index=1,id=cache,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/cache.img.qcow2,overlap-check=none,cache=unsafe,l2-cache-size=1048576"
|
||||
emulator: argv[29] = "-device"
|
||||
emulator: argv[30] = "virtio-blk-pci,drive=cache,iothread=disk-iothread,modern-pio-notify"
|
||||
emulator: argv[31] = "-drive"
|
||||
emulator: argv[32] = "if=none,index=2,id=userdata,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/userdata-qemu.img.qcow2,overlap-check=none,cache=unsafe,l2-cache-size=1048576"
|
||||
emulator: argv[33] = "-device"
|
||||
emulator: argv[34] = "virtio-blk-pci,drive=userdata,iothread=disk-iothread,modern-pio-notify"
|
||||
emulator: argv[35] = "-drive"
|
||||
emulator: argv[36] = "if=none,index=3,id=encrypt,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/encryptionkey.img.qcow2,overlap-check=none,cache=unsafe,l2-cache-size=1048576"
|
||||
emulator: argv[37] = "-device"
|
||||
emulator: argv[38] = "virtio-blk-pci,drive=encrypt,iothread=disk-iothread,modern-pio-notify"
|
||||
emulator: argv[39] = "-drive"
|
||||
emulator: argv[40] = "if=none,index=4,id=vendor,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/vendor-qemu.img,read-only"
|
||||
emulator: argv[41] = "-device"
|
||||
emulator: argv[42] = "virtio-blk-pci,drive=vendor,iothread=disk-iothread,modern-pio-notify"
|
||||
....
|
||||
|
||||
The root directory is the <<initrd>> given on the QEMU CLI, which `/proc/mounts` reports at:
|
||||
|
||||
....
|
||||
rootfs on / type rootfs (ro,seclabel,size=886392k,nr_inodes=221598)
|
||||
....
|
||||
|
||||
This contains the <<android-init>>, which through `.rc` must be mounting mounts the drives int o the right places TODO find exact point.
|
||||
|
||||
The drive order is:
|
||||
|
||||
....
|
||||
system
|
||||
cache
|
||||
userdata
|
||||
encryptionkey
|
||||
vendor-qemu
|
||||
....
|
||||
|
||||
Then, on the terminal:
|
||||
|
||||
....
|
||||
mount | grep vd
|
||||
....
|
||||
|
||||
gives:
|
||||
|
||||
....
|
||||
/dev/block/vda1 on /system type ext4 (ro,seclabel,relatime,data=ordered)
|
||||
/dev/block/vde1 on /vendor type ext4 (ro,seclabel,relatime,data=ordered)
|
||||
/dev/block/vdb on /cache type ext4 (rw,seclabel,nosuid,nodev,noatime,errors=panic,data=ordered)
|
||||
....
|
||||
|
||||
and we see that the order of `vda`, `vdb`, etc. matches that in which `-drive` were given to QEMU.
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
==== Android images read-only
|
||||
|
||||
From `mount`, we can see that some of the mounted images are `ro`.
|
||||
|
||||
Basically, every image that was given to QEMU as qcow2 is writable, and that qcow2 is an overlay over the actual original image.
|
||||
|
||||
In order to make `/system` and `/vendor` writable by using qcow2 for them as well, we must use the `-writable-system` option:
|
||||
|
||||
....
|
||||
./run-android -- -writable-system
|
||||
....
|
||||
|
||||
* https://android.stackexchange.com/questions/110927/how-to-mount-system-rewritable-or-read-only-rw-ro/207200#207200
|
||||
* https://stackoverflow.com/questions/13089694/adb-remount-permission-denied-but-able-to-access-super-user-in-shell-android/43163693#43163693
|
||||
|
||||
then:
|
||||
|
||||
....
|
||||
su
|
||||
mount -o rw,remount /system
|
||||
date >/system/a
|
||||
....
|
||||
|
||||
Now reboot, and relaunch with `-writable-system` once again to pick up the modified qcow2 images:
|
||||
|
||||
....
|
||||
./run-android -- -writable-system
|
||||
....
|
||||
|
||||
and the newly created file is still there:
|
||||
|
||||
....
|
||||
date >/system/a
|
||||
....
|
||||
|
||||
`/system` and `/vendor` can be nuked quickly with:
|
||||
|
||||
....
|
||||
./build-android --extra-args snod
|
||||
./build-android --extra-args vnod
|
||||
....
|
||||
|
||||
as mentioned at: https://stackoverflow.com/questions/29023406/how-to-just-build-android-system-image and on:
|
||||
|
||||
....
|
||||
./build-android --extra-args help
|
||||
....
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
==== Android /data partition
|
||||
|
||||
When I install an app like F-Droid, it goes under `/data` according to:
|
||||
|
||||
....
|
||||
find / -iname '*fdroid*'
|
||||
....
|
||||
|
||||
and it <<disk-persistency,persists across boots>>.
|
||||
|
||||
`/data` is behind a RW LVM device:
|
||||
|
||||
....
|
||||
/dev/block/dm-0 on /data type ext4 (rw,seclabel,nosuid,nodev,noatime,errors=panic,data=ordered)
|
||||
....
|
||||
|
||||
but TODO I can't find where it comes from since I don't have the CLI tools mentioned at:
|
||||
|
||||
* https://superuser.com/questions/131519/what-is-this-dm-0-device
|
||||
* https://unix.stackexchange.com/questions/185057/where-does-lvm-store-its-configuration
|
||||
|
||||
However, by looking at:
|
||||
|
||||
....
|
||||
./run-android -- -help
|
||||
....
|
||||
|
||||
we see:
|
||||
|
||||
....
|
||||
-data <file> data image (default <datadir>/userdata-qemu.img
|
||||
....
|
||||
|
||||
which confirms the suspicion that this data goes in `userdata-qemu.img`.
|
||||
|
||||
To reset images to their original state, just remove the qcow2 overlay and regenerate it: https://stackoverflow.com/questions/54446680/how-to-reset-the-userdata-image-when-building-android-aosp-and-running-it-on-the
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
=== Install Android apps
|
||||
|
||||
I don't know how to download files from the web on Vanilla android, the default browser does not download anything, and there is no `wget`:
|
||||
|
||||
* https://android.stackexchange.com/questions/6984/how-to-download-files-from-the-web-in-the-android-browser
|
||||
* https://stackoverflow.com/questions/26775079/wget-in-android-terminal
|
||||
|
||||
Installing with `adb install` does however work: https://stackoverflow.com/questions/7076240/install-an-apk-file-from-command-prompt
|
||||
|
||||
link:https://f-droid.org[F-Droid] installed fine like that, however it does not have permission to install apps: https://www.maketecheasier.com/install-apps-from-unknown-sources-android/
|
||||
|
||||
And the `Settings` app crashes so I can't change it, logcat contains:
|
||||
|
||||
....
|
||||
No service published for: wifip2p
|
||||
....
|
||||
|
||||
which is mentioned at: https://stackoverflow.com/questions/47839955/android-8-settings-app-crashes-on-emulator-with-clean-aosp-build
|
||||
|
||||
We also tried to enable it from the command line with:
|
||||
|
||||
....
|
||||
settings put secure install_non_market_apps 1
|
||||
....
|
||||
|
||||
as mentioned at: https://android.stackexchange.com/questions/77280/allow-unknown-sources-from-terminal-without-going-to-settings-app but it didn't work either.
|
||||
|
||||
No person alive seems to know how to pre-install apps on AOSP: https://stackoverflow.com/questions/6249458/pre-installing-android-application
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
=== Android init
|
||||
|
||||
For Linux in general, see: <<init>>.
|
||||
|
||||
The `/init` executable interprets the `/init.rc` files, which is in a custom Android init system language: https://android.googlesource.com/platform/system/core/+/ee0e63f71d90537bb0570e77aa8a699cc222cfaf/init/README.md
|
||||
|
||||
The top of that file then sources other `.rc` files present on the root directory:
|
||||
|
||||
....
|
||||
import /init.environ.rc
|
||||
import /init.usb.rc
|
||||
import /init.${ro.hardware}.rc
|
||||
import /vendor/etc/init/hw/init.${ro.hardware}.rc
|
||||
import /init.usb.configfs.rc
|
||||
import /init.${ro.zygote}.rc
|
||||
....
|
||||
|
||||
TODO: how is `ro.hardware` determined? https://stackoverflow.com/questions/20572781/android-boot-where-is-the-init-hardware-rc-read-in-init-c-where-are-servic It is a system property and can be obtained with:
|
||||
|
||||
....
|
||||
getprop ro.hardware
|
||||
....
|
||||
|
||||
This gives:
|
||||
|
||||
....
|
||||
ranchu
|
||||
....
|
||||
|
||||
which is the codename for the QEMU virtual platform we are running on: https://www.oreilly.com/library/view/android-system-programming/9781787125360/9736a97c-cd09-40c3-b14d-955717648302.xhtml
|
||||
|
||||
TODO: is it possible to add a custom `.rc` file without modifying the initrd that <<android-image-structure,gets mounted on root>>? https://stackoverflow.com/questions/9768103/make-persistent-changes-to-init-rc
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
== Benchmark this repo
|
||||
|
||||
TODO: didn't fully port during refactor after 3b0a343647bed577586989fb702b760bd280844a. Reimplementing should not be hard.
|
||||
@@ -12316,266 +12706,6 @@ gem5:
|
||||
** https://stackoverflow.com/questions/47997565/gem5-system-requirements-for-decent-performance/48941793#48941793
|
||||
** https://github.com/gem5/gem5/issues/25
|
||||
|
||||
== WIP
|
||||
|
||||
Big new features that are not yet working.
|
||||
|
||||
=== Android
|
||||
|
||||
Remember: Android AOSP is a huge undocumented piece of bloatware. It's integration into this repo will likely never be super good.
|
||||
|
||||
Verbose setup description: https://stackoverflow.com/questions/1809774/how-to-compile-the-android-aosp-kernel-and-test-it-with-the-android-emulator/48310014#48310014
|
||||
|
||||
Download, build and run with the prebuilt AOSP QEMU emulator and the AOSP kernel:
|
||||
|
||||
....
|
||||
./build-android \
|
||||
--android-base-dir /path/to/your/hd \
|
||||
--android-version 8.1.0_r60 \
|
||||
download \
|
||||
build \
|
||||
;
|
||||
./run-android \
|
||||
--android-base-dir /path/to/your/hd \
|
||||
--android-version 8.1.0_r60 \
|
||||
;
|
||||
....
|
||||
|
||||
Sources:
|
||||
|
||||
* link:build-android[]
|
||||
* link:run-android[]
|
||||
|
||||
TODO how to hack the AOSP kernel, userland and emulator?
|
||||
|
||||
Other archs work as well as usual with `--arch` parameter. However, running in non-x86 is very slow due to the lack of KVM.
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
==== Android image structure
|
||||
|
||||
https://source.android.com/devices/bootloader/partitions-images
|
||||
|
||||
The messy AOSP generates a ton of images instead of just one.
|
||||
|
||||
When the emulator launches, we can see them through QEMU `-drive` arguments:
|
||||
|
||||
....
|
||||
emulator: argv[21] = "-initrd"
|
||||
emulator: argv[22] = "/data/aosp/8.1.0_r60/out/target/product/generic_x86_64/ramdisk.img"
|
||||
emulator: argv[23] = "-drive"
|
||||
emulator: argv[24] = "if=none,index=0,id=system,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/system-qemu.img,read-only"
|
||||
emulator: argv[25] = "-device"
|
||||
emulator: argv[26] = "virtio-blk-pci,drive=system,iothread=disk-iothread,modern-pio-notify"
|
||||
emulator: argv[27] = "-drive"
|
||||
emulator: argv[28] = "if=none,index=1,id=cache,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/cache.img.qcow2,overlap-check=none,cache=unsafe,l2-cache-size=1048576"
|
||||
emulator: argv[29] = "-device"
|
||||
emulator: argv[30] = "virtio-blk-pci,drive=cache,iothread=disk-iothread,modern-pio-notify"
|
||||
emulator: argv[31] = "-drive"
|
||||
emulator: argv[32] = "if=none,index=2,id=userdata,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/userdata-qemu.img.qcow2,overlap-check=none,cache=unsafe,l2-cache-size=1048576"
|
||||
emulator: argv[33] = "-device"
|
||||
emulator: argv[34] = "virtio-blk-pci,drive=userdata,iothread=disk-iothread,modern-pio-notify"
|
||||
emulator: argv[35] = "-drive"
|
||||
emulator: argv[36] = "if=none,index=3,id=encrypt,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/encryptionkey.img.qcow2,overlap-check=none,cache=unsafe,l2-cache-size=1048576"
|
||||
emulator: argv[37] = "-device"
|
||||
emulator: argv[38] = "virtio-blk-pci,drive=encrypt,iothread=disk-iothread,modern-pio-notify"
|
||||
emulator: argv[39] = "-drive"
|
||||
emulator: argv[40] = "if=none,index=4,id=vendor,file=/path/to/aosp/8.1.0_r60/out/target/product/generic_x86_64/vendor-qemu.img,read-only"
|
||||
emulator: argv[41] = "-device"
|
||||
emulator: argv[42] = "virtio-blk-pci,drive=vendor,iothread=disk-iothread,modern-pio-notify"
|
||||
....
|
||||
|
||||
The root directory is the <<initrd>> given on the QEMU CLI, which `/proc/mounts` reports at:
|
||||
|
||||
....
|
||||
rootfs on / type rootfs (ro,seclabel,size=886392k,nr_inodes=221598)
|
||||
....
|
||||
|
||||
This contains the <<android-init>>, which through `.rc` must be mounting mounts the drives int o the right places TODO find exact point.
|
||||
|
||||
The drive order is:
|
||||
|
||||
....
|
||||
system
|
||||
cache
|
||||
userdata
|
||||
encryptionkey
|
||||
vendor-qemu
|
||||
....
|
||||
|
||||
Then, on the terminal:
|
||||
|
||||
....
|
||||
mount | grep vd
|
||||
....
|
||||
|
||||
gives:
|
||||
|
||||
....
|
||||
/dev/block/vda1 on /system type ext4 (ro,seclabel,relatime,data=ordered)
|
||||
/dev/block/vde1 on /vendor type ext4 (ro,seclabel,relatime,data=ordered)
|
||||
/dev/block/vdb on /cache type ext4 (rw,seclabel,nosuid,nodev,noatime,errors=panic,data=ordered)
|
||||
....
|
||||
|
||||
and we see that the order of `vda`, `vdb`, etc. matches that in which `-drive` were given to QEMU.
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
===== Android images read-only
|
||||
|
||||
From `mount`, we can see that some of the mounted images are `ro`.
|
||||
|
||||
Basically, every image that was given to QEMU as qcow2 is writable, and that qcow2 is an overlay over the actual original image.
|
||||
|
||||
In order to make `/system` and `/vendor` writable by using qcow2 for them as well, we must use the `-writable-system` option:
|
||||
|
||||
....
|
||||
./run-android -- -writable-system
|
||||
....
|
||||
|
||||
* https://android.stackexchange.com/questions/110927/how-to-mount-system-rewritable-or-read-only-rw-ro/207200#207200
|
||||
* https://stackoverflow.com/questions/13089694/adb-remount-permission-denied-but-able-to-access-super-user-in-shell-android/43163693#43163693
|
||||
|
||||
then:
|
||||
|
||||
....
|
||||
su
|
||||
mount -o rw,remount /system
|
||||
date >/system/a
|
||||
....
|
||||
|
||||
Now reboot, and relaunch with `-writable-system` once again to pick up the modified qcow2 images:
|
||||
|
||||
....
|
||||
./run-android -- -writable-system
|
||||
....
|
||||
|
||||
and the newly created file is still there:
|
||||
|
||||
....
|
||||
date >/system/a
|
||||
....
|
||||
|
||||
`/system` and `/vendor` can be nuked quickly with:
|
||||
|
||||
....
|
||||
./build-android --extra-args snod
|
||||
./build-android --extra-args vnod
|
||||
....
|
||||
|
||||
as mentioned at: https://stackoverflow.com/questions/29023406/how-to-just-build-android-system-image and on:
|
||||
|
||||
....
|
||||
./build-android --extra-args help
|
||||
....
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
===== Android /data partition
|
||||
|
||||
When I install an app like F-Droid, it goes under `/data` according to:
|
||||
|
||||
....
|
||||
find / -iname '*fdroid*'
|
||||
....
|
||||
|
||||
and it <<disk-persistency,persists across boots>>.
|
||||
|
||||
`/data` is behind a RW LVM device:
|
||||
|
||||
....
|
||||
/dev/block/dm-0 on /data type ext4 (rw,seclabel,nosuid,nodev,noatime,errors=panic,data=ordered)
|
||||
....
|
||||
|
||||
but TODO I can't find where it comes from since I don't have the CLI tools mentioned at:
|
||||
|
||||
* https://superuser.com/questions/131519/what-is-this-dm-0-device
|
||||
* https://unix.stackexchange.com/questions/185057/where-does-lvm-store-its-configuration
|
||||
|
||||
However, by looking at:
|
||||
|
||||
....
|
||||
./run-android -- -help
|
||||
....
|
||||
|
||||
we see:
|
||||
|
||||
....
|
||||
-data <file> data image (default <datadir>/userdata-qemu.img
|
||||
....
|
||||
|
||||
which confirms the suspicion that this data goes in `userdata-qemu.img`.
|
||||
|
||||
To reset images to their original state, just remove the qcow2 overlay and regenerate it: https://stackoverflow.com/questions/54446680/how-to-reset-the-userdata-image-when-building-android-aosp-and-running-it-on-the
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
==== Install Android apps
|
||||
|
||||
I don't know how to download files from the web on Vanilla android, the default browser does not download anything, and there is no `wget`:
|
||||
|
||||
* https://android.stackexchange.com/questions/6984/how-to-download-files-from-the-web-in-the-android-browser
|
||||
* https://stackoverflow.com/questions/26775079/wget-in-android-terminal
|
||||
|
||||
Installing with `adb install` does however work: https://stackoverflow.com/questions/7076240/install-an-apk-file-from-command-prompt
|
||||
|
||||
link:https://f-droid.org[F-Droid] installed fine like that, however it does not have permission to install apps: https://www.maketecheasier.com/install-apps-from-unknown-sources-android/
|
||||
|
||||
And the `Settings` app crashes so I can't change it, logcat contains:
|
||||
|
||||
....
|
||||
No service published for: wifip2p
|
||||
....
|
||||
|
||||
which is mentioned at: https://stackoverflow.com/questions/47839955/android-8-settings-app-crashes-on-emulator-with-clean-aosp-build
|
||||
|
||||
We also tried to enable it from the command line with:
|
||||
|
||||
....
|
||||
settings put secure install_non_market_apps 1
|
||||
....
|
||||
|
||||
as mentioned at: https://android.stackexchange.com/questions/77280/allow-unknown-sources-from-terminal-without-going-to-settings-app but it didn't work either.
|
||||
|
||||
No person alive seems to know how to pre-install apps on AOSP: https://stackoverflow.com/questions/6249458/pre-installing-android-application
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
=== Android init
|
||||
|
||||
For Linux in general, see: <<init>>.
|
||||
|
||||
The `/init` executable interprets the `/init.rc` files, which is in a custom Android init system language: https://android.googlesource.com/platform/system/core/+/ee0e63f71d90537bb0570e77aa8a699cc222cfaf/init/README.md
|
||||
|
||||
The top of that file then sources other `.rc` files present on the root directory:
|
||||
|
||||
....
|
||||
import /init.environ.rc
|
||||
import /init.usb.rc
|
||||
import /init.${ro.hardware}.rc
|
||||
import /vendor/etc/init/hw/init.${ro.hardware}.rc
|
||||
import /init.usb.configfs.rc
|
||||
import /init.${ro.zygote}.rc
|
||||
....
|
||||
|
||||
TODO: how is `ro.hardware` determined? https://stackoverflow.com/questions/20572781/android-boot-where-is-the-init-hardware-rc-read-in-init-c-where-are-servic It is a system property and can be obtained with:
|
||||
|
||||
....
|
||||
getprop ro.hardware
|
||||
....
|
||||
|
||||
This gives:
|
||||
|
||||
....
|
||||
ranchu
|
||||
....
|
||||
|
||||
which is the codename for the QEMU virtual platform we are running on: https://www.oreilly.com/library/view/android-system-programming/9781787125360/9736a97c-cd09-40c3-b14d-955717648302.xhtml
|
||||
|
||||
TODO: is it possible to add a custom `.rc` file without modifying the initrd that <<android-image-structure,gets mounted on root>>? https://stackoverflow.com/questions/9768103/make-persistent-changes-to-init-rc
|
||||
|
||||
Tested on: `8.1.0_r60`.
|
||||
|
||||
== About this repo
|
||||
|
||||
=== Supported hosts
|
||||
@@ -13057,88 +13187,6 @@ link:include/[] contains headers that are shared across both kernel modules and
|
||||
|
||||
They contain data structs and magic constant for kernel to userland communication.
|
||||
|
||||
==== userland directory
|
||||
|
||||
Userland test programs. They can be used in the following ways:
|
||||
|
||||
* inside a full system simulation, e.g.: <<qemu-buildroot-setup>>
|
||||
* inside <<user-mode-simulation>>
|
||||
* directly on the host: <<userland-directory-host-build>>
|
||||
|
||||
For usage inside full system simulation, first ensure that Buildroot has been built for the toolchain, and then build the examples with:
|
||||
|
||||
....
|
||||
./build-userland
|
||||
....
|
||||
|
||||
Source: link:build-userland[].
|
||||
|
||||
This makes them visible immediately on the <<9p>> mount of a running simulator.
|
||||
|
||||
In order to place them in the root filesystem image itself, you must also run:
|
||||
|
||||
....
|
||||
./build-buildroot
|
||||
....
|
||||
|
||||
===== userland directory host build
|
||||
|
||||
It is possible to build and run some of the userland examples directly on your host:
|
||||
|
||||
....
|
||||
cd userland
|
||||
make
|
||||
./hello.out
|
||||
make clean
|
||||
....
|
||||
|
||||
or more cleanly out of tree:
|
||||
|
||||
....
|
||||
./build-userland --gcc-which host --userland-build-id host
|
||||
"$(./getvar --userland-build-id host userland_build_dir)/hello.out"
|
||||
....
|
||||
|
||||
Extra make flags may be passed as:
|
||||
|
||||
....
|
||||
./build-userland --gcc-which host --userland-build-id host-static --make-args='-B CFLAGS_EXTRA=-static'
|
||||
"$(./getvar --userland-build-id host-static userland_build_dir)/hello.out"
|
||||
....
|
||||
|
||||
This for example would both force a rebuild due to `-B` and link statically due to `CFLAGS_EXTRA=-static`.
|
||||
|
||||
TODO: OpenMP does not like `-static`:
|
||||
|
||||
....
|
||||
/usr/lib/gcc/x86_64-linux-gnu/5/libgomp.a(target.o): In function `gomp_target_init':
|
||||
(.text+0xba): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
|
||||
....
|
||||
|
||||
See: https://stackoverflow.com/questions/23869981/linking-openmp-statically-with-gcc
|
||||
|
||||
===== userland cheats
|
||||
|
||||
We have accumulated considerable material in the following userland subjects.
|
||||
|
||||
====== C
|
||||
|
||||
Programs under link:userland/c/[] are examples of link:https://en.wikipedia.org/wiki/ANSI_C[ANSI C] programming.
|
||||
|
||||
[[cpp]]
|
||||
====== C++
|
||||
|
||||
Programs under link:userland/cpp/[] are examples of link:https://en.wikipedia.org/wiki/C%2B%2B#Standardization[ISO C] programming.
|
||||
|
||||
====== POSIX
|
||||
|
||||
Programs under link:userland/posix/[] are examples of POSIX C programming.
|
||||
|
||||
What is POSIX:
|
||||
|
||||
* https://stackoverflow.com/questions/1780599/what-is-the-meaning-of-posix/31865755#31865755
|
||||
* https://unix.stackexchange.com/questions/11983/what-exactly-is-posix/220877#220877
|
||||
|
||||
==== buildroot_packages directory
|
||||
|
||||
Source: link:buildroot_packages/[]
|
||||
@@ -13171,7 +13219,7 @@ You can force a rebuild with:
|
||||
./build-buildroot --config 'BR2_PACKAGE_SAMPLE_PACKAGE=y' -- sample_package-reconfigure
|
||||
....
|
||||
|
||||
Buildroot packages are convenient, but in general, if a package if very important to you, but not really mergeable back to Buildroot, you might want to just use a custom build script for it, and point it to the Buildroot toolchain, and then use `BR2_ROOTFS_OVERLAY`, much like we do for <<userland-directory>>.
|
||||
Buildroot packages are convenient, but in general, if a package if very important to you, but not really mergeable back to Buildroot, you might want to just use a custom build script for it, and point it to the Buildroot toolchain, and then use `BR2_ROOTFS_OVERLAY`, much like we do for <<userland-setup>>.
|
||||
|
||||
A custom build script can give you more flexibility: e.g. the package can be made work with other root filesystems more easily, have better <<9p>> support, and rebuild faster as it evades some Buildroot boilerplate.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user