ESP8266 ROM XTOS

来自Jack's Lab
2015年12月11日 (五) 08:01Comcat (讨论 | 贡献)的版本

(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转到: 导航, 搜索

目录

1 逆向工程



2 探索

2.1 SYSTEM_RTC_MEM_READ

uint32 system_rtc_mem_read(int32 addr, void *buff, int32 length)
{
    int32 blocks;
     
    // validate reading a user block
    //if (addr < 64) return 0;
    if (buff == 0) return 0;
    // validate 4 byte aligned
    if (((uint32)buff & 0x3) != 0) return 0;
    // validate length is multiple of 4
    if ((length & 0x3) != 0) return 0;
     
    // check valid length from specified starting point
    if (length > (0x300 - (addr * 4))) return 0;
 
    // copy the data
    for (blocks = (length >> 2) - 1; blocks >= 0; blocks--) {
        volatile uint32 *ram = ((uint32*)buff) + blocks;
        volatile uint32 *rtc = ((uint32*)0x60001100) + addr + blocks;
        *ram = *rtc;
    }
 
    return 1;
}



2.2 SYSTEM_RTC_MEM_WRITE

uint32 system_rtc_mem_write(int32 addr, void *buff, int32 length)
{
    int32 blocks;
     
    // validate reading a user block
    if (addr < 64) return 0;
    if (buff == 0) return 0;
    // validate 4 byte aligned
    if (((uint32)buff & 0x3) != 0) return 0;
    // validate length is multiple of 4
    if ((length & 0x3) != 0) return 0;
     
    // check valid length from specified starting point
    if (length > (0x300 - (addr * 4))) return 0;
 
    // copy the data
    for (blocks = (length >> 2) - 1; blocks >= 0; blocks--) {
        volatile uint32 *ram = ((uint32*)buff) + blocks;
        volatile uint32 *rtc = ((uint32*)0x60001100) + addr + blocks;
        *rtc = *ram;
    }
 
    return 1;
}



2.3 SYSTEM_GET_RST_INFO

struct rst_info {
    uint32 reason;
    uint32 exccause;
    uint32 epc1;
    uint32 epc2;
    uint32 epc3;
    uint32 excvaddr;
    uint32 depc;
};
 
struct rst_info system_get_rst_info()
{
    struct rst_info rst;
    system_rtc_mem_read(0, &rst, sizeof(struct rst_info);
    if (rst.reason >= 7) {
        ets_memset(&rst, 0, sizeof(struct rst_info));
    }
    if (rtc_get_reset_reason() == 2) {
        ets_memset(&rst, 0, sizeof(struct rst_info));
        rst.reason = 6;
    }
    return rst;
}




3 CACHE_READ_ENABLE

Cache_Read_Enable is defined in the Boot ROM (XTOS) at memory address 0x40004678


 void Cache_Read_Enable(uint8 odd_even, uint8 mb_count, unt8 no_idea);


Valid values for odd_even:

 0 – clears bits 24 & 25 of control register 0x3FF0000C
 1 – clears bit 24, sets bit 25
 other – clears bit 25, sets bit 24


Function of odd_even:

 0 – allows access to even numbered mb
 1 – allow access to odd numbered mb
 other – appears to do the same as 1, there must be a difference but I haven’t worked out what it it


Valid values for mb_count:

 0-7 – set bits 16, 17 & 18 of control register 0x3FF0000C

Function of mb_count:

Which odd or even bank to map (according to odd_even option)

 e.g. mb_count = 0, odd_even = 0 -> map first 8Mbit of flash
 e.g. mb_count = 0, odd_even = 1 -> map second 8Mbit of flash
 e.g. mb_count = 1, odd_even = 0 -> map third 8Mbit of flash
 e.g. mb_count = 1, odd_even = 1 -> map fourth 8Mbit of flash


Valid values for no_idea:

 0 – sets bit 3 of 0x3FF00024
 1 – sets bit 26 of 0x3FF0000C and sets bits 3 & 4 of 0x3FF00024

Function of no_idea:

The clue is in the name, I can’t work out what this does from my experiments, but the SDK always sets this to 1.

void Cache_Read_Enable(uint8 odd_even, uint8 mb_count, uint8 no_idea) {
     
    uint32 base1 = 0x3FEFFE00;
    volatile uint32 *r20c = (uint32*)(base1 + 0x20c);
    volatile uint32 *r224 = (uint32*)(base1 + 0x224);
     
    uint32 base2 = 0x60000200;
    volatile uint32 *r008 = (uint32*)(base2 + 8);
     
    while (*r20c & 0x100) {
        *r20c &= 0xeff;
    }
 
    *r008 &= 0xFFFDFFFF;
    *r20c &= 0x7e;
    *r20c |= 0x1;
     
    while ((*r20c & 0x2) == 0) {
    }
 
    *r20c &= 0x7e;
    *r008 |= 0x20000;
 
    if (odd_even == 0) {
        *r20c &= 0xFCFFFFFF;  // clear bits 24 & 25
    } else if (odd_even == 1) {
        *r20c &= 0xFEFFFFFF;  // clear bit 24
        *r20c |= 0x2000000;   // set bit 25
    } else {
        *r20c &= 0xFDFFFFFF;  // clear bit 25
        *r20c |= 0x1000000;   // set bit 24
    }
 
    *r20c &= 0xFBF8FFFF; // clear bits 16, 17, 18, 26
    *r20c |= ((no_idea << 0x1a) | (mb_count << 0x10)); // set bits 26 & 18/17/16
    // no_idea should be 0-1 (1 bit), mb_count 0-7 (3 bits)
 
    if (no_idea == 0) {
        *r224 |= 0x08; // set bit 3
    } else {
        *r224 |= 0x18; // set bits 3 & 4
    }
     
    while ((*r20c & 0x100) == 0) {
        *r20c |= 0x100;
    }
 
    return;
}



个人工具
名字空间

变换
操作
导航
工具箱