Search code examples
linux-kernelembedded-linuxu-bootwatchdogcompression

Linux kernel detecting the pre-boot environment for watchdog


So I'm developing for an embedded Linux system and we had some trouble with an external watchdog chip which needed to be fed very early in the boot process.

More specifically, from what we could work out it would this external watchdog would cause a reset while the kernel was decompressing its image in the pre-boot environment. Not enough down time before it starts needing to be fed, which should probably have been sorted in hardware as it is external, but an internal software solution is wanted.

The solution from one of our developers was to put in some extra code into...

int zlib_inflate(z_streamp strm, int flush) in the lib/zlib_inflate/inflate.c kernel code

This new code periodically toggles the watchdog pin during the decompression.

Now besides the fact that I feel like this is a little bit of a dirty hack. It does work, and it has raised an interesting point in my mind. Because this lib is used after boot as well. So is there a nice way for a bit of code detecting whether you're in the pre-boot environment? So it could only preform this toggling pre-boot and not when the lib is used later.

As an aside, I'm also interested in any ideas to avoid the hack in the first place.


Solution

  • See @sawdust answer for an answer on how to achieve the watchdog feeding without having to hack the kernel code.

    However this does not fully address the original question of how to detect that code is being compiled in the "pre-boot environment", as it is called within kernel source.

    Files within the kernel such as ...

    include/linux/decompress/mm.h
    
    lib/decompress_inflate.c
    

    And to a lesser extent (it isn't commented as clearly)...

    lib/decompress_unlzo.c
    

    Seem to check the STATIC definition to set "pre-boot environment" differences. Such as in this excerpt from include/linux/decompress/mm.h ...

    #ifdef STATIC
    
    /* Code active when included from pre-boot environment: */
    
    ...
    
    #else /* STATIC */
    
    /* Code active when compiled standalone for use when loading ramdisk: */
    
    ...
    
    #endif /* STATIC */