diff --git a/README.adoc b/README.adoc index 40cd7b9..73d2e1e 100644 --- a/README.adoc +++ b/README.adoc @@ -868,13 +868,13 @@ git clean -xdf . To only nuke one architecture, do: .... -rm -rf out/x86_64/buildroot +rm -rf "$(./getvar buildroot_out_dir)" .... 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 .... @@ -1132,15 +1132,15 @@ This method also allows us to keep run outputs in separate directories for later produces two separate `m5out` directories: .... -less out/aarch64/gem5/0/m5out -less out/aarch64/gem5/1/m5out +ls "$(./getvar -a A -g -n 0 m5out_dir)" +ls "$(./getvar -a A -g -n 1 m5out_dir)" .... and the gem5 host executable stdout and stderr can be found at: .... -less out/aarch64/gem5/0/termout.txt -less out/aarch64/gem5/1/termout.txt +less "$(./getvar -a A -g -n 0 termout_file)" +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. @@ -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 .... -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. However this still takes up the same ports as: @@ -1450,7 +1444,7 @@ so it is close to the failing `0xbf0000cc`. `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. @@ -1464,7 +1458,7 @@ This is not very easy, since by the time the module finishes loading, and `lx-sy Possibly asked at: * 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 @@ -1524,7 +1518,7 @@ Now let's find the offset of `myinit`: .... ./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 .... @@ -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): .... -less ./out/arm/qemu/0/trace.txt +less "$(./getvar -a arm trace_txt_file)" .... and break there: @@ -1845,7 +1839,7 @@ We have also double checked the address with: .... ./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 .... @@ -2276,13 +2270,13 @@ Host: 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: -* 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. -* `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. +* 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. +* `$(./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`: + @@ -2447,7 +2441,7 @@ TODO Can you run arm executables in the aarch64 guest? https://stackoverflow.com 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' .... @@ -2781,7 +2775,7 @@ To x11 packages have an `xserver` prefix as in: ./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 <>: @@ -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: .... -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: @@ -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: .... -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. @@ -3031,13 +3025,13 @@ CONFIG_IKCONFIG_PROC=y 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[]: .... -./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. @@ -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: .... -./runtc readelf -SW ./out/x86_64/buildroot/target/module_info.ko +./runtc readelf -SW "$(./getvar target_dir)/module_info.ko" .... contains: @@ -3375,7 +3369,7 @@ contains: and: .... -./runtc readelf -x .modinfo ./out/x86_64/buildroot/target/module_info.ko +./runtc readelf -x .modinfo "$(./getvar build_dir)/module_info.ko" .... 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: .... -./out/x86_64/buildroot/host/usr/bin/x86_64-buildroot-linux-uclibc-gdb \ +./runtc gdb \ -batch \ -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: + .... -./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: @@ -5288,7 +5282,7 @@ Notes: 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: @@ -5546,7 +5540,7 @@ cad 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: @@ -6119,7 +6113,7 @@ Snapshots are stored inside the `.qcow2` images themselves. 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: @@ -6770,7 +6764,7 @@ This has nothing to do with the Linux kernel, but it is cool: .... sudo apt-get install qemu-user ./build -a arm -cd out/arm/buildroot/target +cd "$(./getvar target_dir)" 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: .... -./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 .... @@ -6798,7 +6792,7 @@ Anyways, this warns us that the userland emulation will likely not be reliable, 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 ../host/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gdb \ --nh \ @@ -6832,14 +6826,12 @@ First we try some `-static` sanity checks. Works and prints `hello`: .... -./out/arm/buildroot/host/bin/arm-linux-gcc -static ./kernel_module/user/hello.c -./out/common/gem5/build/X86/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.out - -./out/arm/buildroot/host/bin/arm-linux-gcc -static ./kernel_module/user/hello.c -./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.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 +./runtc -a x86_64 gcc -static -o x86_64.out ./kernel_module/user/hello.c +./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 +"$(./getvar -a x86_64 -g exec)" ./gem5/gem5/configs/example/se.py -c ./x86_64.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 .... 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: .... -./out/common/gem5/build/X86/gem5.opt ./gem5/gem5/configs/example/se.py -c ./out/x86_64/buildroot/target/hello.out -./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./out/arm/buildroot/target/hello.out -./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./out/aarch64/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" +"$(./getvar -a arm -g exec)" ./gem5/gem5/configs/example/se.py -c "$(./getvar -a arm -g target_dir)/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. .... -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: @@ -6875,13 +6867,13 @@ gem5 user mode: .... make \ - -C out/arm/buildroot/build/dhrystone-2 \ - CC="$(pwd)/out/arm/buildroot/host/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gcc" \ + -C "$(./getvar -a arm build_dir)/dhrystone-2" \ + CC=""$(./getvar buildroot_out_dir)/host/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gcc" \ CFLAGS=-static \ ; -time ./out/common/gem5/build/ARM/gem5.opt \ +time "$(./getvar -a arm -g exec)" \ ./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 \ ; .... @@ -6898,7 +6890,7 @@ time ./run -a a -l 1 -g 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: @@ -7031,7 +7023,7 @@ The most interesting are events which show instructions that QEMU ran, for which 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: @@ -7045,7 +7037,7 @@ Enable other specific trace events: .... ./run -T trace1,trace2 ./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: @@ -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 -less ./out/x86_64/qemu/0/trace-lines.txt +less "$(./getvar -a x86_64 run_dir)/trace-lines.txt" .... 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 -less out/aarch64/gem5/0/m5out/trace.txt +less "$(./getvar -a aarch64 run_dir)/trace.txt" .... List all available debug flags: @@ -7288,7 +7280,7 @@ Trace the source lines just like <> with: .... ./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? @@ -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: .... -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: @@ -7564,7 +7556,7 @@ So we take a performance measurement approach instead: .... ./gem5-bench-cache -a aarch64 -cat out/aarch64/gem5/0/bench-cache.txt +cat "$(./getvar -a aarch64 run_dir)bench-cache.txt" .... 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 | .... -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, @@ -7882,10 +7880,10 @@ If you want to remove PARSEC later, Buildroot doesn't provide an automated packa .... rm -rf \ ./out/common/dl/parsec-* \ - ./out/arm-gem5/buildroot/build/parsec-* \ - ./out/arm-gem5/buildroot/build/packages-file-list.txt \ - ./out/arm-gem5/buildroot/images/rootfs.* \ - ./out/arm-gem5/buildroot/target/parsec-* \ + "$(./getvar buildroot_out_dir)"/build/parsec-* \ + "$(./getvar buildroot_out_dir)"/build/packages-file-list.txt \ + "$(./getvar buildroot_out_dir)"/images/rootfs.* \ + "$(./getvar buildroot_out_dir)"/target/parsec-* \ ; ./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: .... -out//gem5//m5out/cpt. +"$(./getvar -g run_dir)/m5out/cpt." .... where `` is the cycle number at which the checkpoint was taken. @@ -8267,7 +8265,7 @@ m5 writefile myfileguest myfilehost Host: .... -cat out/aarch64/gem5/0/m5out/myfilehost +cat "$(./getvar -a aarch64 -g m5out_dir)/myfilehost" .... Does not work for subdirectories, gem5 crashes: @@ -8459,7 +8457,7 @@ TODO We didn't manage to find a working ARM analogue to <>: link:kernel_m 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//buildroot/build/`), and then build there. +This is not normally possible with Buildroot, since normal Buildroot packages first copy files to the output directory (`$(./getvar -a build_dir)/`), 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. @@ -8564,7 +8562,7 @@ mv out out~ `make menuconfig` is a convenient way to find Buildroot configurations: .... -cd out/x86_64/buildroot +cd "$(./getvar buildroot_out_dir)" 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: .... -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: @@ -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: .... -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. @@ -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: .... -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 @@ -8908,19 +8906,39 @@ So for example when you run: 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: .... -cat ./out/arm/qemu/0/run.sh +cat "$(./getvar -a arm run_dir)/run.sh" .... 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: @@ -8968,7 +8986,7 @@ We tried to automate it on Travis with link:.travis.yml[] but it hits the curren .... ./bench-boot -cat out/bench-boot.txt +cat "$(./getvar bench_boot)" .... 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: .... -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: @@ -9068,7 +9086,7 @@ cat ../linux-kernel-module-cheat-regression/*/build-time.log ===== Find which packages are making the build slow .... -cd out/x86_64/buildroot +cd "$(./getvar buildroot_out_dir) make graph-build graph-depends xdg-open graphs/build.pie-packages.pdf xdg-open graphs/graph-depends.pdf @@ -9412,6 +9430,30 @@ include::run-usage.adoc[] :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 ==== Testing @@ -9497,7 +9539,7 @@ git bisect run ../qemu-bisect-boot git bisect reset cd .. 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[]. diff --git a/common b/common index 592a0d3..06476ae 100644 --- a/common +++ b/common @@ -30,15 +30,18 @@ common_setup() { case "$common_arch" in a|arm) common_arch=arm + common_gem5_arch=ARM ;; A|aarch64) common_arch=aarch64 + common_gem5_arch=ARM ;; m|mips64) common_arch=mips64 ;; x|x86_64) common_arch=x86_64 + common_gem5_arch=X86 ;; *) 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_guest_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_host_dir="${common_buildroot_out_dir}/host" common_images_dir="${common_buildroot_out_dir}/images" 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_m5out_dir="${common_gem5_run_dir}/m5out" 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_m5term="${common_gem5_out_dir}/m5term" 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" if [ -n "$common_gem5_worktree" ]; then 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" fi if "$common_gem5"; then + common_exec="$common_gem5_exec" common_run_dir="$common_gem5_run_dir" common_termout_file="$common_gem5_termout_file" else + common_exec="$common_qemu_exec" common_run_dir="$common_qemu_run_dir" common_termout_file="$common_qemu_termout_file" fi diff --git a/getvar b/getvar new file mode 100755 index 0000000..0d10299 --- /dev/null +++ b/getvar @@ -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}" diff --git a/run b/run index fbe051f..48fe5af 100755 --- a/run +++ b/run @@ -193,11 +193,6 @@ fi if "$common_gem5"; then memory="${memory}B" - if [ "$common_arch" = x86_64 ]; then - gem5_arch=X86 - else - gem5_arch=ARM - fi if "$trace_enabled"; then gem5opts="${gem5opts} --debug-flags='${trace_type}' \\ " @@ -205,7 +200,7 @@ if "$common_gem5"; then gem5_common="\ M5_PATH='${common_gem5_system_dir}' \\ ${debug_vm}\ -'${common_gem5_build_dir}/${gem5_arch}/gem5.${common_gem5_build_type}' \\ +'${common_exec}' \\ --debug-file=trace.txt \\ ${gem5opts}\ -d '${common_m5out_dir}' \\ @@ -276,14 +271,14 @@ else fi if "$prebuilt"; then common_mkdir - qemu_executable="qemu-system-${common_arch}" + qemu_exec="qemu-system-${common_arch}" else - qemu_executable="${common_qemu_variant_dir}/${common_arch}-softmmu/qemu-system-${common_arch}" + qemu_exec="${common_qemu_exec}" fi extra_flags="${extra_flags_qemu}${extra_flags}" qemu_common="\ ${debug_vm}\ -${qemu_executable} \\ +${qemu_exec} \\ -device rtl8139,netdev=net0 \\ -gdb 'tcp::${common_gdb_port}' \\ -kernel '${common_linux_image}' \\ diff --git a/runtc b/runtc index 73de5f6..e679d6c 100755 --- a/runtc +++ b/runtc @@ -6,11 +6,7 @@ while getopts a:gh OPT; do common_arch="$OPTARG" ;; h) - printf "Usage: $0 TOOL [TOOL_ARGS]... -Call a built ToolChain tool. Example: - - $0 -a arm readelf -h -" 2>&1 + echo "https://github.com/cirosantilli/linux-kernel-module-cheat#runtc" 2>&1 exit 0 ;; esac