This is how CE roms are laid out

IM: The *original of this document can be found here. this is based on a 3.15.15 o2 rom.
range sizeusedfreecontents
80000000-80040000 40000 28084 17f7c the bootloader
80040000-802c2000 282000 22a7a8 57858 kernel
802c2000-80580000 2be000 2bb330 2cd0 OS
80580000-80780000 200000 1da690 25970 SHELL
80780000-80a40000 2c0000 292aac 2d554 BROWSING
80a40000-80dc0000 380000 34a33c 35cc4 COREAPPS
80dc0000-80ec0000 100000 fd6c8 2938 SYNC
80ec0000-81080000 1c0000 1788e0 47720 24MAPPS
81080000-81400000 380000 2c8248 b7db8 24MCONSUMER
81400000-81440000 40000 1484 3eb7c xipchain - public keys for updatexip.exe
81440000-81900000 4c0000 3b0f24 10f0dc MISC
81900000-81940000 40000 25800 1a800 bootup bitmap
81940000-81e40000 500000 3339b2 1cc64e autoconfig files
81e40000-81f00000 c0000 c0000 empty
81f00000-81f01000 1000 3b0 c50 saved contacts index
81f01000-81f80000 7f000 4410 7abf0 saved contacts
81f80000-81f81000 1000 290 d70 saved registry index
81f81000-81fc0000 3f000 bf70 33090 saved registry
81fc0000-81fc1000 1000 810 7f0 saved mail index
81fc1000-82000000 3f000 3c740 28c0 saved mail
notes: the saved data indexes are formatted as follows:
0000-00050000 0000 0000
0006flag ?
0008+8*iCEOID ( ce record object id )
000c+8*irecord length
000e+8*iflag?
idc script to document contacts db layout:
// idx  = entry index
// base = pointer to index entry
// ea   = start of record
// end  = end of record
//
// returns real size of record.
static MakeContactsEntry(idx, base, ea, end) {
    auto ofs, aLen;

    MakeUnknown(ea, end);

    ExtLinA(ea, 0, "");
    ExtLinA(ea, 1, form("--- %3d %08lx %04x %04x", 
        idx, Dword(base),Word(base+4),Word(base+6)) );

    for (ofs= ea ; ofs < ea+6*4 ; ofs = ofs+4)
        MakeDword(ofs);

    SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);
    do {
        MakeStr(ofs, -1);
        aLen= ItemSize(ofs);

        if (aLen>2)
            ofs = ofs + aLen;
    } while (aLen>2);
    MakeDword(ofs);
    MakeDword(ofs+4);
    MakeDword(ofs+8);
    MakeDword(ofs+12);
    ofs= ofs+16;

    SetLongPrm(INF_STRTYPE, ASCSTR_LEN4);
    MakeStr(ofs,-1);
    aLen= ItemSize(ofs);
    if (aLen>1) {
        ofs= ofs+aLen;
    }
    else {
        MakeDword(ofs);
        ofs= ofs+4;
    }

    if (ofs&3) {
        MakeAlign(ofs,2,2);
        ofs= ofs+ItemSize(ofs);
    }

    return ofs-ea;
}

dumprom romfile extraction tool

To get almost usable versions of the files in rom, the relocation information is missing, but for most it is not an issue, and most files seem to have a truncated resources section ( probably due to a bug in microsofts romimage tool ) I created this tool, you can find the source here
to compile:
cl /Zi /Wall /wd4710 /wd4217 /wd4668 /wd4820 /wd4619 /EHsc dumprom.cpp NKCOMPR.LIB
btw, weird that microsofts own header files generate so many warnings

dumprom was updated on june 14th, it now detects where the image starts. sometimes it will just tell you what the offset is, then specify that offset prefixed with '0x' after the filename on the commandline to actually look at the rom.
I will fix this in the next release

dumprom nk-e740-1.0618.0409.bin
img 00000000 : hdr=80273c8c base=80040000  commandlineoffset=8003ffe5
img 00282000 : hdr=8057cd38 base=80040000  commandlineoffset=8003ffe5
img 00540000 : hdr=80759a38 base=80040000  commandlineoffset=8003ffe5
...
then type dumprom nk-e740-1.0618.0409.bin 0x8003ffe5 to view the rom contents.
or dumprom nk-e740-1.0618.0409.bin 0x8003ffe5 -d files >e740info.txt to save the info to a text file, and extract the rom files to a directory

tools to do the reverse ( create a rom from a set of files ) can be found here.