From 3697845a267bf08be08e9d4808d5830bbf8f21f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Sat, 19 Oct 2019 00:00:00 +0000 Subject: [PATCH] 9afe5355e90bbb6b6c636f871b6eb461a957b0ea --- index.html | 1088 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 914 insertions(+), 174 deletions(-) diff --git a/index.html b/index.html index 02a4511..cb6de90 100644 --- a/index.html +++ b/index.html @@ -741,7 +741,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • 13.4. X11 Buildroot @@ -1053,19 +1053,21 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b @@ -1189,7 +1191,22 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • 19.18. gem5 ARM platforms
  • 19.19. gem5 internals
  • @@ -1736,118 +1753,119 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • 29.5. Benchmark this repo bibliography
  • -
  • 30. About this repo +
  • 30. Xephyr
  • +
  • 31. About this repo
  • @@ -1864,14 +1882,14 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b

    If you don’t know which one to go for, start with QEMU Buildroot setup getting started.

    -

    Design goals of this project are documented at: Section 30.18.1, “Design goals”.

    +

    Design goals of this project are documented at: Section 31.18.1, “Design goals”.

    1.1. QEMU Buildroot setup

    1.1.1. QEMU Buildroot setup getting started

    -

    This setup has been mostly tested on Ubuntu. For other host operating systems see: Section 30.1, “Supported hosts”. For greater stability, consider using the latest release instead of master: https://github.com/cirosantilli/linux-kernel-module-cheat/releases

    +

    This setup has been mostly tested on Ubuntu. For other host operating systems see: Section 31.1, “Supported hosts”. For greater stability, consider using the latest release instead of master: https://github.com/cirosantilli/linux-kernel-module-cheat/releases

    Reserve 12Gb of disk and run:

    @@ -1888,7 +1906,7 @@ cd linux-kernel-module-cheat

    You don’t need to clone recursively even though we have .git submodules: download-dependencies fetches just the submodules that you need for this build to save time.

    The initial build will take a while (30 minutes to 2 hours) to clone and build, see Benchmark builds for more details.

    @@ -1971,7 +1989,7 @@ hello2 cleanup
    -

    To avoid typing --arch aarch64 many times, you can set the default arch as explained at: Section 30.4, “Default command line arguments”

    +

    To avoid typing --arch aarch64 many times, you can set the default arch as explained at: Section 31.4, “Default command line arguments”

    I now urge you to read the following sections which contain widely applicable information:

    @@ -2275,7 +2293,7 @@ hello /root/.profile

    If you really want to develop semiconductors, your only choice is to join an university or a semiconductor company that has the EDA licenses.

    While hacking QEMU, you will likely want to GDB step its source. That is trivial since QEMU is just another userland program like any other, but our setup has a shortcut to make it even more convenient, see: Section 18.7, “Debug the emulator”.

    @@ -2714,7 +2732,7 @@ j = 0

    This repository has been tested inside clean Docker containers.

    -

    This is a good option if you are on a Linux host, but the native setup failed due to your weird host distribution, and you have better things to do with your life than to debug it. See also: Section 30.1, “Supported hosts”.

    +

    This is a good option if you are on a Linux host, but the native setup failed due to your weird host distribution, and you have better things to do with your life than to debug it. See also: Section 31.1, “Supported hosts”.

    For example, to do a QEMU Buildroot setup inside Docker, run:

    @@ -3792,7 +3810,7 @@ xdg-open README.html
    -

    More information about our documentation internals can be found at: Section 30.5, “Documentation”

    +

    More information about our documentation internals can be found at: Section 31.5, “Documentation”

    @@ -7163,7 +7181,7 @@ qw er

    The gem5 tests require building statically with build id static, see also: Section 10.6, “gem5 syscall emulation mode”. TODO automate this better.

    -

    See: Section 30.13, “Test this repo” for more useful testing tips.

    +

    See: Section 31.13, “Test this repo” for more useful testing tips.

    @@ -7844,7 +7862,7 @@ hello
    -

    13.3.3. Graphic mode gem5 internals

    +

    13.3.3. gem5 graphic mode internals

    We cannot use mainline Linux because the gem5 arm Linux kernel patches are required at least to provide the CONFIG_DRM_VIRT_ENCODER option.

    @@ -8751,7 +8769,7 @@ xeyes

    14.1. Enable networking

    -

    We disable networking by default because it starts an userland process, and we want to keep the number of userland processes to a minimum to make the system more understandable as explained at: Section 30.18.3, “Resource tradeoff guidelines”

    +

    We disable networking by default because it starts an userland process, and we want to keep the number of userland processes to a minimum to make the system more understandable as explained at: Section 31.18.3, “Resource tradeoff guidelines”

    To enable networking on Buildroot, simply run:

    @@ -9041,6 +9059,9 @@ uname -a > guest mount -t 9p -o trans=virtio,version=9p2000.L host0 /mnt/my9p
    +
    +

    where mount tag host0 is set by the emulator (mount_tag flag on QEMU CLI), and can be found in the guest with: cat /sys/bus/virtio/drivers/9pnet_virtio/virtio0/mount_tag as documented at: https://www.kernel.org/doc/Documentation/filesystems/9p.txt.

    +
  • Launch QEMU with -virtfs as in your run script

    @@ -9087,6 +9108,15 @@ mount -t 9p -o trans=virtio,version=9p2000.L host0 /mnt/my9p
  • +
    +

    From the source, there is just one exported tag named gem5, so we could try on the guest:

    +
    +
    +
    +
    mkdir -p /mnt/9p/gem5
    +mount -t 9p -o trans=virtio,version=9p2000.L gem5 /mnt/9p/data
    +
    +

    14.4.4. NFS

    @@ -9575,15 +9605,15 @@ git log | grep -E ' Linux [0-9]+\.' | head

    This also makes this repo the perfect setup to develop the Linux kernel.

    -

    In case something breaks while updating the Linux kernel, you can try to bisect it to understand the root cause, see: Section 30.14, “Bisection”.

    +

    In case something breaks while updating the Linux kernel, you can try to bisect it to understand the root cause, see: Section 31.14, “Bisection”.

    15.2.2.1. Update the Linux kernel LKMC procedure
    -

    First, use use the branching procedure described at: Section 30.16, “Update a forked submodule”

    +

    First, use use the branching procedure described at: Section 31.16, “Update a forked submodule”

    -

    Because the kernel is so central to this repository, almost all tests must be re-run, so basically just follow the full testing procedure described at: Section 30.13, “Test this repo”. The only tests that can be skipped are essentially the Baremetal tests.

    +

    Because the kernel is so central to this repository, almost all tests must be re-run, so basically just follow the full testing procedure described at: Section 31.13, “Test this repo”. The only tests that can be skipped are essentially the Baremetal tests.

    Before comitting, don’t forget to update:

    @@ -16746,11 +16776,30 @@ IN:

    PANDA can list memory addresses, so I bet it can also decode the instructions: https://github.com/panda-re/panda/blob/883c85fa35f35e84a323ed3d464ff40030f06bd6/panda/docs/LINE_Censorship.md I wonder why they don’t just upstream those things to QEMU’s tracing: https://github.com/panda-re/panda/issues/290

    -

    gem5 can do it as shown at: Section 18.8.6, “gem5 tracing”.

    +

    gem5 can do it as shown at: Section 18.8.7, “gem5 tracing”.

    -

    18.8.3. Trace source lines

    +

    18.8.3. QEMU trace memory accesses

    +
    +

    Not possible apparently, not even with the memory_region_ops_read and memory_region_ops_write trace events, Peter comments https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg07482.html

    +
    +
    +
    +
    +

    No. You will miss all the fast-path memory accesses, which are +done with custom generated assembly in the TCG backend. In +general QEMU is not designed to support this kind of monitoring +of guest operations.

    +
    +
    +
    + +
    +
    +

    18.8.4. Trace source lines

    We can further use Binutils' addr2line to get the line that corresponds to each address:

    @@ -16806,7 +16855,7 @@ less "$(./getvar --arch x86_64 run_dir)/trace-lines.txt"
    -

    18.8.4. QEMU record and replay

    +

    18.8.5. QEMU record and replay

    QEMU runs, unlike gem5, are not deterministic by default, however it does support a record and replay mechanism that allows you to replay a previous run deterministically.

    @@ -16913,7 +16962,7 @@ less "$(./getvar --arch x86_64 run_dir)/trace-lines.txt"

    Solved on unmerged c42634d8e3428cfa60672c3ba89cabefc720cde9 from https://github.com/ispras/qemu/tree/rr-180725

    -
    18.8.4.1. QEMU reverse debugging
    +
    18.8.5.1. QEMU reverse debugging

    TODO get working.

    @@ -16952,7 +17001,7 @@ reverse-continue
    -

    18.8.5. QEMU trace multicore

    +

    18.8.6. QEMU trace multicore

    TODO: is there any way to distinguish which instruction runs on each core? Doing:

    @@ -16967,7 +17016,7 @@ reverse-continue
    -

    18.8.6. gem5 tracing

    +

    18.8.7. gem5 tracing

    gem5 provides also provides a tracing mechanism documented at: http://www.gem5.org/Trace_Based_Debugging:

    @@ -16978,6 +17027,9 @@ less "$(./getvar --arch aarch64 run_dir)/trace.txt"
    +

    Our wrapper just forwards the options to the --debug-flags gem5 option.

    +
    +

    Keep in mind however that the disassembly is very broken in several places as of 2019q2, so you can’t always trust it.

    @@ -17008,6 +17060,9 @@ less "$(./getvar --arch aarch64 run_dir)/trace.txt"
    +

    Be warned, the trace is humongous, at 16Gb.

    +
    +

    This would produce a lot of output however, so you will likely not want that when tracing a Linux kernel boot instructions. But it can be very convenient for smaller traces such as Baremetal.

    @@ -17047,15 +17102,12 @@ less "$(./getvar gem5_source_dir)/src/cpu/exetrace.cc"
    -

    The traces are generated from DPRINTF(<trace-id> calls scattered throughout the code.

    +

    Trace internals are discussed at: gem5 trace internals.

    As can be seen on the Sconstruct, Exec is just an alias that enables a set of flags.

    -

    Be warned, the trace is humongous, at 16Gb.

    -
    -

    We can make the trace smaller by naming the trace file as trace.txt.gz, which enables GZIP compression, but that is not currently exposed on our scripts, since you usually just need something human readable to work on.

    @@ -17075,7 +17127,44 @@ less "$(./getvar --arch 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?

    -
    18.8.6.1. gem5 ExecAll trace format
    +
    18.8.7.1. gem5 trace internals
    +
    +

    gem5 traces are generated from DPRINTF(<trace-id> calls scattered throughout the code, except for ExecAll instruction traces, which uses Debug::ExecEnable directly..

    +
    +
    +

    The trace IDs are themselves encoded in SConscript files, e.g.:

    +
    +
    +
    +
    DebugFlag('Event'
    +
    +
    +
    +

    in src/cpu/SConscript.

    +
    +
    +

    The build system then automatically adds the options to the --debug-flags.

    +
    +
    +

    For this entry, the build system then generates a file build/ARM/debug/ExecEnable.hh, which contains:

    +
    +
    +
    +
    namespace Debug {
    +class SimpleFlag;
    +extern SimpleFlag ExecEnable;
    +}
    +
    +
    +
    +

    and must be included in from callers of DPRINTF( as <debug/ExecEnable.hh>.

    +
    +
    +

    Tested in b4879ae5b0b6644e6836b0881e4da05c64a6550d.

    +
    +
    +
    +
    18.8.7.2. gem5 ExecAll trace format

    This debug flag traces all instructions.

    @@ -17158,7 +17247,7 @@ less "$(./getvar --arch aarch64 run_dir)/trace-lines.txt"
    -
    18.8.6.2. gem5 Registers trace format
    +
    18.8.7.3. gem5 Registers trace format

    This flag shows a more detailed register usage than gem5 ExecAll trace format.

    @@ -17213,13 +17302,13 @@ add x1, x0, 2
    -
    18.8.6.3. gem5 TARMAC traces
    +
    18.8.7.4. gem5 TARMAC traces
    -
    18.8.6.4. gem5 tracing internals
    +
    18.8.7.5. gem5 tracing internals

    As of gem5 16eeee5356585441a49d05c78abc328ef09f7ace the default tracer is ExeTracer. It is set at:

    @@ -17395,6 +17484,9 @@ root
  • gem5 ARM at least appears to implement more low level CPU functionality than QEMU, e.g. QEMU only added EL2 in 2018: https://stackoverflow.com/questions/42824706/qemu-system-aarch64-entering-el1-when-emulating-a53-power-up See also: Section 27.8.1, “ARM exception levels”

  • +
  • +

    gem5 offers more advanced logging, even for non micro architectural things which QEMU models in some way, e.g. QEMU trace memory accesses, because QEMU’s binary translation optimizations reduce visibility

    +
  • @@ -20305,8 +20397,62 @@ Indirect leak of 1346 byte(s) in 2 object(s) allocated from:

    19.19. gem5 internals

    +
    +

    Internals under other sections:

    +
    +
    -

    19.19.1. gem5 Python C++ interaction

    +

    19.19.1. gem5 Eclipse configuration

    +
    +

    In order to develop complex C++ software such as gem5, a good IDE setup is fundamental.

    +
    +
    +

    The best setup I’ve reached is with Eclipse. It is not perfect, and there is a learning curve, but is worth it.

    +
    +
    +

    I recommend the following settings, tested in Eclipse 2019.09, Ubuntu 18.04:

    +
    +
    + +
    +
    +

    To run and GDB step debug the executable, just copy the full command line from the output ./run, and configure it into Eclipse.

    +
    +
    +
    +

    19.19.2. gem5 Python C++ interaction

    The interaction uses the Python C extension interface https://docs.python.org/2/extending/extending.html interface through the pybind11 helper library: https://github.com/pybind/pybind11

    @@ -20471,6 +20617,532 @@ static EmbeddedPyBind embed_obj("BadDevice", module_init, "BasicPioDevice");Tested on gem5 08c79a194d1a3430801c04f37d13216cc9ec1da3.

    +
    +

    19.19.3. gem5 entry point

    +
    +

    The main is at: src/sim/main.cc. It calls:

    +
    +
    +
    +
    ret = initM5Python();
    +
    +
    +
    +

    src/sim/init.cc:

    +
    +
    +
    +
    230 int
    +231 initM5Python()
    +232 {
    +233     EmbeddedPyBind::initAll();
    +234     return EmbeddedPython::initAll();
    +235 }
    +
    +
    +
    +

    initAll basically just initializes the _m5 Python object, which is used across multiple .py.

    +
    +
    +

    Back on main:

    +
    +
    +
    +
    ret = m5Main(argc, argv);
    +
    +
    +
    +

    which goes to:

    +
    +
    +
    +
    result = PyRun_String(*command, Py_file_input, dict, dict);
    +
    +
    +
    +

    with commands looping over:

    +
    +
    +
    +
    import m5
    +m5.main()
    +
    +
    +
    +

    which leads into:

    +
    +
    +
    +
    src/python/m5/main.py#main
    +
    +
    +
    +

    which finally calls your config file like fs.py with:

    +
    +
    +
    +
    filename = sys.argv[0]
    +filedata = file(filename, 'r').read()
    +filecode = compile(filedata, filename, 'exec')
    +[...]
    +exec filecode in scope
    +
    +
    +
    +

    TODO: the file path name appears to be passed as a command line argument to the Python script, but I didn’t have the patience to fully understand the details.

    +
    +
    +

    Tested at gem5 b4879ae5b0b6644e6836b0881e4da05c64a6550d.

    +
    +
    +
    +

    19.19.4. gem5 event queue

    +
    +

    gem5 is an event based simulator, and as such the event queue is of of the crucial elements in the system.

    +
    +
    +

    The gem5 event queue stores one callback event for each future point in time.

    +
    +
    +

    The event queue is implemented in the class EventQueue in the file src/sim/eventq.hh.

    +
    +
    +

    Not all times need to have an associated event: if a given time has no events, gem5 just skips it and jumps to the next event: the queue is basically a linked list of events.

    +
    +
    +

    Important examples of events include:

    +
    +
    +
      +
    • +

      CPU ticks

      +
    • +
    • +

      TODO peripherals and memory

      +
    • +
    +
    +
    +

    At the beginning of simulation, gem5 sets up exactly two events:

    +
    +
    + +
    +
    +

    Tick events then get triggered one by one as simulation progresses, in addition to any other system events.

    +
    +
    +

    The EventQueue class has one awesome dump() function that prints a human friendly representation of the queue, and can be easily called from GDB. TODO example.

    +
    +
    +

    We can also observe what is going on in the event queue with the Event debug flag.

    +
    +
    +

    Event execution is done at EventQueue::serviceOne():

    +
    +
    +
    +
    Event *exit_event = eventq->serviceOne();
    +
    +
    +
    +

    This calls the Event::process method of the event.

    +
    +
    +
    19.19.4.1. gem5 event queue AtomicSimpleCPU syscall emulation freestanding example analysis
    +
    +

    Let’s now analyze every single event on a minimal gem5 syscall emulation mode in the simplest CPU that we have:

    +
    +
    +
    +
    ./run \
    +  --arch aarch64 \
    +  --emulator gem5 \
    +  --userland userland/arch/aarch64/freestanding/linux/hello.S \
    +  --trace Event \
    +  --trace-stdout \
    +;
    +
    +
    +
    +

    At LKMC a0ea29835b9bacc6aa1cceb24c79d895315991d4 + 1 this outputs:

    +
    +
    +
    +
          0: AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event scheduled @ 0
    +**** REAL SIMULATION ****
    +      0: Event_70: generic event scheduled @ 0
    +info: Entering event queue @ 0.  Starting simulation...
    +      0: Event_70: generic event rescheduled @ 18446744073709551615
    +      0: AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event rescheduled @ 500
    +    500: AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event rescheduled @ 1000
    +   1000: AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event rescheduled @ 1500
    +   1500: AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event rescheduled @ 2000
    +hello
    +   2000: AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event rescheduled @ 2500
    +   2500: AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event rescheduled @ 3000
    +   3000: AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event rescheduled @ 3500
    +   3500: Event_71: generic event scheduled @ 3500
    +
    +
    +
    +

    which we immediately guess means that there is one event per tick when comparing to the ExecAll trace:

    +
    +
    +
    +
          0: system.cpu A0 T0 : @asm_main_after_prologue    :   movz   x0, #1, #0        : IntAlu :  D=0x0000000000000001  flags=(IsInteger)
    +    500: system.cpu A0 T0 : @asm_main_after_prologue+4    :   adr   x1, #28            : IntAlu :  D=0x0000000000400098  flags=(IsInteger)
    +   1000: system.cpu A0 T0 : @asm_main_after_prologue+8    :   ldr   w2, #4194464       : MemRead :  D=0x0000000000000006 A=0x4000a0  flags=(IsInteger|IsMemRef|IsLoad)
    +   1500: system.cpu A0 T0 : @asm_main_after_prologue+12    :   movz   x8, #64, #0       : IntAlu :  D=0x0000000000000040  flags=(IsInteger)
    +   2000: system.cpu A0 T0 : @asm_main_after_prologue+16    :   svc   #0x0               : IntAlu :   flags=(IsSerializeAfter|IsNonSpeculative|IsSyscall)
    +hello
    +   2500: system.cpu A0 T0 : @asm_main_after_prologue+20    :   movz   x0, #0, #0        : IntAlu :  D=0x0000000000000000  flags=(IsInteger)
    +   3000: system.cpu A0 T0 : @asm_main_after_prologue+24    :   movz   x8, #93, #0       : IntAlu :  D=0x000000000000005d  flags=(IsInteger)
    +   3500: system.cpu A0 T0 : @asm_main_after_prologue+28    :   svc   #0x0               : IntAlu :   flags=(IsSerializeAfter|IsNonSpeculative|IsSyscall)
    +Exiting @ tick 3500 because exiting with last active thread context
    +
    +
    +
    +

    On the event trace, we can see:

    +
    +
    +
      +
    • +

      AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event scheduled @ 0 schedules a tick event for time 0, and this leads to the first clock tick

      +
    • +
    • +

      0: Event_70: generic event scheduled @ 0: schedules the end of time event for time 0, which is later rescheduled to the actual end of time: 0: Event_70: generic event rescheduled @ 18446744073709551615

      +
    • +
    • +

      at 0: AtomicSimpleCPU tick.wrapped_function_event: EventFunctionWrapped event rescheduled @ 500 the first clock tick must have finished running, and so to represent the next one, it was simply rescheduled for the next time 500! This is done at the end of AtomicSimpleCPU::tick():

      +
      +
      +
      if (_status != Idle)
      +    reschedule(tickEvent, curTick() + latency, true);
      +
      +
      +
    • +
    • +

      at 3500: Event_71: generic event scheduled @ 3500 the exit system call is called and the simulation ends.

      +
      +

      A new event is scheduled for the current time itself. TODO what is this event?

      +
      +
    • +
    +
    +
    +

    Let’s study the first event. From GDB, it’s stack trace is:

    +
    +
    +
    +
    Trace::OstreamLogger::logMessage() at trace.cc:149 0x5555593b3b1e
    +void Trace::Logger::dprintf_flag<char const*, char const*, unsigned long>() at 0x55555949e603
    +void Trace::Logger::dprintf<char const*, char const*, unsigned long>() at 0x55555949de58
    +Event::trace() at eventq.cc:395 0x55555946d109
    +EventQueue::schedule() at eventq_impl.hh:65 0x555557195441
    +EventManager::schedule() at eventq.hh:746 0x555557194aa2
    +AtomicSimpleCPU::activateContext() at atomic.cc:239 0x555559075531
    +SimpleThread::activate() at simple_thread.cc:177 0x555559545a63
    +Process::initState() at process.cc:283 0x555559484011
    +ArmProcess64::initState() at process.cc:126 0x55555730827a
    +ArmLinuxProcess64::initState() at process.cc:1,777 0x5555572d5e5e
    +
    +
    +
    +

    The interesting call is at AtomicSimpleCPU::activateContext:

    +
    +
    +
    +
    schedule(tickEvent, clockEdge(Cycles(0)));
    +
    +
    +
    +

    which calls EventManager::schedule.

    +
    +
    +

    AtomicSimpleCPU is an EventManager because SimObject inherits from it.

    +
    +
    +

    tickEvent is an EventFunctionWrapper which contains a std::function<void(void)> callback;, and is initialized in the constructor as:

    +
    +
    +
    +
    tickEvent([this]{ tick(); }, "AtomicSimpleCPU tick",
    +        false, Event::CPU_Tick_Pri),
    +
    +
    +
    +

    So that’s how the main atomic tick loop works, fully understood!

    +
    +
    +

    The second event has backtrace:

    +
    +
    +
    +
    Trace::OstreamLogger::logMessage() at trace.cc:149 0x5555593b3b1e
    +void Trace::Logger::dprintf_flag<char const*, char const*, unsigned long>() at 0x55555949e603
    +void Trace::Logger::dprintf<char const*, char const*, unsigned long>() at 0x55555949de58
    +Event::trace() at eventq.cc:395 0x55555946d109
    +EventQueue::schedule() at eventq_impl.hh:65 0x555557195441
    +BaseGlobalEvent::schedule() at global_event.cc:78 0x55555946d6f1
    +GlobalEvent::GlobalEvent() at 0x55555949d177
    +GlobalSimLoopExitEvent::GlobalSimLoopExitEvent() at sim_events.cc:61 0x555559474470
    +simulate() at simulate.cc:104 0x555559476d6f
    +
    +
    +
    +

    so gets scheduled automatically at object creation simulate() through the GlobalEvent() constructor:

    +
    +
    +
    +
    simulate_limit_event =
    +    new GlobalSimLoopExitEvent(mainEventQueue[0]->getCurTick(),
    +                                "simulate() limit reached", 0);
    +
    +
    +
    +

    This event indicates that the simulation should finish by overriding bool isExitEvent() which gets checked in the main simulation at EventQueue::serviceOne:

    +
    +
    +
    +
    if (event->isExitEvent()) {
    +    assert(!event->flags.isSet(Event::Managed) ||
    +            !event->flags.isSet(Event::IsMainQueue)); // would be silly
    +    return event;
    +
    +
    +
    +

    And at long, we can guess without reading the code that Event_71 is comes from the SE implementation of the exit syscall, so let’s just confirm, the trace contains:

    +
    +
    +
    +
    exitSimLoop() at sim_events.cc:97 0x5555594746e0
    +exitImpl() at syscall_emul.cc:215 0x55555948c046
    +exitFunc() at syscall_emul.cc:225 0x55555948c147
    +SyscallDesc::doSyscall() at syscall_desc.cc:72 0x5555594949b6
    +Process::syscall() at process.cc:401 0x555559484717
    +SimpleThread::syscall() at 0x555559558059
    +ArmISA::SupervisorCall::invoke() at faults.cc:856 0x5555572950d7
    +BaseSimpleCPU::advancePC() at base.cc:681 0x555559083133
    +AtomicSimpleCPU::tick() at atomic.cc:757 0x55555907834c
    +
    +
    +
    +

    and exitSimLoop() does:

    +
    +
    +
    +
    new GlobalSimLoopExitEvent(when + simQuantum, message, exit_code, repeat);
    +
    +
    +
    +

    Tested at b4879ae5b0b6644e6836b0881e4da05c64a6550d.

    +
    +
    +
    +
    19.19.4.2. gem5 event queue MinorCPU syscall emulation freestanding example analysis
    +
    +

    The events for the Atomic CPU were pretty simple: basically just ticks.

    +
    +
    +

    But as we venture into more complex CPU models such as MinorCPU, the events get much more complex and interesting.

    +
    +
    +

    TODO: analyze the trace for:

    +
    +
    +
    +
    ./run \
    +  --arch aarch64 \
    +  --emulator gem5 \
    +  --userland userland/arch/aarch64/freestanding/linux/hello.S \
    +  --trace Event \
    +  --trace-stdout \
    +  -- \
    +  --cpu-type MinorCPU \
    +  --caches \
    +;
    +
    +
    +
    +
    +
    +

    19.19.5. gem5 stats internals

    +
    +

    This describes the internals of the gem5 m5out/stats.txt file.

    +
    +
    +

    GDB call stack to dumpstats:

    +
    +
    +
    +
    Stats::pythonDump () at build/ARM/python/pybind11/stats.cc:58
    +Stats::StatEvent::process() ()
    +GlobalEvent::BarrierEvent::process (this=0x555559fa6a80) at build/ARM/sim/global_event.cc:131
    +EventQueue::serviceOne (this=this@entry=0x555558c36080) at build/ARM/sim/eventq.cc:228
    +doSimLoop (eventq=0x555558c36080) at build/ARM/sim/simulate.cc:219
    +simulate (num_cycles=<optimized out>) at build/ARM/sim/simulate.cc:132
    +
    +
    +
    +

    Stats::pythonDump does:

    +
    +
    +
    +
    void
    +pythonDump()
    +{
    +    py::module m = py::module::import("m5.stats");
    +    m.attr("dump")();
    +}
    +
    +
    +
    +

    This calls src/python/m5/stats/init.py in def dump does the main dumping

    +
    +
    +

    That function does notably:

    +
    +
    +
    +
        for output in outputList:
    +        if output.valid():
    +            output.begin()
    +            for stat in stats_list:
    +                stat.visit(output)
    +            output.end()
    +
    +
    +
    +

    begin and end are defined in C++ and output the header and tail respectively

    +
    +
    +
    +
    void
    +Text::begin()
    +{
    +    ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
    +}
    +
    +void
    +Text::end()
    +{
    +    ccprintf(*stream, "\n---------- End Simulation Statistics   ----------\n");
    +    stream->flush();
    +}
    +
    +
    +
    +

    stats_list contains the stats, and stat.visit prints them, outputList contains by default just the text output. I don’t see any other types of output in gem5, but likely JSON / binary formats could be envisioned.

    +
    +
    +

    Tested in gem5 b4879ae5b0b6644e6836b0881e4da05c64a6550d.

    +
    +
    +
    +

    19.19.6. gem5 build system

    +
    +
    19.19.6.1. gem5 polymorphic ISA includes
    +
    +

    E.g. src/cpu/decode_cache.hh includes:

    +
    +
    +
    +
    #include "arch/isa_traits.hh"
    +
    +
    +
    +

    which in turn is meant to refer to files of form:

    +
    +
    +
    +
    src/arch/<isa>/isa_traits.hh
    +
    +
    +
    +

    What happens is that the build system creates a file:

    +
    +
    +
    +
    build/ARM/arch/isa_traits.hh
    +
    +
    +
    +

    which contains just:

    +
    +
    +
    +
    #include "arch/arm/isa_traits.hh"
    +
    +
    +
    +

    and puts that in the -I include path during build.

    +
    +
    +

    It appears to be possible to deal with it using preprocessor macros, but it is ugly: https://stackoverflow.com/questions/3178946/using-define-to-include-another-file-in-c-c/3179218#3179218

    +
    +
    +

    In addition to the header polymorphism, gem5 also namespaces classes with TheISA::, e.g. in src/cpu/decode_cache.hh:

    +
    +
    +
    +
    Value items[TheISA::PageBytes];
    +
    +
    +
    +

    which is defined at:

    +
    +
    +

    …​ +build/ARM/config/the_isa.hh +…​

    +
    +
    +

    as:

    +
    +
    +
    +
    #define TheISA ArmISA
    +
    +
    +
    +

    and forces already arm/ specific headers to define their symbols under:

    +
    +
    +
    +
    namespace ArmISA
    +
    +
    +
    +

    so I don’t see the point of this pattern, why not just us PageBytes directly? Looks like a documentation mechanism to indicate that a certain symbol is ISA specific.

    +
    +
    +

    Tested in gem5 2a242c5f59a54bc6b8953f82486f7e6fe0aa9b3d.

    +
    +
    +
    +
    19.19.6.2. Why are all C++ symlinked into the gem5 build dir?
    +
    +

    Some scons madness.

    +
    + +
    +

    Then the a5bc2291391b0497fdc60fdc960e07bcecebfb8f SConstruct use symlinks in a futile attempt to make things better for editors or build systems from the past century.

    +
    +
    +

    It was not possible to disable the symlinks automatically for the entire project when I last asked: https://stackoverflow.com/questions/53656787/how-to-set-disable-duplicate-0-for-all-scons-build-variants-without-repeating-th

    +
    +
    +
    @@ -20574,7 +21246,7 @@ qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -smp 1 -kernel output/ima

    The clean is necessary because the source files didn’t change, so make would just check the timestamps and not build anything.

    -

    You will then likely want to make those more permanent as explained at: Section 30.4, “Default command line arguments”.

    +

    You will then likely want to make those more permanent as explained at: Section 31.4, “Default command line arguments”.

    20.2.1. Enable Buildroot compiler optimizations

    @@ -20749,7 +21421,7 @@ make menuconfig

    If none of those methods are flexible enough for you, you can just fork or hack up buildroot_packages/sample_package the sample package to do what you want.

    -

    For how to use that package, see: Section 30.12.2, “buildroot_packages directory”.

    +

    For how to use that package, see: Section 31.12.2, “buildroot_packages directory”.

    Then iterate trying to do what you want and reading the manual until it works: https://buildroot.org/downloads/manual/manual.html

    @@ -20934,7 +21606,7 @@ git -C "$(./getvar qemu_source_dir)" checkout -

    Then, you will also want to do a Bisection to pinpoint the exact commit to blame, and CC that developer.

    -

    Finally, give the images you used save upstream developers' time as shown at: Section 30.17.2, “release-zip”.

    +

    Finally, give the images you used save upstream developers' time as shown at: Section 31.17.2, “release-zip”.

    For Buildroot problems, you should wither provide the config you have:

    @@ -21147,6 +21819,9 @@ git -C "$(./getvar qemu_source_dir)" checkout -
  • userland/c/file_write_read.c

  • +
  • +

    userland/linux/open_o_tmpfile.c: https://stackoverflow.com/questions/4508998/what-is-an-anonymous-inode-in-linux/44388030#44388030

    +
  • @@ -21408,6 +22083,29 @@ echo 1 > /proc/sys/vm/overcommit_memory +
  • +

    fstream

    + +
  • +
  • +

    random

    + +
  • @@ -28574,7 +29272,7 @@ ISB

    In baremetal, we detect if tests failed by parsing logs for the Magic failure string.

    -

    See: Section 30.13, “Test this repo” for more useful testing tips.

    +

    See: Section 31.13, “Test this repo” for more useful testing tips.

    @@ -29431,10 +30129,52 @@ tail -n+1 ../linux-kernel-module-cheat-regression/*/gem5-bench-build-*.txt
    -

    30. About this repo

    +

    30. Xephyr

    +
    +
    +

    Xephyr is an RTOS that has POSIX support. I think it works much like our Baremetal setup which uses Newlib and generates individual ELF files that contain both our C program’s code, and the Xephyr libraries.

    +
    +
    +

    TODO get a hello world working, and then consider further integration in this repo, e.g. being able to run all C userland content on it.

    +
    +
    +

    TODO: Cortex-A CPUs are not currently supported, there are some qemu_cortex_m0 boards, but can’t find a QEMU Cortex-A. There is an x86_64 qemu board, but we don’t currently have an x86 baremetal toolchain. For this reason, we won’t touch this further for now.

    +
    +
    +

    However, unlike Newlib, Xephyr must be setting up a simple pre-main runtime to be able to handle threads.

    +
    +
    +

    Failed attempt:

    +
    +
    +
    +
    # https://askubuntu.com/questions/952429/is-there-a-good-ppa-for-cmake-backports
    +wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add -
    +sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic-rc main'
    +sudo apt-get update
    +sudo apt-get install cmake
    +git clone https://github.com/zephyrproject-rtos/zephyr
    +pip3 install --user -U west packaging
    +cd zephyr
    +git checkout v1.14.1
    +west init zephyrproject
    +west update
    +export ZEPHYR_TOOLCHAIN_VARIANT=xtools
    +export XTOOLS_TOOLCHAIN_PATH="$(pwd)/out/crosstool-ng/build/default/install/aarch64/bin/"
    +source zephyr-env.sh
    +west build -b qemu_aarch64 samples/hello_world
    +
    +
    +
    +

    The build system of that project is a bit excessive / wonky. You need an edge CMake not present in Ubuntu 18.04, which I don’t want to install right now, and it uses the weird custom west build tool frontend.

    +
    +
    +
    +
    +

    31. About this repo

    -

    30.1. Supported hosts

    +

    31.1. Supported hosts

    The host requirements depend a lot on which examples you want to run.

    @@ -29483,9 +30223,9 @@ tail -n+1 ../linux-kernel-module-cheat-regression/*/gem5-bench-build-*.txt
    -

    30.2. Common build issues

    +

    31.2. Common build issues

    -

    30.2.1. You must put some 'source' URIs in your sources.list

    +

    31.2.1. You must put some 'source' URIs in your sources.list

    If ./build --download-dependencies fails with:

    @@ -29499,7 +30239,7 @@ tail -n+1 ../linux-kernel-module-cheat-regression/*/gem5-bench-build-*.txt
    -

    30.2.2. Build from downloaded source zip files

    +

    31.2.2. Build from downloaded source zip files

    It does not work if you just download the .zip with the sources for this repository from GitHub because we use Git submodules, you must clone this repo.

    @@ -29509,7 +30249,7 @@ tail -n+1 ../linux-kernel-module-cheat-regression/*/gem5-bench-build-*.txt
    -

    30.3. Run command after boot

    +

    31.3. Run command after boot

    If you just want to run a command after boot ends without thinking much about it, just use the --eval-after option, e.g.:

    @@ -29526,7 +30266,7 @@ tail -n+1 ../linux-kernel-module-cheat-regression/*/gem5-bench-build-*.txt
    -

    30.4. Default command line arguments

    +

    31.4. Default command line arguments

    It gets annoying to retype --arch aarch64 for every single command, or to remember --config setups.

    @@ -29571,12 +30311,12 @@ tail -n+1 ../linux-kernel-module-cheat-regression/*/gem5-bench-build-*.txt
    -

    30.5. Documentation

    +

    31.5. Documentation

    To learn how to build the documentation see: Section 1.8, “Build the documentation”.

    -

    30.5.1. Documentation verification

    +

    31.5.1. Documentation verification

    When running build-doc, we do the following checks:

    @@ -29597,7 +30337,7 @@ tail -n+1 ../linux-kernel-module-cheat-regression/*/gem5-bench-build-*.txt

    The scripts prints what you have to fix and exits with an error status if there are any errors.

    - + @@ -29620,7 +30360,7 @@ tail -n+1 ../linux-kernel-module-cheat-regression/*/gem5-bench-build-*.txt
    -
    30.5.1.2. asciidoctor/extract-header-ids
    +
    31.5.1.2. asciidoctor/extract-header-ids

    Documentation for asciidoctor/extract-header-ids

    @@ -29665,7 +30405,7 @@ explicitly-given
    - +

    The Asciidoctor extension scripts:

    @@ -29693,7 +30433,7 @@ explicitly-given
    -

    30.6.1. GitHub pages

    +

    31.6.1. GitHub pages

    As mentioned before the TOC, we have to push this README to GitHub pages due to: https://github.com/isaacs/github/issues/1610

    @@ -29743,7 +30483,7 @@ explicitly-given
    -

    30.7. Clean the build

    +

    31.7. Clean the build

    You did something crazy, and nothing seems to work anymore?

    @@ -29807,7 +30547,7 @@ ls "$(./getvar buildroot_build_dir)"
    -

    30.8. ccache

    +

    31.8. ccache

    ccache might save you a lot of re-build when you decide to Clean the build or create a new build variant.

    @@ -29876,7 +30616,7 @@ export CCACHE_MAXSIZE="20G"
    -

    30.9. Rebuild Buildroot while running

    +

    31.9. Rebuild Buildroot while running

    It is not possible to rebuild the root filesystem while running QEMU because QEMU holds the file qcow2 file:

    @@ -29887,7 +30627,7 @@ export CCACHE_MAXSIZE="20G"
    -

    30.10. Simultaneous runs

    +

    31.10. Simultaneous runs

    When doing long simulations sweeping across multiple system parameters, it becomes fundamental to do multiple simulations in parallel.

    @@ -29983,7 +30723,7 @@ less "$(./getvar --arch aarch64 --emulator gem5 --run-id 1 termout_file)"
    -

    To run multiple gem5 checkouts, see: Section 30.11.3.1, “gem5 worktree”.

    +

    To run multiple gem5 checkouts, see: Section 31.11.3.1, “gem5 worktree”.

    Implementation note: we create multiple namespaces for two things:

    @@ -30022,7 +30762,7 @@ less "$(./getvar --arch aarch64 --emulator gem5 --run-id 1 termout_file)"
    -

    30.11. Build variants

    +

    31.11. Build variants

    It often happens that you are comparing two versions of the build, a good and a bad one, and trying to figure out why the bad one is bad.

    @@ -30030,7 +30770,7 @@ less "$(./getvar --arch aarch64 --emulator gem5 --run-id 1 termout_file)"

    Our build variants system allows you to keep multiple built versions of all major components, so that you can easily switching between running one or the other.

    -

    30.11.1. Linux kernel build variants

    +

    31.11.1. Linux kernel build variants

    If you want to keep two builds around, one for the latest Linux version, and the other for Linux v4.16:

    @@ -30066,11 +30806,11 @@ git -C "$(./getvar linux_source_dir)" checkout -
    -

    To run both kernels simultaneously, one on each QEMU instance, see: Section 30.10, “Simultaneous runs”.

    +

    To run both kernels simultaneously, one on each QEMU instance, see: Section 31.10, “Simultaneous runs”.

    -

    30.11.2. QEMU build variants

    +

    31.11.2. QEMU build variants

    Analogous to the Linux kernel build variants but with the --qemu-build-id option instead:

    @@ -30086,7 +30826,7 @@ git -C "$(./getvar qemu_source_dir)" checkout -
    -

    30.11.3. gem5 build variants

    +

    31.11.3. gem5 build variants

    Analogous to the Linux kernel build variants but with the --gem5-build-id option instead:

    @@ -30117,7 +30857,7 @@ git -C "$(./getvar gem5_source_dir)" checkout some-branch

    Therefore, you can’t forget to checkout to the sources to that of the corresponding build before running, unless you explicitly tell gem5 to use a non-default source tree with gem5 worktree. This becomes inevitable when you want to launch multiple simultaneous runs at different checkouts.

    -
    30.11.3.1. gem5 worktree
    +
    31.11.3.1. gem5 worktree

    --gem5-build-id goes a long way, but if you want to seamlessly switch between two gem5 tress without checking out multiple times, then --gem5-worktree is for you.

    @@ -30170,7 +30910,7 @@ cd -
    -
    30.11.3.2. gem5 private source trees
    +
    31.11.3.2. gem5 private source trees

    Suppose that you are working on a private fork of gem5, but you want to use this repository to develop it as well.

    @@ -30214,7 +30954,7 @@ gem5_internal="$(pwd)/gem5-internal"
    -

    30.11.4. Buildroot build variants

    +

    31.11.4. Buildroot build variants

    Allows you to have multiple versions of the GCC toolchain or root filesystem.

    @@ -30234,9 +30974,9 @@ git -C "$(./getvar buildroot_source_dir)" checkout -
    -

    30.12. Directory structure

    +

    31.12. Directory structure

    -

    30.12.1. lkmc directory

    +

    31.12.1. lkmc directory

    lkmc/ contains sources and headers that are shared across kernel modules, userland and baremetal examples.

    @@ -30247,7 +30987,7 @@ git -C "$(./getvar buildroot_source_dir)" checkout -

    Another option would have been to name it as includes/lkmc, but that would make paths longer, and we might want to store source code in that directory as well in the future.

    -
    30.12.1.1. Userland objects vs header-only
    +
    31.12.1.1. Userland objects vs header-only

    When factoring out functionality across userland examples, there are two main options:

    @@ -30306,7 +31046,7 @@ git -C "$(./getvar buildroot_source_dir)" checkout -
    -

    30.12.2. buildroot_packages directory

    +

    31.12.2. buildroot_packages directory

    @@ -30355,7 +31095,7 @@ git -C "$(./getvar buildroot_source_dir)" checkout -

    A custom build script can give you more flexibility: e.g. the package can be made work with other root filesystems more easily, have better 9P support, and rebuild faster as it evades some Buildroot boilerplate.

    -
    30.12.2.1. kernel_modules buildroot package
    +
    31.12.2.1. kernel_modules buildroot package
    @@ -30402,9 +31142,9 @@ git -C "$(./getvar buildroot_source_dir)" checkout -
    -

    30.12.3. patches directory

    +

    31.12.3. patches directory

    -
    30.12.3.1. patches/global directory
    +
    31.12.3.1. patches/global directory

    Has the following structure:

    @@ -30421,7 +31161,7 @@ git -C "$(./getvar buildroot_source_dir)" checkout -
    -
    30.12.3.2. patches/manual directory
    +
    31.12.3.2. patches/manual directory

    Patches in this directory are never applied automatically: it is up to users to manually apply them before usage following the instructions in this documentation.

    @@ -30431,7 +31171,7 @@ git -C "$(./getvar buildroot_source_dir)" checkout -
    -

    30.12.4. rootfs_overlay

    +

    31.12.4. rootfs_overlay

    We use this directory for:

    @@ -30476,7 +31216,7 @@ git -C "$(./getvar buildroot_source_dir)" checkout -
    -

    30.12.5. lkmc.c

    +

    31.12.5. lkmc.c

    The files:

    @@ -30506,7 +31246,7 @@ git -C "$(./getvar buildroot_source_dir)" checkout -
    -

    30.12.6. rand_check.out

    +

    31.12.6. rand_check.out

    Print out several parameters that normally change randomly from boot to boot:

    @@ -30533,7 +31273,7 @@ git -C "$(./getvar buildroot_source_dir)" checkout -
    -

    30.12.7. lkmc_home

    +

    31.12.7. lkmc_home

    lkmc_home refers to the target base directory in which we put all our custom built stuff, such as userland executables and kernel modules.

    @@ -30567,9 +31307,9 @@ git -C "$(./getvar buildroot_source_dir)" checkout -
    -

    30.13. Test this repo

    +

    31.13. Test this repo

    -

    30.13.1. Automated tests

    +

    31.13.1. Automated tests

    Run almost all tests:

    @@ -30625,7 +31365,7 @@ echo $?

    test does not all possible tests, because there are too many possible variations and that would take forever. The rationale is the same as for ./build all and is explained in ./build --help.

    -
    30.13.1.1. Test arch and emulator selection
    +
    31.13.1.1. Test arch and emulator selection

    You can select multiple archs and emulators of interest, as for an other command, with:

    @@ -30658,7 +31398,7 @@ echo $?
    -
    30.13.1.2. Quit on fail
    +
    31.13.1.2. Quit on fail

    By default, continue running even after the first failure happens, and they show a summary at the end.

    @@ -30672,7 +31412,7 @@ echo $?
    -
    30.13.1.3. Test userland in full system
    +
    31.13.1.3. Test userland in full system

    TODO: we really need a mechanism to automatically generate the test list automatically e.g. based on path_properties, currently there are many tests missing, and we have to add everything manually which is very annoying.

    @@ -30701,7 +31441,7 @@ echo $?
    -
    30.13.1.4. GDB tests
    +
    31.13.1.4. GDB tests

    We have some pexpect automated tests for GDB for both userland and baremetal programs!

    @@ -30774,7 +31514,7 @@ echo $?
    -
    30.13.1.5. Magic failure string
    +
    31.13.1.5. Magic failure string

    We do not know of any way to set the emulator exit status in QEMU arm full system.

    @@ -30877,9 +31617,9 @@ echo $?
    -

    30.13.2. Non-automated tests

    +

    31.13.2. Non-automated tests

    -
    30.13.2.1. Test GDB Linux kernel
    +
    31.13.2.1. Test GDB Linux kernel

    For the Linux kernel, do the following manual tests for now.

    @@ -30917,7 +31657,7 @@ echo $?
    -
    30.13.2.2. Test the Internet
    +
    31.13.2.2. Test the Internet

    You should also test that the Internet works:

    @@ -30928,7 +31668,7 @@ echo $?
    -
    30.13.2.3. CLI script tests
    +
    31.13.2.3. CLI script tests

    build-userland and test-executables have a wide variety of target selection modes, and it was hard to keep them all working without some tests:

    @@ -30946,7 +31686,7 @@ echo $?
    -

    30.14. Bisection

    +

    31.14. Bisection

    When updating the Linux kernel, QEMU and gem5, things sometimes break.

    @@ -31002,7 +31742,7 @@ git submodule update
    -

    30.15. path_properties

    +

    31.15. path_properties

    In order to build and run each userland and baremetal example properly, we need per-file metadata such as compiler flags and required number of cores.

    @@ -31045,7 +31785,7 @@ git submodule update
    -

    30.16. Update a forked submodule

    +

    31.16. Update a forked submodule

    This is a template update procedure for submodules for which we have some patches on on top of mainline.

    @@ -31075,9 +31815,9 @@ git commit -m "linux: update to ${next_mainline_revision}"
    -

    30.17. Release

    +

    31.17. Release

    -

    30.17.1. Release procedure

    +

    31.17.1. Release procedure

    Ensure that the Automated tests are passing on a clean build:

    @@ -31088,7 +31828,7 @@ git commit -m "linux: update to ${next_mainline_revision}"
    -

    The ./build-test command builds a superset of what will be downloaded which also tests other things we would like to be working on the release. For the minimal build to generate the files to be uploaded, see: Section 30.17.2, “release-zip”

    +

    The ./build-test command builds a superset of what will be downloaded which also tests other things we would like to be working on the release. For the minimal build to generate the files to be uploaded, see: Section 31.17.2, “release-zip”

    The clean build is necessary as it generates clean images since it is not possible to remove Buildroot packages

    @@ -31158,7 +31898,7 @@ git push --follow-tags
    -

    30.17.2. release-zip

    +

    31.17.2. release-zip

    Create a zip containing all files required for Prebuilt setup:

    @@ -31183,7 +31923,7 @@ git push --follow-tags
    -

    30.17.3. release-upload

    +

    31.17.3. release-upload

    After:

    @@ -31231,9 +31971,9 @@ git push --follow-tags
    -

    30.18. Design rationale

    +

    31.18. Design rationale

    -

    30.18.1. Design goals

    +

    31.18.1. Design goals

    This project was created to help me understand, modify and test low level system components by using system simulators.

    @@ -31309,7 +32049,7 @@ git push --follow-tags
    -

    30.18.2. Setup trade-offs

    +

    31.18.2. Setup trade-offs

    The trade-offs between the different setups are basically a balance between:

    @@ -31334,13 +32074,13 @@ git push --follow-tags

    compatibility: how likely is is that all the components will work well together: emulator, compiler, kernel, standard library, …​

  • -

    guest software availability: how wide is your choice of easily installed guest software packages? See also: Section 30.18.4, “Linux distro choice”

    +

    guest software availability: how wide is your choice of easily installed guest software packages? See also: Section 31.18.4, “Linux distro choice”

  • -

    30.18.3. Resource tradeoff guidelines

    +

    31.18.3. Resource tradeoff guidelines

    Choosing which features go into our default builds means making tradeoffs, here are our guidelines:

    @@ -31385,7 +32125,7 @@ git push --follow-tags
    -

    30.18.4. Linux distro choice

    +

    31.18.4. Linux distro choice

    We haven’t found the ultimate distro yet, here is a summary table of trade-offs that we care about: Table 7, “Comparison of Linux distros for usage in this repository”.

    @@ -31488,9 +32228,9 @@ git push --follow-tags
    -

    30.19. Soft topics

    +

    31.19. Soft topics

    -

    30.19.1. Fairy tale

    +

    31.19.1. Fairy tale

    @@ -31527,7 +32267,7 @@ git push --follow-tags
    -

    30.19.2. Should you waste your life with systems programming?

    +

    31.19.2. Should you waste your life with systems programming?

    Being the hardcore person who fully understands an important complex system such as a computer, it does have a nice ring to it doesn’t it?

    @@ -31612,7 +32352,7 @@ git push --follow-tags