readme: factor out hardcoded paths on code snippets with getvar

This commit is contained in:
Ciro Santilli
2018-08-12 23:48:12 +01:00
parent 185c2730cc
commit a8bc1f4cce
5 changed files with 177 additions and 95 deletions

View File

@@ -868,13 +868,13 @@ git clean -xdf .
To only nuke one architecture, do: To only nuke one architecture, do:
.... ....
rm -rf out/x86_64/buildroot rm -rf "$(./getvar buildroot_out_dir)"
.... ....
Only nuke one one package: Only nuke one one package:
.... ....
rm -rf out/x86_64/buildroot/build/host-qemu-custom rm -rf "$(./getvar buildroot_out_dir)/build/host-qemu-custom"
./build ./build
.... ....
@@ -1132,15 +1132,15 @@ This method also allows us to keep run outputs in separate directories for later
produces two separate `m5out` directories: produces two separate `m5out` directories:
.... ....
less out/aarch64/gem5/0/m5out ls "$(./getvar -a A -g -n 0 m5out_dir)"
less out/aarch64/gem5/1/m5out ls "$(./getvar -a A -g -n 1 m5out_dir)"
.... ....
and the gem5 host executable stdout and stderr can be found at: and the gem5 host executable stdout and stderr can be found at:
.... ....
less out/aarch64/gem5/0/termout.txt less "$(./getvar -a A -g -n 0 termout_file)"
less out/aarch64/gem5/1/termout.txt less "$(./getvar -a A -g -n 1 termout_file)"
.... ....
Each line is prepended with the timestamp in seconds since the start of the program when it appeared. Each line is prepended with the timestamp in seconds since the start of the program when it appeared.
@@ -1151,12 +1151,6 @@ You can also add a prefix to the build ID before a period:
./run -a A -g -n some-experiment.1 ./run -a A -g -n some-experiment.1
.... ....
which then uses the output directory:
....
less out/aarch64/gem5/some-experiment.1/m5out
....
and makes it easier to remember afterwards which directory contains what. and makes it easier to remember afterwards which directory contains what.
However this still takes up the same ports as: However this still takes up the same ports as:
@@ -1450,7 +1444,7 @@ so it is close to the failing `0xbf0000cc`.
`readelf`: `readelf`:
.... ....
./runtc readelf -s ./out/x86_64/buildroot/build/kernel_module-1.0/hello.ko ./runtc readelf -s "$(./getvar build_dir)/kernel_module-1.0/hello.ko"
.... ....
does not give any interesting hits at `cc`, no symbol was placed that far. does not give any interesting hits at `cc`, no symbol was placed that far.
@@ -1464,7 +1458,7 @@ This is not very easy, since by the time the module finishes loading, and `lx-sy
Possibly asked at: Possibly asked at:
* https://stackoverflow.com/questions/37059320/debug-a-kernel-module-being-loaded * https://stackoverflow.com/questions/37059320/debug-a-kernel-module-being-loaded
* https://stackoverflow.com/questions/11888412/debug-the-init-module-call-of-a-linux-kernel-module?rq=1 * https://stackoverflow.com/questions/11888412/debug-the-init-module-call-of-a-linux-kernel-module
===== GDB module_init step into it ===== GDB module_init step into it
@@ -1524,7 +1518,7 @@ Now let's find the offset of `myinit`:
.... ....
./runtc readelf \ ./runtc readelf \
-s ./out/x86_64/buildroot/build/kernel_module-1.0/fops.ko | \ -s "$(./getvar build_dir)/kernel_module-1.0/fops.ko" | \
grep myinit grep myinit
.... ....
@@ -1691,7 +1685,7 @@ One possibility is to run:
and then find the second address (the first one does not work, already too late maybe): and then find the second address (the first one does not work, already too late maybe):
.... ....
less ./out/arm/qemu/0/trace.txt less "$(./getvar -a arm trace_txt_file)"
.... ....
and break there: and break there:
@@ -1845,7 +1839,7 @@ We have also double checked the address with:
.... ....
./runtc -a arm readelf \ ./runtc -a arm readelf \
-s ./out/arm/buildroot/build/kernel_module-1.0/user/hello.out | \ -s "$(./getvar -a arm build_dir)/kernel_module-1.0/fops.ko" | \
grep main grep main
.... ....
@@ -2276,13 +2270,13 @@ Host:
You can find the executable with: You can find the executable with:
.... ....
find out/x86_64/buildroot/build -name myinsmod.out find "$(./getvar build_dir)" -name myinsmod.out
.... ....
TODO: automate the path finding: TODO: automate the path finding:
* using the executable from under `out/x86_64/buildroot/target` would be easier as the path is the same as in guest, but unfortunately those executables are stripped to make the guest smaller. `BR2_STRIP_none=y` should disable stripping, but make the image way larger. * using the executable from under `$(./getvar target_dir)` would be easier as the path is the same as in guest, but unfortunately those executables are stripped to make the guest smaller. `BR2_STRIP_none=y` should disable stripping, but make the image way larger.
* `outputx86_64~/staging/` would be even better than `target/` as the docs say that this directory contains binaries before they were stripped. However, only a few binaries are pre-installed there by default, and it seems to be a manual per package thing. * `$(./getvar staging_dir)` would be even better than the target dir as Buildroot docs say that this directory contains binaries before they were stripped. However, only a few binaries are pre-installed there by default, and it seems to be a manual per package thing.
+ +
E.g. `pciutils` has for `lspci`: E.g. `pciutils` has for `lspci`:
+ +
@@ -2447,7 +2441,7 @@ TODO Can you run arm executables in the aarch64 guest? https://stackoverflow.com
I've tried: I've tried:
.... ....
./out/aarch64/buildroot/host/bin/aarch64-linux-gcc -static ~/test/hello_world.c -o data/9p/a.out ./runtc -a aarch64 gcc|cg -static ~/test/hello_world.c -o data/9p/a.out
./run -a A -F '/mnt/9p/a.out' ./run -a A -F '/mnt/9p/a.out'
.... ....
@@ -2781,7 +2775,7 @@ To x11 packages have an `xserver` prefix as in:
./build -b br2/x11 -- xserver_xorg-server-reconfigure ./build -b br2/x11 -- xserver_xorg-server-reconfigure
.... ....
the easiest way to find them out is to just list `out/x86_64/buildroot/build/x*`. the easiest way to find them out is to just list `"$(./getvar build_dir)/x*`.
TODO as of: c2696c978d6ca88e8b8599c92b1beeda80eb62b2 I noticed that `startx` leads to a <<bug_on>>: TODO as of: c2696c978d6ca88e8b8599c92b1beeda80eb62b2 I noticed that `startx` leads to a <<bug_on>>:
@@ -2874,7 +2868,7 @@ To enable initrd instead of the default ext2 disk image, do:
Notice how it boots fine, even though this leads to not giving QEMU the `-drive` option, as can be verified with: Notice how it boots fine, even though this leads to not giving QEMU the `-drive` option, as can be verified with:
.... ....
cat ./out/x86_64/qemu/0/run.sh cat "$(./getvar run_dir)/run.sh"
.... ....
Also as expected, there is no filesystem persistency, since we are doing everything in memory: Also as expected, there is no filesystem persistency, since we are doing everything in memory:
@@ -2949,7 +2943,7 @@ The `-l` (ell) should only be used the first time you move to / from a different
It is interesting to see how this increases the size of the kernel image if you do a: It is interesting to see how this increases the size of the kernel image if you do a:
.... ....
ls -lh out/x86_64/buildroot/images/bzImage ls -lh "$(./getvar linux_image)"
.... ....
before and after using initramfs, since the `.cpio` is now glued to the kernel image. before and after using initramfs, since the `.cpio` is now glued to the kernel image.
@@ -3031,13 +3025,13 @@ CONFIG_IKCONFIG_PROC=y
From host: From host:
.... ....
cat out/*/buildroot/build/linux-custom/.config cat "$(./getvar linux_custom_dir)/.config"
.... ....
Just for fun link:https://stackoverflow.com/a/14958263/895245[]: Just for fun link:https://stackoverflow.com/a/14958263/895245[]:
.... ....
./linux/scripts/extract-ikconfig out/*/buildroot/build/linux-custom/vmlinux ./linux/scripts/extract-ikconfig "$(./getvar vmlinux)"
.... ....
although this can be useful when someone gives you a random image. although this can be useful when someone gives you a random image.
@@ -3363,7 +3357,7 @@ vermagic: 4.17.0 SMP mod_unload modversions
Module information is stored in a special `.modinfo` section of the ELF file: Module information is stored in a special `.modinfo` section of the ELF file:
.... ....
./runtc readelf -SW ./out/x86_64/buildroot/target/module_info.ko ./runtc readelf -SW "$(./getvar target_dir)/module_info.ko"
.... ....
contains: contains:
@@ -3375,7 +3369,7 @@ contains:
and: and:
.... ....
./runtc readelf -x .modinfo ./out/x86_64/buildroot/target/module_info.ko ./runtc readelf -x .modinfo "$(./getvar build_dir)/module_info.ko"
.... ....
gives: gives:
@@ -3592,10 +3586,10 @@ as explained at: https://stackoverflow.com/questions/8545931/using-gdb-to-conver
The exact same thing can be done post mortem with: The exact same thing can be done post mortem with:
.... ....
./out/x86_64/buildroot/host/usr/bin/x86_64-buildroot-linux-uclibc-gdb \ ./runtc gdb \
-batch \ -batch \
-ex 'info line *(myinit+0x1d)' \ -ex 'info line *(myinit+0x1d)' \
./out/x86_64/buildroot/build/kernel_module-1.0/panic.ko \ "$(./getvar build_dir)/kernel_module-1.0/panic.ko" \
; ;
.... ....
@@ -4916,7 +4910,7 @@ Meaning of the flags:
* `vaddr`: first virtual address of a page the belongs to the process. Notably: * `vaddr`: first virtual address of a page the belongs to the process. Notably:
+ +
.... ....
./runtc readelf -l out/x86_64/buildroot/build/kernel_module-1.0/user/virt_to_phys_test.out ./runtc readelf -l "$(./getvar build_dir)/kernel_module-1.0/user/virt_to_phys_test.out"
.... ....
+ +
contains: contains:
@@ -5288,7 +5282,7 @@ Notes:
It can be found from: It can be found from:
+ +
.... ....
./runtc readelf -e out/x86_64/buildroot/build/linux-*/vmlinux | grep Entry ./runtc readelf -e "$(./getvar build_dir)"/linux-*/vmlinux | grep Entry
.... ....
+ +
TODO confirm further. If I try to break there with: TODO confirm further. If I try to break there with:
@@ -5546,7 +5540,7 @@ cad
To map between `man 2 reboot` and the uclibc `RB_*` magic constants see: To map between `man 2 reboot` and the uclibc `RB_*` magic constants see:
.... ....
less out/x86_64/buildroot/build/uclibc-*/include/sys/reboot.h less "$(./getvar build_dir)"/uclibc-*/include/sys/reboot.h"
.... ....
The procfs mechanism is documented at: The procfs mechanism is documented at:
@@ -6119,7 +6113,7 @@ Snapshots are stored inside the `.qcow2` images themselves.
They can be observed with: They can be observed with:
.... ....
./out/x86_64/buildroot/host/bin/qemu-img info out/x86_64/buildroot/images/rootfs.ext2.qcow2 "$(./getvar host_dir)/bin/qemu-img" info "$(./getvar qcow2_file)"
.... ....
which after `savevm my_snap_id` and `savevm asdf` contains an output of type: which after `savevm my_snap_id` and `savevm asdf` contains an output of type:
@@ -6770,7 +6764,7 @@ This has nothing to do with the Linux kernel, but it is cool:
.... ....
sudo apt-get install qemu-user sudo apt-get install qemu-user
./build -a arm ./build -a arm
cd out/arm/buildroot/target cd "$(./getvar target_dir)"
qemu-arm -L . bin/ls qemu-arm -L . bin/ls
.... ....
@@ -6781,7 +6775,7 @@ The reason this is cool, is that `ls` is not statically compiled, but since we h
In other words, much cooler than: In other words, much cooler than:
.... ....
./out/arm/buildroot/host/bin/arm-linux-gcc -static ./kernel_module/user/hello.c ./runtc -a arm gcc -static ./kernel_module/user/hello.c
qemu-arm a.out qemu-arm a.out
.... ....
@@ -6798,7 +6792,7 @@ Anyways, this warns us that the userland emulation will likely not be reliable,
GDB step debugging is also possible with: GDB step debugging is also possible with:
.... ....
cd out/arm/buildroot/target cd "$(./getvar -a arm target_dir)"
qemu-arm -g 1234 -L . ../build/kernel_module-1.0/user/myinsmod.out qemu-arm -g 1234 -L . ../build/kernel_module-1.0/user/myinsmod.out
../host/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gdb \ ../host/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gdb \
--nh \ --nh \
@@ -6832,14 +6826,12 @@ First we try some `-static` sanity checks.
Works and prints `hello`: Works and prints `hello`:
.... ....
./out/arm/buildroot/host/bin/arm-linux-gcc -static ./kernel_module/user/hello.c ./runtc -a x86_64 gcc -static -o x86_64.out ./kernel_module/user/hello.c
./out/common/gem5/build/X86/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.out ./runtc -a arm gcc -static -o arm.out ./kernel_module/user/hello.c
./runtc -a aarch64 gcc -static -o aarch64.out ./kernel_module/user/hello.c
./out/arm/buildroot/host/bin/arm-linux-gcc -static ./kernel_module/user/hello.c "$(./getvar -a x86_64 -g exec)" ./gem5/gem5/configs/example/se.py -c ./x86_64.out
./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.out "$(./getvar -a arm -g exec)" ./gem5/gem5/configs/example/se.py -c ./arm.out
"$(./getvar -a aarch64 -g exec)" ./gem5/gem5/configs/example/se.py -c ./aarch64.out
./out/aarch64/buildroot/host/bin/aarch64-linux-gcc -static ./kernel_module/user/hello.c
./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.out
.... ....
But I think this is unreliable, and only works because we are using uclibc which does not check the kernel version as glibc does: https://stackoverflow.com/questions/48959349/how-to-solve-fatal-kernel-too-old-when-running-gem5-in-syscall-emulation-se-m/50542301#50542301 But I think this is unreliable, and only works because we are using uclibc which does not check the kernel version as glibc does: https://stackoverflow.com/questions/48959349/how-to-solve-fatal-kernel-too-old-when-running-gem5-in-syscall-emulation-se-m/50542301#50542301
@@ -6847,18 +6839,18 @@ But I think this is unreliable, and only works because we are using uclibc which
Ignoring that insanity, we then try it with dynamically linked executables: Ignoring that insanity, we then try it with dynamically linked executables:
.... ....
./out/common/gem5/build/X86/gem5.opt ./gem5/gem5/configs/example/se.py -c ./out/x86_64/buildroot/target/hello.out "$(./getvar -a x86_64 -g exec)" ./gem5/gem5/configs/example/se.py -c "$(./getvar -a x86_64 -g target_dir)/hello.out"
./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./out/arm/buildroot/target/hello.out "$(./getvar -a arm -g exec)" ./gem5/gem5/configs/example/se.py -c "$(./getvar -a arm -g target_dir)/hello.out"
./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./out/aarch64/buildroot/target/hello.out "$(./getvar -a aarch64 -g exec)" ./gem5/gem5/configs/example/se.py -c "$(./getvar -a aarch64 -g target_dir)/hello.out"
.... ....
But they fail with: But at 185c2730cc78d5adda683d76c0e3b35e7cb534f0 they fail with:
.... ....
fatal: Unable to open dynamic executable's interpreter. fatal: Unable to open dynamic executable's interpreter.
.... ....
and `cd ./out/aarch64/buildroot/target` did not help: https://stackoverflow.com/questions/50542222/how-to-run-a-dynamically-linked-executable-syscall-emulation-mode-se-py-in-gem5 and `cd "$(./getvar -a aarch64 target_dir)` did not help: https://stackoverflow.com/questions/50542222/how-to-run-a-dynamically-linked-executable-syscall-emulation-mode-se-py-in-gem5
The current FAQ says it is not possible to use dynamic executables: http://gem5.org/Frequently_Asked_Questions but I don't trust it, and then these presentations mention it: The current FAQ says it is not possible to use dynamic executables: http://gem5.org/Frequently_Asked_Questions but I don't trust it, and then these presentations mention it:
@@ -6875,13 +6867,13 @@ gem5 user mode:
.... ....
make \ make \
-C out/arm/buildroot/build/dhrystone-2 \ -C "$(./getvar -a arm build_dir)/dhrystone-2" \
CC="$(pwd)/out/arm/buildroot/host/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gcc" \ CC=""$(./getvar buildroot_out_dir)/host/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gcc" \
CFLAGS=-static \ CFLAGS=-static \
; ;
time ./out/common/gem5/build/ARM/gem5.opt \ time "$(./getvar -a arm -g exec)" \
./gem5/gem5/configs/example/se.py \ ./gem5/gem5/configs/example/se.py \
-c out/arm/buildroot/build/dhrystone-2/dhrystone \ -c "$(./getvar -a arm build_dir)/dhrystone-2/dhrystone" \
-o 100000 \ -o 100000 \
; ;
.... ....
@@ -6898,7 +6890,7 @@ time ./run -a a -l 1 -g
QEMU user mode: QEMU user mode:
.... ....
time qemu-arm out/arm/buildroot/build/dhrystone-2/dhrystone 100000000 time qemu-arm "$(./getvar -a arm build_dir)/dhrystone-2/dhrystone" 100000000
.... ....
QEMU full system: QEMU full system:
@@ -7031,7 +7023,7 @@ The most interesting are events which show instructions that QEMU ran, for which
You can then inspect the instructions with: You can then inspect the instructions with:
.... ....
less ./out/x86_64/qemu/0/trace.txt less "$(./getvar -a x86_64 run_dir)/trace.txt"
.... ....
Get the list of available trace events: Get the list of available trace events:
@@ -7045,7 +7037,7 @@ Enable other specific trace events:
.... ....
./run -T trace1,trace2 ./run -T trace1,trace2
./qemu-trace2txt -a "$arch" ./qemu-trace2txt -a "$arch"
less ./out/x86_64/qemu/0/trace.txt less "$(./getvar -a "$arch" run_dir)/trace.txt"
.... ....
This functionality relies on the following setup: This functionality relies on the following setup:
@@ -7077,7 +7069,7 @@ We can further use Binutils' `addr2line` to get the line that corresponds to eac
.... ....
./trace-boot -a x86_64 && ./trace2line -a x86_64 ./trace-boot -a x86_64 && ./trace2line -a x86_64
less ./out/x86_64/qemu/0/trace-lines.txt less "$(./getvar -a x86_64 run_dir)/trace-lines.txt"
.... ....
The format is as follows: The format is as follows:
@@ -7234,7 +7226,7 @@ But it also provides a tracing mechanism documented at: link:http://www.gem5.org
.... ....
./run -a aarch64 -E 'm5 exit' -g -T Exec ./run -a aarch64 -E 'm5 exit' -g -T Exec
less out/aarch64/gem5/0/m5out/trace.txt less "$(./getvar -a aarch64 run_dir)/trace.txt"
.... ....
List all available debug flags: List all available debug flags:
@@ -7288,7 +7280,7 @@ Trace the source lines just like <<trace-source-lines,for QEMU>> with:
.... ....
./trace-boot -a aarch64 -g && ./trace2line -a aarch64 -g ./trace-boot -a aarch64 -g && ./trace2line -a aarch64 -g
less ./out/aarch64/gem5/0/trace-lines.txt less "$(./getvar -a aarch64 run_dir)/trace-lines.txt"
.... ....
TODO: 7452d399290c9c1fc6366cdad129ef442f323564 `./trace2line` this is too slow and takes hours. QEMU's processing of 170k events takes 7 seconds. gem5's processing is analogous, but there are 140M events, so it should take 7000 seconds ~ 2 hours which seems consistent with what I observe, so maybe there is no way to speed this up... The workaround is to just use gem5's `ExecSymbol` to get function granularity, and then GDB individually if line detail is needed? TODO: 7452d399290c9c1fc6366cdad129ef442f323564 `./trace2line` this is too slow and takes hours. QEMU's processing of 170k events takes 7 seconds. gem5's processing is analogous, but there are 140M events, so it should take 7000 seconds ~ 2 hours which seems consistent with what I observe, so maybe there is no way to speed this up... The workaround is to just use gem5's `ExecSymbol` to get function granularity, and then GDB individually if line detail is needed?
@@ -7465,7 +7457,7 @@ Now you can play a fun little game with your friends:
To find out why your program is slow, a good first step is to have a look at the statistics for the run: To find out why your program is slow, a good first step is to have a look at the statistics for the run:
.... ....
cat out/aarch64/gem5/0/m5out/stats.txt cat "$(./getvar -a aarch64 m5out_dir)/stats.txt"
.... ....
Whenever we run `m5 dumpstats` or `m5 exit`, a section with the following format is added to that file: Whenever we run `m5 dumpstats` or `m5 exit`, a section with the following format is added to that file:
@@ -7564,7 +7556,7 @@ So we take a performance measurement approach instead:
.... ....
./gem5-bench-cache -a aarch64 ./gem5-bench-cache -a aarch64
cat out/aarch64/gem5/0/bench-cache.txt cat "$(./getvar -a aarch64 run_dir)bench-cache.txt"
.... ....
which gives: which gives:
@@ -7725,7 +7717,13 @@ The test performs a general matrix multiplication:
| 1.0 -1.0 | | 0.5 0.5 0.5 | | 5.0 - 1.0 3.0 | | 1.0 -1.0 | | 0.5 0.5 0.5 | | 5.0 - 1.0 3.0 |
.... ....
This can be deduced from the Fortran interfaces at: `out/x86_64/buildroot/build/openblas-*/reference/dgemmf.f`, which we can map to our call as: This can be deduced from the Fortran interfaces at
....
less "$(./getvar build_dir)"/openblas-*/reference/dgemmf.f
....
which we can map to our call as:
.... ....
C := alpha*op( A )*op( B ) + beta*C, C := alpha*op( A )*op( B ) + beta*C,
@@ -7882,10 +7880,10 @@ If you want to remove PARSEC later, Buildroot doesn't provide an automated packa
.... ....
rm -rf \ rm -rf \
./out/common/dl/parsec-* \ ./out/common/dl/parsec-* \
./out/arm-gem5/buildroot/build/parsec-* \ "$(./getvar buildroot_out_dir)"/build/parsec-* \
./out/arm-gem5/buildroot/build/packages-file-list.txt \ "$(./getvar buildroot_out_dir)"/build/packages-file-list.txt \
./out/arm-gem5/buildroot/images/rootfs.* \ "$(./getvar buildroot_out_dir)"/images/rootfs.* \
./out/arm-gem5/buildroot/target/parsec-* \ "$(./getvar buildroot_out_dir)"/target/parsec-* \
; ;
./build -a arm -g ./build -a arm -g
.... ....
@@ -8094,7 +8092,7 @@ since boot has already happened, and the parameters are already in the RAM of th
Checkpoints are stored inside the `m5out` directory at: Checkpoints are stored inside the `m5out` directory at:
.... ....
out/<arch>/gem5/<run-id>/m5out/cpt.<checkpoint-time> "$(./getvar -g run_dir)/m5out/cpt.<checkpoint-time>"
.... ....
where `<checkpoint-time>` is the cycle number at which the checkpoint was taken. where `<checkpoint-time>` is the cycle number at which the checkpoint was taken.
@@ -8267,7 +8265,7 @@ m5 writefile myfileguest myfilehost
Host: Host:
.... ....
cat out/aarch64/gem5/0/m5out/myfilehost cat "$(./getvar -a aarch64 -g m5out_dir)/myfilehost"
.... ....
Does not work for subdirectories, gem5 crashes: Does not work for subdirectories, gem5 crashes:
@@ -8459,7 +8457,7 @@ TODO We didn't manage to find a working ARM analogue to <<rdtsc>>: link:kernel_m
We have made a crazy setup that allows you to just `cd` into `gem5/gem5`, and edit Python scripts directly there. We have made a crazy setup that allows you to just `cd` into `gem5/gem5`, and edit Python scripts directly there.
This is not normally possible with Buildroot, since normal Buildroot packages first copy files to the output directory (`out/<arch>/buildroot/build/<pkg>`), and then build there. This is not normally possible with Buildroot, since normal Buildroot packages first copy files to the output directory (`$(./getvar -a <arch> build_dir)/<pkg>`), and then build there.
So if you modified the Python scripts with this setup, you would still need to `./build` to copy the modified files over. So if you modified the Python scripts with this setup, you would still need to `./build` to copy the modified files over.
@@ -8564,7 +8562,7 @@ mv out out~
`make menuconfig` is a convenient way to find Buildroot configurations: `make menuconfig` is a convenient way to find Buildroot configurations:
.... ....
cd out/x86_64/buildroot cd "$(./getvar buildroot_out_dir)"
make menuconfig make menuconfig
.... ....
@@ -8637,7 +8635,7 @@ If you don't set it, the default is to use `~/.buildroot-ccache` with `5G`, whic
I find it very relaxing to watch ccache at work with: I find it very relaxing to watch ccache at work with:
.... ....
watch -n1 'make -C out/x86_64/buildroot/ ccache-stats' watch -n1 'make -C "$(./getvar buildroot_out_dir)" ccache-stats'
.... ....
or if you have it installed on host and the environment variables exported simply with: or if you have it installed on host and the environment variables exported simply with:
@@ -8810,7 +8808,7 @@ This hack-ish technique allows us to rebuild just one package at a time:
and now you can see that a new version of `kernel_module` was built and put inside the image: and now you can see that a new version of `kernel_module` was built and put inside the image:
.... ....
ls out/x86_64/buildroot/build/kernel_module-mybranch ls "$(./getvar build_dir)/kernel_module-mybranch"
.... ....
Unfortunately we don't have a nice runtime selection with `./run` implemented currently, you have to manually move packages around. Unfortunately we don't have a nice runtime selection with `./run` implemented currently, you have to manually move packages around.
@@ -8856,7 +8854,7 @@ Note that dots cannot be used as in `1.5G`, so just use Megs as in `1500M` inste
Unfortunately, TODO we don't have a perfect way to find the right value for `BR2_TARGET_ROOTFS_EXT2_SIZE`. One good heuristic is: Unfortunately, TODO we don't have a perfect way to find the right value for `BR2_TARGET_ROOTFS_EXT2_SIZE`. One good heuristic is:
.... ....
du -hsx out/arm-gem5/buildroot/target/ du -hsx "$(./getvar -a arm target_dir)"
.... ....
https://stackoverflow.com/questions/49211241/is-there-a-way-to-automatically-detect-the-minimum-required-br2-target-rootfs-ex https://stackoverflow.com/questions/49211241/is-there-a-way-to-automatically-detect-the-minimum-required-br2-target-rootfs-ex
@@ -8908,19 +8906,39 @@ So for example when you run:
Stdout shows a line with the full command of type: Stdout shows a line with the full command of type:
.... ....
./out/arm/buildroot/host/usr/bin/qemu-system-arm -m 128M -monitor telnet::45454,server,nowait -netdev user,hostfwd=tcp::45455-:45455,id=net0 -smp 1 -M versatilepb -append 'root=/dev/sda nokaslr norandmaps printk.devkmsg=on printk.time=y' -device rtl8139,netdev=net0 -dtb ./out/arm/buildroot/images/versatile-pb.dtb -kernel ./out/arm/buildroot/images/zImage -serial stdio -drive file='./out/arm/buildroot/images/rootfs.ext2.qcow2,if=scsi,format=qcow2' time \
/home/ciro/bak/git/linux-kernel-module-cheat/out/arm/buildroot/build/host-qemu-custom.default/arm-softmmu/qemu-system-arm \
-device rtl8139,netdev=net0 \
-gdb 'tcp::45457' \
-kernel '/home/ciro/bak/git/linux-kernel-module-cheat/out/arm/buildroot/build/linux-custom.default/arch/arm/boot/zImage' \
-m '256M' \
-monitor 'telnet::45454,server,nowait' \
-netdev 'user,hostfwd=tcp::45455-:45455,hostfwd=tcp::45456-:22,id=net0' \
-no-reboot \
-serial mon:stdio \
-smp '1' \
-trace 'enable=pr_manager_run,file=/home/ciro/bak/git/linux-kernel-module-cheat/out/arm/qemu/0/trace.bin' \
-virtfs 'local,path=/home/ciro/bak/git/linux-kernel-module-cheat/data/9p,mount_tag=host_scratch,security_model=mapped,id=host_scratch' \
-virtfs 'local,path=/home/ciro/bak/git/linux-kernel-module-cheat/out/arm/buildroot/build,mount_tag=host_out,security_model=mapped,id=host_out' \
-M virt,highmem=off \
-append 'root=/dev/vda console_msg_format=syslog nokaslr norandmaps panic=-1 printk.devkmsg=on printk.time=y' \
-cpu cortex-a15 \
-device virtio-gpu-pci \
-nographic \
-drive 'file=/home/ciro/bak/git/linux-kernel-module-cheat/out/arm/buildroot/images/rootfs.ext2.qcow2,format=qcow2,if=virtio,snapshot' \
|& tee >(ts -s %.s > /home/ciro/bak/git/linux-kernel-module-cheat/out/arm/qemu/0/termout.txt)
.... ....
and this line is also saved to a file for convenience: and this line is also saved to a file for convenience:
.... ....
cat ./out/arm/qemu/0/run.sh cat "$(./getvar -a arm run_dir)/run.sh"
.... ....
or for gem5: or for gem5:
.... ....
cat ./out/arm/gem5/0/run.sh cat "$(./getvar -a arm -g run_dir)/run.sh"
.... ....
Next, you will also want to give the relevant images to save them time. Zip the images with: Next, you will also want to give the relevant images to save them time. Zip the images with:
@@ -8968,7 +8986,7 @@ We tried to automate it on Travis with link:.travis.yml[] but it hits the curren
.... ....
./bench-boot ./bench-boot
cat out/bench-boot.txt cat "$(./getvar bench_boot)"
.... ....
Sample results at 2bddcc2891b7e5ac38c10d509bdfc1c8fe347b94: Sample results at 2bddcc2891b7e5ac38c10d509bdfc1c8fe347b94:
@@ -9055,7 +9073,7 @@ Single file change on `./build kernel_module-reconfigure`: 7 seconds.
Buildroot automatically stores build timestamps as milliseconds since Epoch. Convert to minutes: Buildroot automatically stores build timestamps as milliseconds since Epoch. Convert to minutes:
.... ....
awk -F: 'NR==1{start=$1}; END{print ($1 - start)/(60000.0)}' out/x86_64/buildroot/build/build-time.log awk -F: 'NR==1{start=$1}; END{print ($1 - start)/(60000.0)}' "$(./getvar build_dir)/build-time.log"
.... ....
Or to conveniently do a clean build without affecting your current one: Or to conveniently do a clean build without affecting your current one:
@@ -9068,7 +9086,7 @@ cat ../linux-kernel-module-cheat-regression/*/build-time.log
===== Find which packages are making the build slow ===== Find which packages are making the build slow
.... ....
cd out/x86_64/buildroot cd "$(./getvar buildroot_out_dir)
make graph-build graph-depends make graph-build graph-depends
xdg-open graphs/build.pie-packages.pdf xdg-open graphs/build.pie-packages.pdf
xdg-open graphs/graph-depends.pdf xdg-open graphs/graph-depends.pdf
@@ -9412,6 +9430,30 @@ include::run-usage.adoc[]
:leveloffset: -3 :leveloffset: -3
==== getvar
The link:getvar[] helper script prints the value of a variable from the link:common[] file.
For example, to get the Buildroot output directory for an ARM build, you can use:
....
./getvar -a arm buildroot_out_dir
....
This script exists mostly to factor out instructions given on the README which users are expected to copy paste into the terminal.
Otherwise, it becomes very difficult to keep everything working across path refactors, since README snippets cannot be tested automatically.
==== runtc
The link:runtc[] helper script runs a Tool Chain executable built by Buildroot.
For example, to run `readelf -h` for the `arm` architecture, use:
....
./runtc -a arm readelf -h
....
=== CONTRIBUTING === CONTRIBUTING
==== Testing ==== Testing
@@ -9497,7 +9539,7 @@ git bisect run ../qemu-bisect-boot
git bisect reset git bisect reset
cd .. cd ..
git submodule update git submodule update
rm -rf out/arm/buildroot/build/host-qemu-custom.bisect/ rm -rf "$(./getvar -a arm build_dir)/host-qemu-custom.bisect"
.... ....
An example of Linux kernel commit bisection on gem5 boots can be found at: link:linux-bisect-boot-gem5[]. An example of Linux kernel commit bisection on gem5 boots can be found at: link:linux-bisect-boot-gem5[].

9
common
View File

@@ -30,15 +30,18 @@ common_setup() {
case "$common_arch" in case "$common_arch" in
a|arm) a|arm)
common_arch=arm common_arch=arm
common_gem5_arch=ARM
;; ;;
A|aarch64) A|aarch64)
common_arch=aarch64 common_arch=aarch64
common_gem5_arch=ARM
;; ;;
m|mips64) m|mips64)
common_arch=mips64 common_arch=mips64
;; ;;
x|x86_64) x|x86_64)
common_arch=x86_64 common_arch=x86_64
common_gem5_arch=X86
;; ;;
*) *)
printf "unknown arch: ${common_arch}\n" 1>&2 printf "unknown arch: ${common_arch}\n" 1>&2
@@ -59,10 +62,13 @@ common_setup() {
common_qemu_custom_dir="${common_build_dir}/host-qemu-custom" common_qemu_custom_dir="${common_build_dir}/host-qemu-custom"
common_qemu_guest_variant_dir="${common_qemu_custom_dir}.${common_qemu_variant}" common_qemu_guest_variant_dir="${common_qemu_custom_dir}.${common_qemu_variant}"
common_qemu_variant_dir="${common_qemu_custom_dir}.${common_qemu_variant}" common_qemu_variant_dir="${common_qemu_custom_dir}.${common_qemu_variant}"
common_qemu_exec="${common_qemu_variant_dir}/${common_arch}-softmmu/qemu-system-${common_arch}"
common_qemu_guest_custom_dir="${common_build_dir}/qemu-custom" common_qemu_guest_custom_dir="${common_build_dir}/qemu-custom"
common_host_dir="${common_buildroot_out_dir}/host" common_host_dir="${common_buildroot_out_dir}/host"
common_images_dir="${common_buildroot_out_dir}/images" common_images_dir="${common_buildroot_out_dir}/images"
common_qcow2_file="${common_images_dir}/rootfs.ext2.qcow2" common_qcow2_file="${common_images_dir}/rootfs.ext2.qcow2"
common_staging_dir="${common_buildroot_out_dir}/staging"
common_target_dir="${common_buildroot_out_dir}/target"
common_gem5_run_dir="${common_out_arch_dir}/gem5/${common_run_id}" common_gem5_run_dir="${common_out_arch_dir}/gem5/${common_run_id}"
common_m5out_dir="${common_gem5_run_dir}/m5out" common_m5out_dir="${common_gem5_run_dir}/m5out"
common_trace_txt_file="${common_m5out_dir}/trace.txt" common_trace_txt_file="${common_m5out_dir}/trace.txt"
@@ -73,6 +79,7 @@ common_setup() {
common_gem5_out_dir="${common_dir}/gem5/${common_gem5_variant}" common_gem5_out_dir="${common_dir}/gem5/${common_gem5_variant}"
common_gem5_m5term="${common_gem5_out_dir}/m5term" common_gem5_m5term="${common_gem5_out_dir}/m5term"
common_gem5_build_dir="${common_gem5_out_dir}/build" common_gem5_build_dir="${common_gem5_out_dir}/build"
common_gem5_exec="${common_gem5_build_dir}/${common_gem5_arch}/gem5.${common_gem5_build_type}"
common_gem5_system_dir="${common_gem5_out_dir}/system" common_gem5_system_dir="${common_gem5_out_dir}/system"
if [ -n "$common_gem5_worktree" ]; then if [ -n "$common_gem5_worktree" ]; then
common_gem5_src_dir="${common_gem5_non_default_src_root_dir}/${common_gem5_worktree}" common_gem5_src_dir="${common_gem5_non_default_src_root_dir}/${common_gem5_worktree}"
@@ -80,9 +87,11 @@ common_setup() {
common_gem5_src_dir="${common_root_dir}/gem5/gem5" common_gem5_src_dir="${common_root_dir}/gem5/gem5"
fi fi
if "$common_gem5"; then if "$common_gem5"; then
common_exec="$common_gem5_exec"
common_run_dir="$common_gem5_run_dir" common_run_dir="$common_gem5_run_dir"
common_termout_file="$common_gem5_termout_file" common_termout_file="$common_gem5_termout_file"
else else
common_exec="$common_qemu_exec"
common_run_dir="$common_qemu_run_dir" common_run_dir="$common_qemu_run_dir"
common_termout_file="$common_qemu_termout_file" common_termout_file="$common_qemu_termout_file"
fi fi

40
getvar Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common"
while getopts ha:gL:M:N:n:Q:t: OPT; do
case "$OPT" in
h)
echo "https://github.com/cirosantilli/linux-kernel-module-cheat#getvar" 2>&1
exit 0
;;
a)
common_arch="$OPTARG"
;;
g)
common_gem5=true
;;
L)
common_linux_variant="$OPTARG"
;;
M)
common_gem5_variant="$OPTARG"
;;
N)
common_gem5_worktree="$OPTARG"
;;
n)
common_run_id="$OPTARG"
;;
Q)
common_qemu_variant="$OPTARG"
;;
t)
common_gem5_build_type="$OPTARG"
;;
?)
exit 2
;;
esac
done
shift "$(($OPTIND - 1))"
common_setup
eval "echo \$common_${1}"

13
run
View File

@@ -193,11 +193,6 @@ fi
if "$common_gem5"; then if "$common_gem5"; then
memory="${memory}B" memory="${memory}B"
if [ "$common_arch" = x86_64 ]; then
gem5_arch=X86
else
gem5_arch=ARM
fi
if "$trace_enabled"; then if "$trace_enabled"; then
gem5opts="${gem5opts} --debug-flags='${trace_type}' \\ gem5opts="${gem5opts} --debug-flags='${trace_type}' \\
" "
@@ -205,7 +200,7 @@ if "$common_gem5"; then
gem5_common="\ gem5_common="\
M5_PATH='${common_gem5_system_dir}' \\ M5_PATH='${common_gem5_system_dir}' \\
${debug_vm}\ ${debug_vm}\
'${common_gem5_build_dir}/${gem5_arch}/gem5.${common_gem5_build_type}' \\ '${common_exec}' \\
--debug-file=trace.txt \\ --debug-file=trace.txt \\
${gem5opts}\ ${gem5opts}\
-d '${common_m5out_dir}' \\ -d '${common_m5out_dir}' \\
@@ -276,14 +271,14 @@ else
fi fi
if "$prebuilt"; then if "$prebuilt"; then
common_mkdir common_mkdir
qemu_executable="qemu-system-${common_arch}" qemu_exec="qemu-system-${common_arch}"
else else
qemu_executable="${common_qemu_variant_dir}/${common_arch}-softmmu/qemu-system-${common_arch}" qemu_exec="${common_qemu_exec}"
fi fi
extra_flags="${extra_flags_qemu}${extra_flags}" extra_flags="${extra_flags_qemu}${extra_flags}"
qemu_common="\ qemu_common="\
${debug_vm}\ ${debug_vm}\
${qemu_executable} \\ ${qemu_exec} \\
-device rtl8139,netdev=net0 \\ -device rtl8139,netdev=net0 \\
-gdb 'tcp::${common_gdb_port}' \\ -gdb 'tcp::${common_gdb_port}' \\
-kernel '${common_linux_image}' \\ -kernel '${common_linux_image}' \\

6
runtc
View File

@@ -6,11 +6,7 @@ while getopts a:gh OPT; do
common_arch="$OPTARG" common_arch="$OPTARG"
;; ;;
h) h)
printf "Usage: $0 TOOL [TOOL_ARGS]... echo "https://github.com/cirosantilli/linux-kernel-module-cheat#runtc" 2>&1
Call a built ToolChain tool. Example:
$0 -a arm readelf -h
" 2>&1
exit 0 exit 0
;; ;;
esac esac