Menu

#3909 HOME segment silently moved, producing unbootable image

open
nobody
None
other
5
2026-01-08
2025-12-31
No

ITE Tech makes 8051-based laptop embedded controllers (EC), such as the IT5570. Their chips have a hardware mechanism to check if e-flash firmware is programmed by a 16-byte signature check at power-on. The default code address for this is 0x40.

The introduction of the atomic functions in r14916 ("Full atomic_flag for mcs51, ds390. Some infrastructure for lock-free atomics.") introduces a conflict with this address.

Actual behavior

  • Compilation is successful
    • HOME segment, reset vector is silently moved to 0x50, producing an unbootable image

Expected behavior

  • Either, compilation is successful
    • HOME segment, reset vector remain at 0
    • ITE code signature occupies 16-bytes starting at 0x40
    • Atomic functions are placed in any other available space
  • Or, compilation fails
    • Error reported for conflicting address

Code

Using debian:trixie-20251208-slim container:

# sdcc --version
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/r800/ds390/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502/mos65c02/f8 TD- 4.5.0 #15242 (Linux)

main.c:

// ITE code signature for eSPI host
static __code const unsigned char __at(0x40) SIGNATURE[16] = {
    0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA4, 0x95,
    0x85, 0x12, 0x5A, 0x5A, 0xAA, 0x00, 0x55, 0x55,
};

void main(void) {
    for (;;) {}
}

Built with:

sdcc -mmcs51 --model-large --Werror -o main.ihx main.c

Discussion

  • Tim Crawford

    Tim Crawford - 2026-01-08

    According to the datasheet, the signature can be at any 16-byte aligned at 0x40-0xF0.

    The 8051-based SoC datasheets are still only available under NDA, but the RISC-V ones are publicly available and have the same functions. e.g.: IT82302:

    6.4.3.12 E-flash Power-on Detection
    6.4.3.12.1 16B-signature and Implicit/Explicit EC Code Base Address

    Doing a quick search, the signature was fixed and documented in this Zephyr pull request: https://github.com/zephyrproject-rtos/zephyr/pull/36379
    ...Which is more informative than the literal datasheets, because it actually defines the LPC/eSPI bus function in byte 7.

    Proprietary firmware for the 8051-based SoCs still use 0x40, so I'd like to continue using that for the signature for parity if possible. But can at least look into using 0x80 to match the RISC-V Zephyr SoCs.

     

    Last edit: Tim Crawford 2026-01-08
    • Maarten Brock

      Maarten Brock - 2026-01-08

      If this signature can indeed be moved that would be the most easy way to fix this.

      The alternative is to modify SDCC itself as the start up code with the interrupt vectors and the atomic functions is generated when main() is compiled.
      https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/src/mcs51/main.c#l339

      Or to rename main() to e.g. mymain() and create your own startup.asm from the currently generated main.asm.

      Note that the sdcc_atomic_* functions must start at a multiple of 8 address for the rollback to work properly.

      Once the linker can handle .bndry directives the generated sdcc_atomic_* implementations can be moved into a separate module.

       

Log in to post a comment.