PCI expansion ROM header Entry point for INIT function

808 views Asked by At

As indicated in section 6.3.3.1. ROM Header Extensions (PCI Local Bus Specification v2.3), offset 0x3h is "Entry point for INIT function. POST does a FAR CALL to this location.", this field's length is 3 bytes.

I have a PCI Rom image which length is 40448 bytes, the Entry Point bytes are 0xe9_cf_06 (0xe9 at address 0x3h, 0xcf at address 0x4h and 0x06 at address 0x5h). This offset exceeds the ROM image length. May anyone please help to explain the meaning of this field and how to use it to figure out the entry point for image on ROM?

Any suggestions are appreciated. Thanks!

2

There are 2 answers

3
Jonathon Reinhart On BEST ANSWER

Offset 03h is the entrypoint, not the address of the entrypoint. That means that the BIOS actually jumps to offset 03h and begins executing code there.

Note, your ROM looks something like:

aa 55 xx e9 cf 06 ...

You shouldn't notate those bytes as 0x_e9_cf_06 - that's interpreting the multiple bytes as an integer, (which you don't mean to do), and as this is Intel, it's in the wrong order (Intel is little endian).

You could drop this ROM into a decompiler to understand more.

As you found out, E9 CF 06 is a JMP 0x06CF which means (jump 0x6CF bytes from the next instruction). Always remember to consult the Intel Instruction Set Reference (Vol. 2).

0
Dien Nguyen On

I finally figured out the meaning of this field. It is actually and x86 instruction embedded inside the ROM header. The first byte "0xe9" is a jump instruction. Anyone who is interested in can check the fcode suite source code for more detail

        switch (data->reserved[1]) {
        case 0xeb: /* short jump */
                entry = data->reserved[2] + 2;
                /* a short jump instruction is 2 bytes,
                 * we have to add those to the offset
                 */
                break;
        case 0xe9: /* jump */
                entry = ((data->reserved[3]<<8)|data->reserved[2]) + 3;
                /* jump is 3 bytes, so add them */
                break;
        default:
                entry=0;
                break;
        }

        if (entry) {
                /* 0x55aa rom signature plus 1 byte len */
                entry += 3;
                printf( "  Entry point for INIT function:"
                        " 0x%x\n\n",entry);
        } else
                printf( "  Unable to determine entry point for INIT"
                        " function. Please report.\n\n");

        break;