# Linux Kernel Module Cheat

##### 33.10.7.1. NienfengYao/armv8-bare-metal

https://github.com/NienfengYao/armv8-bare-metal

The only QEMU `-m virt` aarch64 example set that I can find on the web. Awesome.

A large part of the code is taken from the awesome educational OS under 2-clause BSD as can be seen from file headers: https://github.com/takeharukato/sample-tsk-sw/tree/ce7973aa5d46c9eedb58309de43df3b09d4f8d8d/hal/aarch64 but Nienfeng largely minimized it.

I needed the following minor patches: https://github.com/NienfengYao/armv8-bare-metal/pull/1

Handles an SVC and setups and handles the timer about once per second.

The source claims GICv3, however if I try to add `-machine gic_version=3` on their command line with our QEMU v4.0.0, then it blows up at:

    static void init_gicc(void)
    {
        uint32_t pending_irq;

        /* Disable CPU interface */
        *REG_GIC_GICC_CTLR = GICC_CTLR_DISABLE;

which tries to write to 0x8010000 according to GDB.

Without `-machine`, QEMU’s DTB clearly states GICv2, so I’m starting to wonder if Nienfeng just made a mistake there? The QEMU GICv3 DTB contains:

    reg = <0x0 0x8000000 0x0 0x10000 0x0 0x80a0000 0x0 0xf60000>;

and the GICv2 one:

    reg = <0x0 0x8000000 0x0 0x10000 0x0 0x8010000 0x0 0x10000>;

which further confirms that the exception is correct: v2 has a register range at 0x8010000 while in v3 it moved to 0x80a0000 and 0x8010000 is empty.

The original source does not mention GICv3 anywhere, only pl390, which is a specific GIC model that predates the GICv2 spec I believe.

TODO if I hack `#define GIC_GICC_BASE (GIC_BASE + 0xa0000)`, then it goes a bit further, but the next loop never ends.