mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-27 04:01:36 +01:00
Enable either ext2, initrd or initramfs for x86, arm and aarch64
Mention that initrd and initramfs must fit into memory. Fix missing stdout when ./run -d is used. Ignore ./run -n for non x86.
This commit is contained in:
321
README.adoc
321
README.adoc
@@ -248,88 +248,7 @@ root
|
|||||||
|
|
||||||
every time.
|
every time.
|
||||||
|
|
||||||
Here are some methods to automate that.
|
To automate that, use the methods described at: <<init>>
|
||||||
|
|
||||||
==== Replace init
|
|
||||||
|
|
||||||
This method replaces init and evals a command from the <<kernel-command-line-parameters>>:
|
|
||||||
|
|
||||||
....
|
|
||||||
./run -E 'echo "asdf qwer";insmod /hello.ko;/poweroff.out' -n
|
|
||||||
....
|
|
||||||
|
|
||||||
It is basically a shortcut for:
|
|
||||||
|
|
||||||
....
|
|
||||||
./run -e 'init=/eval.sh - lkmc_eval="insmod /hello.ko;/poweroff.out"' -n
|
|
||||||
....
|
|
||||||
|
|
||||||
although `-E` allows for quoting and newlines by using base64 encoding, so you should almost always use it, unless you are really counting each cycle ;-)
|
|
||||||
|
|
||||||
If the script is large, you can add it to a gitignored file and pass that to `-E` as in:
|
|
||||||
|
|
||||||
....
|
|
||||||
echo '
|
|
||||||
insmod /hello.ko
|
|
||||||
/poweroff.out
|
|
||||||
' > ignore.sh
|
|
||||||
./run -E "$(cat ignore.sh)" -n
|
|
||||||
....
|
|
||||||
|
|
||||||
or add it to a file to the root filesystem guest and rebuild:
|
|
||||||
|
|
||||||
....
|
|
||||||
echo '#!/bin/sh
|
|
||||||
insmod /hello.ko
|
|
||||||
/poweroff.out
|
|
||||||
' > rootfs_overlay/ignore.sh
|
|
||||||
chmod +x rootfs_overlay/ignore.sh
|
|
||||||
./build
|
|
||||||
./run -e 'init=/ignore.sh' -n
|
|
||||||
....
|
|
||||||
|
|
||||||
==== Run command at the end of BusyBox init
|
|
||||||
|
|
||||||
If you rely on something that BusyBox' init set up for you like networking, this is the way to go:
|
|
||||||
|
|
||||||
....
|
|
||||||
./run -e '- lkmc_eval="insmod /hello.ko;wget -S google.com;poweroff.out;"'
|
|
||||||
....
|
|
||||||
|
|
||||||
or add them to a new `init.d` entry to run at the end o the BusyBox init:
|
|
||||||
|
|
||||||
....
|
|
||||||
cp rootfs_overlay/etc/init.d/S98 rootfs_overlay/etc/init.d/S99
|
|
||||||
vim S99
|
|
||||||
./build
|
|
||||||
./run
|
|
||||||
....
|
|
||||||
|
|
||||||
and they will be run automatically before the login prompt.
|
|
||||||
|
|
||||||
`S99` is a git tracked convenience symlink to the gitignored `rootfs_overlay/etc/init.d/S99`
|
|
||||||
|
|
||||||
Scripts under `/etc/init.d` are run by `/etc/init.d/rcS`, which gets called by the line `::sysinit:/etc/init.d/rcS` in `/etc/inittab`.
|
|
||||||
|
|
||||||
==== The kernel panics despite poweroff
|
|
||||||
|
|
||||||
Just using Busybox' `poweroff` at the end of the `init` does not work and the kernel panics:
|
|
||||||
|
|
||||||
....
|
|
||||||
./run -E poweroff
|
|
||||||
....
|
|
||||||
|
|
||||||
because BusyBox' `poweroff` tries to do some fancy stuff like killing init, likely to allow userland to shutdown nicely.
|
|
||||||
|
|
||||||
But this fails when we are `init` itself!
|
|
||||||
|
|
||||||
`poweroff` works more brutally and effectively if you add `-f`:
|
|
||||||
|
|
||||||
....
|
|
||||||
./run -E 'poweroff -f'
|
|
||||||
....
|
|
||||||
|
|
||||||
but why not just use your super simple and effective `/poweroff.out` and be done with it?
|
|
||||||
|
|
||||||
=== Kernel command line parameters
|
=== Kernel command line parameters
|
||||||
|
|
||||||
@@ -367,6 +286,12 @@ When dealing with real boards, extra command line options are provided on some m
|
|||||||
* GRUB configuration files: https://askubuntu.com/questions/19486/how-do-i-add-a-kernel-boot-parameter
|
* GRUB configuration files: https://askubuntu.com/questions/19486/how-do-i-add-a-kernel-boot-parameter
|
||||||
* Raspberry pi `/boot/cmdline.txt` on a magic partition: https://raspberrypi.stackexchange.com/questions/14839/how-to-change-the-kernel-commandline-for-archlinuxarm-on-raspberry-pi-effectly
|
* Raspberry pi `/boot/cmdline.txt` on a magic partition: https://raspberrypi.stackexchange.com/questions/14839/how-to-change-the-kernel-commandline-for-archlinuxarm-on-raspberry-pi-effectly
|
||||||
|
|
||||||
|
=== Kernel command line parameters escaping
|
||||||
|
|
||||||
|
Double quotes can be used to escape spaces as in `opt="a b"`, but double quotes themselves cannot be escaped, e.g. `opt"a\"b"`
|
||||||
|
|
||||||
|
This even lead us to use base64 encoding with `-E`!
|
||||||
|
|
||||||
=== What command was actually run?
|
=== What command was actually run?
|
||||||
|
|
||||||
When asking for help on upstream repositories outside of this repository, you will need to provide the commands that you are running in detail without referencing our scripts.
|
When asking for help on upstream repositories outside of this repository, you will need to provide the commands that you are running in detail without referencing our scripts.
|
||||||
@@ -408,6 +333,12 @@ If you want to break immediately at a symbol, e.g. `start_kernel` of the boot se
|
|||||||
./rungdb start_kernel
|
./rungdb start_kernel
|
||||||
....
|
....
|
||||||
|
|
||||||
|
or at a given line:
|
||||||
|
|
||||||
|
....
|
||||||
|
./rungdb init/main.c:1088
|
||||||
|
....
|
||||||
|
|
||||||
Now QEMU will stop there, and you can use the normal GDB commands:
|
Now QEMU will stop there, and you can use the normal GDB commands:
|
||||||
|
|
||||||
....
|
....
|
||||||
@@ -948,37 +879,140 @@ TODOs:
|
|||||||
|
|
||||||
When the Linux kernel finishes booting, it runs an executable as the first and only userland process.
|
When the Linux kernel finishes booting, it runs an executable as the first and only userland process.
|
||||||
|
|
||||||
The default path is `/init`, but we an set a custom one with the `init=` <<kernel-command-line-parameters,kernel command line parameter>>.
|
This init process is then responsible for setting up the entire userland (or destroying everything when you want to have fun).
|
||||||
|
|
||||||
This process is then responsible for setting up the entire userland (or destroying everything when you want to have fun).
|
|
||||||
|
|
||||||
This typically means reading some configuration files (e.g. `/etc/initrc`) and forking a bunch of userland executables based on those files.
|
This typically means reading some configuration files (e.g. `/etc/initrc`) and forking a bunch of userland executables based on those files.
|
||||||
|
|
||||||
systemd is a "popular" `/init` implementation for desktop distros as of 2017.
|
systemd provides a "popular" init implementation for desktop distros as of 2017.
|
||||||
|
|
||||||
BusyBox provides its own minimalistic init implementation which Buildroot uses by default.
|
BusyBox provides its own minimalistic init implementation which Buildroot, and therefore this repo, uses by default.
|
||||||
|
|
||||||
=== Custom init
|
=== Replace init
|
||||||
|
|
||||||
Is the default BusyBox `/init` too bloated for you, minimalism freak?
|
To have more control over the system, you can replace BusyBox's init with your own.
|
||||||
|
|
||||||
No problem, just use the `init` kernel boot parameter:
|
The following method replaces init and evals a command from the <<kernel-command-line-parameters>>:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run -e 'init=/sleep_forever.out'
|
./run -E 'echo "asdf qwer";insmod /hello.ko;/poweroff.out' -n
|
||||||
....
|
....
|
||||||
|
|
||||||
Remember that shell scripts can also be used for `init` https://unix.stackexchange.com/questions/174062/init-as-a-shell-script/395375#395375:
|
It is basically a shortcut for:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run -e 'init=/count.sh'
|
./run -e 'init=/eval.sh - lkmc_eval="insmod /hello.ko;/poweroff.out"' -n
|
||||||
....
|
....
|
||||||
|
|
||||||
Also remember that if your init returns, the kernel will panic, there are just two non-panic possibilities:
|
although `-E` is smarter:
|
||||||
|
|
||||||
|
* allows quoting and newlines by using base64 encoding, see: <<kernel-command-line-parameters-escaping>>
|
||||||
|
* automatically chooses between `init=` and `rcinit=` for you, see: <<path-to-init>>
|
||||||
|
|
||||||
|
so you should almost always use it, unless you are really counting each cycle ;-)
|
||||||
|
|
||||||
|
If the script is large, you can add it to a gitignored file and pass that to `-E` as in:
|
||||||
|
|
||||||
|
....
|
||||||
|
echo '
|
||||||
|
insmod /hello.ko
|
||||||
|
/poweroff.out
|
||||||
|
' > ignore.sh
|
||||||
|
./run -E "$(cat ignore.sh)" -n
|
||||||
|
....
|
||||||
|
|
||||||
|
or add it to a file to the root filesystem guest and rebuild:
|
||||||
|
|
||||||
|
....
|
||||||
|
echo '#!/bin/sh
|
||||||
|
insmod /hello.ko
|
||||||
|
/poweroff.out
|
||||||
|
' > rootfs_overlay/ignore.sh
|
||||||
|
chmod +x rootfs_overlay/ignore.sh
|
||||||
|
./build
|
||||||
|
./run -e 'init=/ignore.sh' -n
|
||||||
|
....
|
||||||
|
|
||||||
|
Remember that if your init returns, the kernel will panic, there are just two non-panic possibilities:
|
||||||
|
|
||||||
* run forever in a loop or long sleep
|
* run forever in a loop or long sleep
|
||||||
* `poweroff` the machine
|
* `poweroff` the machine
|
||||||
|
|
||||||
|
==== The kernel panics despite poweroff
|
||||||
|
|
||||||
|
Just using BusyBox' `poweroff` at the end of the `init` does not work and the kernel panics:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run -E poweroff
|
||||||
|
....
|
||||||
|
|
||||||
|
because BusyBox' `poweroff` tries to do some fancy stuff like killing init, likely to allow userland to shutdown nicely.
|
||||||
|
|
||||||
|
But this fails when we are `init` itself!
|
||||||
|
|
||||||
|
`poweroff` works more brutally and effectively if you add `-f`:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run -E 'poweroff -f'
|
||||||
|
....
|
||||||
|
|
||||||
|
but why not just use your super simple and effective `/poweroff.out` and be done with it?
|
||||||
|
|
||||||
|
=== Run command at the end of BusyBox init
|
||||||
|
|
||||||
|
If you rely on something that BusyBox' init set up for you like networking, you caould do:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run -e '- lkmc_eval="insmod /hello.ko;wget -S google.com;poweroff.out;"'
|
||||||
|
....
|
||||||
|
|
||||||
|
The `lkmc_eval` option gets evaled by our default `S98` startup script if present.
|
||||||
|
|
||||||
|
Alternatively, add them to a new `init.d` entry to run at the end o the BusyBox init:
|
||||||
|
|
||||||
|
....
|
||||||
|
cp rootfs_overlay/etc/init.d/S98 rootfs_overlay/etc/init.d/S99
|
||||||
|
vim S99
|
||||||
|
./build
|
||||||
|
./run
|
||||||
|
....
|
||||||
|
|
||||||
|
and they will be run automatically before the login prompt.
|
||||||
|
|
||||||
|
`S99` is a git tracked convenience symlink to the gitignored `rootfs_overlay/etc/init.d/S99`
|
||||||
|
|
||||||
|
Scripts under `/etc/init.d` are run by `/etc/init.d/rcS`, which gets called by the line `::sysinit:/etc/init.d/rcS` in `/etc/inittab`.
|
||||||
|
|
||||||
|
=== Path to init
|
||||||
|
|
||||||
|
The init is selected at:
|
||||||
|
|
||||||
|
- initrd or initramfs system: `/init`, a custom one can be set with the `rdinit=` <<kernel-command-line-parameters,kernel command line parameter>>
|
||||||
|
- otherwise: default is `/sbin/init`, followed by some other paths, a custom one can be set with `init=`
|
||||||
|
|
||||||
|
More details: https://unix.stackexchange.com/questions/30414/what-can-make-passing-init-path-to-program-to-the-kernel-not-start-program-as-i/430614#430614
|
||||||
|
|
||||||
|
=== Init environment
|
||||||
|
|
||||||
|
Documented at link:https://www.kernel.org/doc/html/v4.14/admin-guide/kernel-parameters.html[]:
|
||||||
|
|
||||||
|
____
|
||||||
|
The kernel parses parameters from the kernel command line up to "-"; if it doesn't recognize a parameter and it doesn't contain a '.', the parameter gets passed to init: parameters with '=' go into init's environment, others are passed as command line arguments to init. Everything after "-" is passed as an argument to init.
|
||||||
|
____
|
||||||
|
|
||||||
|
And you can try it out with:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run -e 'init=/init_env_poweroff.sh - asdf=qwer zxcv' -n
|
||||||
|
....
|
||||||
|
|
||||||
|
Also note how the annoying dash `-` also gets passed as a parameter to `init`, which makes it impossible to use this method for most executables.
|
||||||
|
|
||||||
|
Finally, the docs are lying, arguments with dots that come after `-` are still treated specially (of the form `subsystem.somevalue`) and disappear:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run -e 'init=/init_env_poweroff.sh - /poweroff.out' -n
|
||||||
|
....
|
||||||
|
|
||||||
=== Disable networking
|
=== Disable networking
|
||||||
|
|
||||||
The default BusyBox init scripts enable networking, and there is a 15 second timeout in case your network is down or if your kernel / emulator setup does not support it.
|
The default BusyBox init scripts enable networking, and there is a 15 second timeout in case your network is down or if your kernel / emulator setup does not support it.
|
||||||
@@ -995,20 +1029,6 @@ To restore it, run:
|
|||||||
./build -- initscripts-reconfigure
|
./build -- initscripts-reconfigure
|
||||||
....
|
....
|
||||||
|
|
||||||
=== The init environment
|
|
||||||
|
|
||||||
The docs make it clear https://www.kernel.org/doc/html/v4.14/admin-guide/kernel-parameters.html
|
|
||||||
|
|
||||||
____
|
|
||||||
The kernel parses parameters from the kernel command line up to “–”; if it doesn’t recognize a parameter and it doesn’t contain a ‘.’, the parameter gets passed to init: parameters with ‘=’ go into init’s environment, others are passed as command line arguments to init. Everything after “–” is passed as an argument to init.
|
|
||||||
____
|
|
||||||
|
|
||||||
And you can try it out with:
|
|
||||||
|
|
||||||
....
|
|
||||||
./run -e 'init=/init_env_poweroff.sh - asdf=qwer zxcv' -n
|
|
||||||
....
|
|
||||||
|
|
||||||
== modprobe
|
== modprobe
|
||||||
|
|
||||||
If you are feeling fancy, you can also insert modules with:
|
If you are feeling fancy, you can also insert modules with:
|
||||||
@@ -1088,7 +1108,7 @@ Only tested successfully in `x86_64`.
|
|||||||
Build:
|
Build:
|
||||||
|
|
||||||
....
|
....
|
||||||
./build -i br2_x11
|
./build -b br2_x11
|
||||||
./run
|
./run
|
||||||
....
|
....
|
||||||
|
|
||||||
@@ -1257,13 +1277,18 @@ The bootloader, which for us is QEMU itself, is then configured to put that CPIO
|
|||||||
|
|
||||||
With this setup, you don't even need to give a root filesystem to the kernel, it just does everything in memory in a ramfs.
|
With this setup, you don't even need to give a root filesystem to the kernel, it just does everything in memory in a ramfs.
|
||||||
|
|
||||||
Try it out with:
|
To enable initrd instead of the default ext2 disk image, do:
|
||||||
|
|
||||||
....
|
....
|
||||||
|
./build -i
|
||||||
./run -i
|
./run -i
|
||||||
....
|
....
|
||||||
|
|
||||||
Notice how it boots fine, even though `-drive` is not given.
|
Notice how it boots fine, even though this leads to not giving QEMU the `-drive` option, as can be verified with:
|
||||||
|
|
||||||
|
....
|
||||||
|
cat ./run.log
|
||||||
|
....
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
@@ -1274,9 +1299,21 @@ cat f
|
|||||||
# can't open 'f': No such file or directory
|
# can't open 'f': No such file or directory
|
||||||
....
|
....
|
||||||
|
|
||||||
This can be good for automated tests, as it ensures that you are using a pristine unmodified system image every time.
|
which can be good for automated tests, as it ensures that you are using a pristine unmodified system image every time.
|
||||||
|
|
||||||
The main ingredients to get this working are:
|
One downside of this method is that it has to put the entire filesystem into memory, and could lead to a panic:
|
||||||
|
|
||||||
|
....
|
||||||
|
end Kernel panic - not syncing: Out of memory and no killable processes...
|
||||||
|
....
|
||||||
|
|
||||||
|
This can be solved by increasing the memory with:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run -im 256M
|
||||||
|
....
|
||||||
|
|
||||||
|
The main ingredients to get initrd working are:
|
||||||
|
|
||||||
* `BR2_TARGET_ROOTFS_CPIO=y`: make Buildroot generate `output/images/rootfs.cpio` in addition to the other images.
|
* `BR2_TARGET_ROOTFS_CPIO=y`: make Buildroot generate `output/images/rootfs.cpio` in addition to the other images.
|
||||||
+
|
+
|
||||||
@@ -1311,15 +1348,43 @@ So the only argument that QEMU needs is the `-kernel`, no `-drive` not even `-in
|
|||||||
Try it out with:
|
Try it out with:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run -a aarch64
|
rm -f buildroot/output.x86_64~/build/linux-custom/.config
|
||||||
|
./build -I
|
||||||
|
./run -I
|
||||||
....
|
....
|
||||||
|
|
||||||
since our <<aarch64>> setup uses it by default.
|
The line:
|
||||||
|
|
||||||
|
....
|
||||||
|
rm -f buildroot/output.x86_64~/build/linux-custom/.config
|
||||||
|
....
|
||||||
|
|
||||||
|
is only needed the first time you move from a different root filesystem method (ext2 or cpio) to initramfs. It is needed because Buildroot is not automatically updating `CONFIG_INITRAMFS_SOURCE` in the kernel config for some reason: https://stackoverflow.com/questions/49260466/why-when-i-change-br2-linux-kernel-custom-config-file-and-run-make-linux-reconfi
|
||||||
|
|
||||||
|
Then to go back to another boot method such as ext filesystems to:
|
||||||
|
|
||||||
|
....
|
||||||
|
rm -f buildroot/output.x86_64~/build/linux-custom/.config
|
||||||
|
./build
|
||||||
|
./run
|
||||||
|
....
|
||||||
|
|
||||||
|
It is interesting to see how this increases the size of the kernel image if you do a:
|
||||||
|
|
||||||
|
....
|
||||||
|
ls -lh buildroot/output.x86_64~/images/bzImage
|
||||||
|
....
|
||||||
|
|
||||||
|
before and after using initramfs, since the `.cpio` is now glued to the kernel image.
|
||||||
|
|
||||||
In the background, it uses `BR2_TARGET_ROOTFS_INITRAMFS`, and this makes the kernel config option `CONFIG_INITRAMFS_SOURCE` point to the CPIO that will be embedded in the kernel image.
|
In the background, it uses `BR2_TARGET_ROOTFS_INITRAMFS`, and this makes the kernel config option `CONFIG_INITRAMFS_SOURCE` point to the CPIO that will be embedded in the kernel image.
|
||||||
|
|
||||||
http://nairobi-embedded.org/initramfs_tutorial.html shows a full manual setup.
|
http://nairobi-embedded.org/initramfs_tutorial.html shows a full manual setup.
|
||||||
|
|
||||||
|
=== gem5 initrd
|
||||||
|
|
||||||
|
TODO we were not able to get it working yet: https://stackoverflow.com/questions/49261801/how-to-boot-the-linux-kernel-with-initrd-or-initramfs-with-gem5
|
||||||
|
|
||||||
== Linux kernel
|
== Linux kernel
|
||||||
|
|
||||||
=== Use your own kernel config
|
=== Use your own kernel config
|
||||||
@@ -1992,6 +2057,18 @@ TODO These look promising:
|
|||||||
|
|
||||||
TODO: now to verify this with the Linux kernel? Besides raw performance benchmarks.
|
TODO: now to verify this with the Linux kernel? Besides raw performance benchmarks.
|
||||||
|
|
||||||
|
===== gem5 memory size
|
||||||
|
|
||||||
|
....
|
||||||
|
./run -a arm -m 512M
|
||||||
|
....
|
||||||
|
|
||||||
|
and verify inside the guest with:
|
||||||
|
|
||||||
|
....
|
||||||
|
free -m
|
||||||
|
....
|
||||||
|
|
||||||
===== gem5 disk and network latency
|
===== gem5 disk and network latency
|
||||||
|
|
||||||
TODO These look promising:
|
TODO These look promising:
|
||||||
@@ -2080,7 +2157,7 @@ Buildroot supports it, which makes everything just trivial:
|
|||||||
....
|
....
|
||||||
printf 'BR2_PACKAGE_OPENBLAS=y\n' >> br2_local
|
printf 'BR2_PACKAGE_OPENBLAS=y\n' >> br2_local
|
||||||
printf 'BR2_TARGET_ROOTFS_EXT2_SIZE="128M"\n' >> br2_local
|
printf 'BR2_TARGET_ROOTFS_EXT2_SIZE="128M"\n' >> br2_local
|
||||||
./build -a arm -g -i br2_local -- kernel_module-reconfigure
|
./build -a arm -g -b br2_local -- kernel_module-reconfigure
|
||||||
....
|
....
|
||||||
|
|
||||||
and then inside the guest run our test program:
|
and then inside the guest run our test program:
|
||||||
@@ -2113,7 +2190,7 @@ There are two ways to run PARSEC with this repo:
|
|||||||
====== PARSEC benchmark without parsecmgmt
|
====== PARSEC benchmark without parsecmgmt
|
||||||
|
|
||||||
....
|
....
|
||||||
configure -gpq && ./build -a arm -g -i br2_parsec
|
configure -gpq && ./build -a arm -g -b br2_parsec
|
||||||
./run -a arm -g
|
./run -a arm -g
|
||||||
....
|
....
|
||||||
|
|
||||||
@@ -2146,7 +2223,7 @@ Running a benchmark of a different size requires a rebuild wit:
|
|||||||
-c 'BR2_PACKAGE_PARSEC_BENCHMARK_INPUT_SIZE="simsmall"' \
|
-c 'BR2_PACKAGE_PARSEC_BENCHMARK_INPUT_SIZE="simsmall"' \
|
||||||
-c BR2_TARGET_ROOTFS_EXT2_SIZE="500M" \
|
-c BR2_TARGET_ROOTFS_EXT2_SIZE="500M" \
|
||||||
-g \
|
-g \
|
||||||
-i br2_parsec \
|
-b br2_parsec \
|
||||||
-- parsec-benchmark-reconfigure \
|
-- parsec-benchmark-reconfigure \
|
||||||
;
|
;
|
||||||
....
|
....
|
||||||
@@ -2198,7 +2275,7 @@ If you still want to run this, try it out with:
|
|||||||
./build -a arm \
|
./build -a arm \
|
||||||
-c BR2_TARGET_ROOTFS_EXT2_SIZE="3G" \
|
-c BR2_TARGET_ROOTFS_EXT2_SIZE="3G" \
|
||||||
-g
|
-g
|
||||||
-i br2_parsec
|
-b br2_parsec
|
||||||
-- parsec-benchmark-reconfigure \
|
-- parsec-benchmark-reconfigure \
|
||||||
;
|
;
|
||||||
....
|
....
|
||||||
@@ -2225,7 +2302,7 @@ BR2_PACKAGE_PARSEC_BENCHMARK_INPUT_SIZE=simsmall
|
|||||||
and then rebuild with:
|
and then rebuild with:
|
||||||
|
|
||||||
....
|
....
|
||||||
./build -a arm -g -i br2_parsec -- parsec-benchmark-reconfigure
|
./build -a arm -g -b br2_parsec -- parsec-benchmark-reconfigure
|
||||||
....
|
....
|
||||||
|
|
||||||
This limitation exists because `parsecmgmt` generates the input files just before running via the Bash scripts, but we can't run `parsecmgmt` on gem5 as it is too slow!
|
This limitation exists because `parsecmgmt` generates the input files just before running via the Bash scripts, but we can't run `parsecmgmt` on gem5 as it is too slow!
|
||||||
@@ -2272,7 +2349,7 @@ before going for the cross compile build.
|
|||||||
Don't forget to explicitly rebuild PARSEC with:
|
Don't forget to explicitly rebuild PARSEC with:
|
||||||
+
|
+
|
||||||
....
|
....
|
||||||
./build -a arm -g -i br2_parsec parsec-benchmark-reconfigure
|
./build -a arm -g -b br2_parsec parsec-benchmark-reconfigure
|
||||||
....
|
....
|
||||||
+
|
+
|
||||||
You may also want to test if your patches are still functionally correct inside of QEMU first, which is a faster emulator.
|
You may also want to test if your patches are still functionally correct inside of QEMU first, which is a faster emulator.
|
||||||
@@ -2627,7 +2704,7 @@ dmesg
|
|||||||
|
|
||||||
We provide the following mechanisms:
|
We provide the following mechanisms:
|
||||||
|
|
||||||
* `./build -i br2_local`: append the file `br2_local` to a single build. Must be passed every time you run `./build`.
|
* `./build -b br2_local`: append the file `br2_local` to a single build. Must be passed every time you run `./build`.
|
||||||
+
|
+
|
||||||
For convenience, we already gitignore `br2_local` for you.
|
For convenience, we already gitignore `br2_local` for you.
|
||||||
+
|
+
|
||||||
|
|||||||
7
br2
7
br2
@@ -1,6 +1,11 @@
|
|||||||
# Custom packages
|
# Custom packages
|
||||||
BR2_PACKAGE_KERNEL_MODULE=y
|
BR2_PACKAGE_KERNEL_MODULE=y
|
||||||
|
|
||||||
|
# Rootfs
|
||||||
|
BR2_TARGET_ROOTFS_CPIO=n
|
||||||
|
BR2_TARGET_ROOTFS_EXT2=y
|
||||||
|
BR2_TARGET_ROOTFS_INITRAMFS=n
|
||||||
|
|
||||||
BR2_CCACHE=y
|
BR2_CCACHE=y
|
||||||
# Otherwise our precious debug would break!
|
# Otherwise our precious debug would break!
|
||||||
BR2_CCACHE_USE_BASEDIR=n
|
BR2_CCACHE_USE_BASEDIR=n
|
||||||
@@ -19,8 +24,6 @@ BR2_ROOTFS_OVERLAY="../rootfs_overlay"
|
|||||||
BR2_ROOTFS_POST_BUILD_SCRIPT="../rootfs_post_build_script"
|
BR2_ROOTFS_POST_BUILD_SCRIPT="../rootfs_post_build_script"
|
||||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="../rootfs_post_image_script"
|
BR2_ROOTFS_POST_IMAGE_SCRIPT="../rootfs_post_image_script"
|
||||||
BR2_ROOTFS_USERS_TABLES="../user_table"
|
BR2_ROOTFS_USERS_TABLES="../user_table"
|
||||||
BR2_TARGET_ROOTFS_CPIO=y
|
|
||||||
BR2_TARGET_ROOTFS_EXT2=y
|
|
||||||
BR2_TOOLCHAIN_BUILDROOT_CXX=y
|
BR2_TOOLCHAIN_BUILDROOT_CXX=y
|
||||||
BR2_TOOLCHAIN_BUILDROOT_FORTRAN=y
|
BR2_TOOLCHAIN_BUILDROOT_FORTRAN=y
|
||||||
BR2_TOOLCHAIN_BUILDROOT_WCHAR=y
|
BR2_TOOLCHAIN_BUILDROOT_WCHAR=y
|
||||||
|
|||||||
22
build
22
build
@@ -12,11 +12,14 @@ linux_kernel_custom_config_file=''
|
|||||||
post_script_args=''
|
post_script_args=''
|
||||||
qemu_sdl='--enable-sdl --with-sdlabi=2.0'
|
qemu_sdl='--enable-sdl --with-sdlabi=2.0'
|
||||||
v=0
|
v=0
|
||||||
while getopts 'a:c:Cgj:i:kK:lp:qS:v' OPT; do
|
while getopts 'a:b:c:Cgj:IiKk:lp:qS:v' OPT; do
|
||||||
case "$OPT" in
|
case "$OPT" in
|
||||||
a)
|
a)
|
||||||
arch="$OPTARG"
|
arch="$OPTARG"
|
||||||
;;
|
;;
|
||||||
|
b)
|
||||||
|
config_fragments="$config_fragments $OPTARG"
|
||||||
|
;;
|
||||||
c)
|
c)
|
||||||
echo "$OPTARG" >> br2_cli
|
echo "$OPTARG" >> br2_cli
|
||||||
;;
|
;;
|
||||||
@@ -26,11 +29,22 @@ while getopts 'a:c:Cgj:i:kK:lp:qS:v' OPT; do
|
|||||||
g)
|
g)
|
||||||
gem5=true
|
gem5=true
|
||||||
;;
|
;;
|
||||||
j)
|
I)
|
||||||
j="$OPTARG"
|
echo "
|
||||||
|
BR2_TARGET_ROOTFS_CPIO=n
|
||||||
|
BR2_TARGET_ROOTFS_EXT2=n
|
||||||
|
BR2_TARGET_ROOTFS_INITRAMFS=y
|
||||||
|
" >> br2_cli
|
||||||
;;
|
;;
|
||||||
i)
|
i)
|
||||||
config_fragments="$config_fragments $OPTARG"
|
echo "
|
||||||
|
BR2_TARGET_ROOTFS_CPIO=y
|
||||||
|
BR2_TARGET_ROOTFS_EXT2=n
|
||||||
|
BR2_TARGET_ROOTFS_INITRAMFS=n
|
||||||
|
" >> br2_cli
|
||||||
|
;;
|
||||||
|
j)
|
||||||
|
echo "$OPTARG" >> br2_cli
|
||||||
;;
|
;;
|
||||||
k)
|
k)
|
||||||
extra_make_args="$extra_make_args kernel_module-reconfigure"
|
extra_make_args="$extra_make_args kernel_module-reconfigure"
|
||||||
|
|||||||
82
run
82
run
@@ -19,8 +19,11 @@ gem5=false
|
|||||||
gem5opts=''
|
gem5opts=''
|
||||||
lkmc_eval=''
|
lkmc_eval=''
|
||||||
initrd=false
|
initrd=false
|
||||||
|
initramfs=false
|
||||||
|
memory=128M
|
||||||
|
nographic=false
|
||||||
root=''
|
root=''
|
||||||
while getopts a:c:DdE:e:G:giKknt:x OPT; do
|
while getopts a:c:DdE:e:G:gIiKkm:nt:x OPT; do
|
||||||
case "$OPT" in
|
case "$OPT" in
|
||||||
a)
|
a)
|
||||||
arch="$OPTARG"
|
arch="$OPTARG"
|
||||||
@@ -29,7 +32,7 @@ while getopts a:c:DdE:e:G:giKknt:x OPT; do
|
|||||||
cpus="$OPTARG"
|
cpus="$OPTARG"
|
||||||
;;
|
;;
|
||||||
d)
|
d)
|
||||||
extra_flags_qemu="$extra_flags -S -s"
|
extra_flags_qemu="$extra_flags_qemu -S -s"
|
||||||
;;
|
;;
|
||||||
D)
|
D)
|
||||||
debug_vm='gdb -q -ex start --args'
|
debug_vm='gdb -q -ex start --args'
|
||||||
@@ -47,7 +50,7 @@ while getopts a:c:DdE:e:G:giKknt:x OPT; do
|
|||||||
extra_append="$extra_append kgdbwait"
|
extra_append="$extra_append kgdbwait"
|
||||||
# For those who want to try KDB.
|
# For those who want to try KDB.
|
||||||
#extra_append="$extra_append kgdbwait kgdboc=kbd"
|
#extra_append="$extra_append kgdbwait kgdboc=kbd"
|
||||||
extra_flags_qemu="$extra_flags -serial tcp::1234,server,nowait"
|
extra_flags_qemu="$extra_flags_qemu -serial tcp::1234,server,nowait"
|
||||||
kgdb=true
|
kgdb=true
|
||||||
;;
|
;;
|
||||||
g)
|
g)
|
||||||
@@ -56,12 +59,17 @@ while getopts a:c:DdE:e:G:giKknt:x OPT; do
|
|||||||
G)
|
G)
|
||||||
gem5opts="$OPTARG"
|
gem5opts="$OPTARG"
|
||||||
;;
|
;;
|
||||||
|
I)
|
||||||
|
initramfs=true
|
||||||
|
;;
|
||||||
i)
|
i)
|
||||||
initrd=true
|
initrd=true
|
||||||
;;
|
;;
|
||||||
|
m)
|
||||||
|
memory="$OPTARG"
|
||||||
|
;;
|
||||||
n)
|
n)
|
||||||
extra_append="$extra_append console=ttyS0"
|
nographic=true
|
||||||
extra_flags_qemu="$extra_flags -nographic"
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
@@ -75,12 +83,27 @@ root_dir="$(pwd)"
|
|||||||
buildroot_dir="${root_dir}/buildroot"
|
buildroot_dir="${root_dir}/buildroot"
|
||||||
out_dir="${root_dir}/buildroot/output.${arch_dir}~"
|
out_dir="${root_dir}/buildroot/output.${arch_dir}~"
|
||||||
images_dir="${out_dir}/images"
|
images_dir="${out_dir}/images"
|
||||||
|
if "$initrd" || "$initramfs"; then
|
||||||
|
ramfs=true
|
||||||
|
else
|
||||||
|
ramfs=false
|
||||||
|
fi
|
||||||
if [ -n "$lkmc_eval" ]; then
|
if [ -n "$lkmc_eval" ]; then
|
||||||
extra_append="$extra_append init=/eval_base64.sh - lkmc_eval=\"$(printf "$lkmc_eval" | base64)\""
|
if "$ramfs"; then
|
||||||
|
initarg="rdinit"
|
||||||
|
else
|
||||||
|
initarg="init"
|
||||||
|
fi
|
||||||
|
extra_append="${extra_append} ${initarg}=/eval_base64.sh - lkmc_eval=\"$(printf "$lkmc_eval" | base64)\""
|
||||||
|
fi
|
||||||
|
if "$nographic" && [ "$arch" = x86_64 ]; then
|
||||||
|
extra_append="$extra_append console=ttyS0"
|
||||||
|
extra_flags_qemu="$extra_flags_qemu -nographic"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if "$gem5"; then
|
if "$gem5"; then
|
||||||
build_dir="${out_dir}/build/gem5-1.0"
|
build_dir="${out_dir}/build/gem5-1.0"
|
||||||
|
memory="${memory}B"
|
||||||
gem5_dir="${build_dir}/gem5"
|
gem5_dir="${build_dir}/gem5"
|
||||||
if [ "$arch" = x86_64 ]; then
|
if [ "$arch" = x86_64 ]; then
|
||||||
gem5_arch=X86
|
gem5_arch=X86
|
||||||
@@ -98,6 +121,7 @@ ${gem5opts} \
|
|||||||
--checkpoint-dir='${gem5_cpt_dir}' \
|
--checkpoint-dir='${gem5_cpt_dir}' \
|
||||||
--disk-image='${out_dir}/images/rootfs.ext2' \
|
--disk-image='${out_dir}/images/rootfs.ext2' \
|
||||||
--kernel='${out_dir}/build/linux-custom/vmlinux' \
|
--kernel='${out_dir}/build/linux-custom/vmlinux' \
|
||||||
|
--mem-size=${memory} \
|
||||||
--num-cpus='${cpus}' \
|
--num-cpus='${cpus}' \
|
||||||
"
|
"
|
||||||
if [ "$arch" = x86_64 ]; then
|
if [ "$arch" = x86_64 ]; then
|
||||||
@@ -109,11 +133,13 @@ ${gem5opts} \
|
|||||||
$extra_flags \
|
$extra_flags \
|
||||||
"
|
"
|
||||||
elif [ "$arch" = arm ] || [ "$arch" = aarch64 ]; then
|
elif [ "$arch" = arm ] || [ "$arch" = aarch64 ]; then
|
||||||
|
# TODO why is it mandatory to pass mem= here? Not true for QEMU.
|
||||||
|
# Anything smaller than physical blows up as expected, but why can't it auto-detect the right value?
|
||||||
cmd="${gem5_common} \
|
cmd="${gem5_common} \
|
||||||
--command-line='earlyprintk=pl011,0x1c090000 console=ttyAMA0 lpj=19988480 rw loglevel=8 mem=512MB root=/dev/sda $extra_append' \
|
--command-line='earlyprintk=pl011,0x1c090000 console=ttyAMA0 lpj=19988480 rw loglevel=8 mem=${memory} root=/dev/sda $extra_append' \
|
||||||
--dtb-file='${gem5_dir}/system/arm/dt/$([ "$arch" = arm ] && echo "armv7_gem5_v1_${cpus}cpu" || echo "armv8_gem5_v1_${cpus}cpu").dtb' \
|
--dtb-file='${gem5_dir}/system/arm/dt/$([ "$arch" = arm ] && echo "armv7_gem5_v1_${cpus}cpu" || echo "armv8_gem5_v1_${cpus}cpu").dtb' \
|
||||||
--machine-type=VExpress_GEM5_V1 \
|
--machine-type=VExpress_GEM5_V1 \
|
||||||
$extra_flags \
|
${extra_flags} \
|
||||||
"
|
"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
@@ -125,7 +151,7 @@ else
|
|||||||
qemu_common="\
|
qemu_common="\
|
||||||
${debug_vm} \
|
${debug_vm} \
|
||||||
'${out_dir}/host/usr/bin/qemu-system-${arch}' \
|
'${out_dir}/host/usr/bin/qemu-system-${arch}' \
|
||||||
-m 128M \
|
-m ${memory} \
|
||||||
-monitor telnet::45454,server,nowait \
|
-monitor telnet::45454,server,nowait \
|
||||||
-netdev user,hostfwd=tcp::45455-:45455,id=net0 \
|
-netdev user,hostfwd=tcp::45455-:45455,id=net0 \
|
||||||
-smp $cpus \
|
-smp $cpus \
|
||||||
@@ -139,15 +165,17 @@ ${debug_vm} \
|
|||||||
case "$arch" in
|
case "$arch" in
|
||||||
x86_64)
|
x86_64)
|
||||||
if "$kgdb"; then
|
if "$kgdb"; then
|
||||||
extra_append="$extra_append kgdboc=ttyS0,115200"
|
extra_append="${extra_append} kgdboc=ttyS0,115200"
|
||||||
fi
|
fi
|
||||||
if ! "$initrd"; then
|
if "$ramfs"; then
|
||||||
|
root='root=/dev/anything'
|
||||||
|
else
|
||||||
root='root=/dev/vda'
|
root='root=/dev/vda'
|
||||||
extra_flags="$extra_flags -drive file='${images_dir}/rootfs.ext2.qcow2,if=virtio,format=qcow2'"
|
extra_flags="${extra_flags} -drive file='${images_dir}/rootfs.ext2.qcow2,if=virtio,format=qcow2'"
|
||||||
fi
|
fi
|
||||||
cmd="$qemu_common \
|
cmd="${qemu_common} \
|
||||||
-M pc \
|
-M pc \
|
||||||
-append '$root nopat $extra_append' \
|
-append '${root} nopat ${extra_append}' \
|
||||||
-device edu \
|
-device edu \
|
||||||
-device lkmc_pci_min \
|
-device lkmc_pci_min \
|
||||||
-device virtio-net-pci,netdev=net0 \
|
-device virtio-net-pci,netdev=net0 \
|
||||||
@@ -157,15 +185,17 @@ ${extra_flags} \
|
|||||||
;;
|
;;
|
||||||
arm)
|
arm)
|
||||||
if "$kgdb"; then
|
if "$kgdb"; then
|
||||||
extra_append="$extra_append kgdboc=ttyAMA0,115200"
|
extra_append="${extra_append} kgdboc=ttyAMA0,115200"
|
||||||
fi
|
fi
|
||||||
if ! "$initrd"; then
|
if "$ramfs"; then
|
||||||
|
root='root=/dev/anything'
|
||||||
|
else
|
||||||
|
extra_flags="${extra_flags} -drive file='${images_dir}/rootfs.ext2.qcow2,if=scsi,format=qcow2'"
|
||||||
root='root=/dev/sda'
|
root='root=/dev/sda'
|
||||||
extra_flags="$extra_flags -drive file='${images_dir}/rootfs.ext2.qcow2,if=scsi,format=qcow2'"
|
|
||||||
fi
|
fi
|
||||||
cmd="$qemu_common \
|
cmd="$qemu_common \
|
||||||
-M versatilepb \
|
-M versatilepb \
|
||||||
-append '$root $extra_append' \
|
-append '${root} ${extra_append}' \
|
||||||
-device rtl8139,netdev=net0 \
|
-device rtl8139,netdev=net0 \
|
||||||
-dtb '${images_dir}/versatile-pb.dtb' \
|
-dtb '${images_dir}/versatile-pb.dtb' \
|
||||||
-kernel '${images_dir}/zImage' \
|
-kernel '${images_dir}/zImage' \
|
||||||
@@ -177,9 +207,15 @@ $extra_flags \
|
|||||||
if "$kgdb"; then
|
if "$kgdb"; then
|
||||||
extra_append="${extra_append} kgdboc=ttyAMA0,115200"
|
extra_append="${extra_append} kgdboc=ttyAMA0,115200"
|
||||||
fi
|
fi
|
||||||
|
if "$ramfs"; then
|
||||||
|
root='root=/dev/anything'
|
||||||
|
else
|
||||||
|
root='root=/dev/vda'
|
||||||
|
extra_flags="${extra_flags} -drive file='${images_dir}/rootfs.ext2.qcow2,if=virtio,format=qcow2'"
|
||||||
|
fi
|
||||||
cmd="${qemu_common} \
|
cmd="${qemu_common} \
|
||||||
-M virt \
|
-M virt \
|
||||||
-append 'root=/dev/sda ${extra_append}' \
|
-append '${root} ${extra_append}' \
|
||||||
-cpu cortex-a57 \
|
-cpu cortex-a57 \
|
||||||
-device virtio-net-device,netdev=net0 \
|
-device virtio-net-device,netdev=net0 \
|
||||||
-kernel '${images_dir}/Image' \
|
-kernel '${images_dir}/Image' \
|
||||||
@@ -189,13 +225,15 @@ ${extra_flags} \
|
|||||||
"
|
"
|
||||||
;;
|
;;
|
||||||
mips64)
|
mips64)
|
||||||
if ! "$initrd"; then
|
if "$ramfs"; then
|
||||||
|
root='root=/dev/anything'
|
||||||
|
else
|
||||||
root='root=/dev/hda'
|
root='root=/dev/hda'
|
||||||
extra_flags="${extra_flags} -drive file='${images_dir}/rootfs.ext2.qcow2,format=qcow2'"
|
extra_flags="${extra_flags} -drive file='${images_dir}/rootfs.ext2.qcow2,format=qcow2'"
|
||||||
fi
|
fi
|
||||||
cmd="$qemu_common \
|
cmd="${qemu_common} \
|
||||||
-M malta \
|
-M malta \
|
||||||
-append 'root=/dev/hda ${extra_append}' \
|
-append '${root} ${extra_append}' \
|
||||||
-cpu I6400 \
|
-cpu I6400 \
|
||||||
-device pcnet \
|
-device pcnet \
|
||||||
-kernel '${images_dir}/vmlinux' \
|
-kernel '${images_dir}/vmlinux' \
|
||||||
|
|||||||
Reference in New Issue
Block a user