Use this forum to chat about hardware specific topics for the ESP8266 (peripherals, memory, clocks, JTAG, programming)

User avatar
By 0ff
#1247 Okay, building upon this, in order to put any "sense" into the dump, you can add names to the functions, as defined in eagle.rom.addr.v6.ld
These names help A LOT in understanding what's going on.

In IDA Pro, you can simply run the attached commands as python, they will automatically name the functions.
You need to load the dump at 0x40000000 and you need the IDA CPU Plugin for xtensa CPUs (which is the great work of https://github.com/themadinventor/ida-xtensa).

Have fun reading the ROM Code then :-)
You do not have the required permissions to view the files attached to this post.
User avatar
By tinhead
#1250 ohhh i missed that IDA plugin, what beauty!
User avatar
By mamalala
#1320
0ff wrote:In IDA Pro, you can simply run the attached commands as python, they will automatically name the functions.
You need to load the dump at 0x40000000 and you need the IDA CPU Plugin for xtensa CPUs (which is the great work of https://github.com/themadinventor/ida-xtensa).

Have fun reading the ROM Code then :-)


There seems to be a bug in that plugin, as it turns out. I hope the maintainer of it reads this.

As i was poking around with accessing the pin registers directly, i first went by the disassembly of the gpio_output_set() function in the ROM, as done by IDA Pro. This is what it generated:

Code: Select allROM:40004CD0 gpio_output_set:                        ; CODE XREF: gpio_init+26p
ROM:40004CD0                                         ; gpio_intr_test+17p ...
ROM:40004CD0                 l32r            a6, dword_40000FC4
ROM:40004CD3                 memw
ROM:40004CD6                 s32i            a2, a6, 4
ROM:40004CD9                 memw
ROM:40004CDC                 s32i            a3, a6, 8
ROM:40004CDF                 memw
ROM:40004CE2                 s32i            a4, a6, 0x10
ROM:40004CE5                 memw
ROM:40004CE8                 s32i            a5, a6, 0x14
ROM:40004CEB                 ret.n
ROM:40004CEB ; End of function gpio_output_set


Now, the dword at 0x40000FC4 holds the value 0x60000200. Therefore i was assuming that this function accesses the registers at 0x60000204, 0x60000208, 0x60000210 and 0x60000214. However, as soon as i wrote anything to it, the chip rebooted with an exception.

Then i checked eagle_soc.h, and there the base address is given as 0x60000300. And of course, using 0x60000304, 0x60000308, 0x60000310 and 0x60000314 works as expected. I then posetd in the GCC thread to ask jcmvbkbc if he sees anything wrong with the code, or if there is something going on that missed, since he seems to be the resident Xtensa expert here. He couldn't find anything wrong with the bytecode.

Now, tinhead was so kind to check what would show up in the Xtensa IDE, compared to a disassembly by IDA, when accessing stuff. So he went and compiled the following code:

Code: Select allvoid user_init(void)
{
    WRITE_PERI_REG(0x60000300, 0);
    WRITE_PERI_REG(0x60000200,0);
}


Now, in IDA that comes out as:

Code: Select all.text:00000004 dword_4         .int 0x60000200         ; DATA XREF: user_init+2r
.text:00000008
.text:00000008 ; =============== S U B R O U T I N E =======================================
.text:00000008
.text:00000008 ; Attributes: noreturn
.text:00000008
.text:00000008 user_init:
.text:00000008                 movi.n          a2, 0
.text:0000000A                 l32r            a3, dword_4
.text:0000000D                 memw
.text:00000010                 s32i            a2, a3, 0
.text:00000013                 memw
.text:00000016                 s32i.n          a2, a3, 0
.text:00000018                 ret.n
.text:00000018 ; End of function user_init


Now, as you can see that can't be right. One is accessing 0x6000.0300, the other 0x6000.0200, but in both cases the store's are working on a 0 offset to the dword having 0x6000.0200.

Next, doing:

Code: Select all    WRITE_PERI_REG(0x60000400, 0);
    WRITE_PERI_REG(0x60000500,0);


produced the exact same disassembly in IDA. However, in the Xtensa IDE, the disassembly looks like this:

Code: Select allDisassembly of section .text:00000000 <user_init-0x4>:
   0: 60000200                                ...`00000004 <user_init>:
#include "ets_sys.h"
#include "osapi.h"
#include "user_config.h"void user_init(void)
{
   4: 020c       movi.n a2, 0
   6: fffe31         l32r a3, 0 <user_init-0x4> (also 60000200)
 WRITE_PERI_REG(0x60000400, 0);
   9: 0020c0         memw
   c: 806322         s32i a2, a3, 0x200
 WRITE_PERI_REG(0x60000500,0);
   f: 0020c0         memw
  12: c06322         s32i a2, a3, 0x300
}
  15: f00d       ret.n


So here we have the store's using the proper offsets to get the right address. The IDA plugin disassembled them wrongly.

Would be great if that can be fixed, since that affects quite a lot of of stuff when going through a siassembly in IDA.

Greetings,

Chris
User avatar
By 0ff
#1326 Hey Chris,

could you maybe attach a minimal binary to showcase the problem?
If I go ahead and compile the sources, this is what I am left with (i.e. both calls happen with the correct address):

Code: Select all.text:40100000 ; ===========================================================================
.text:40100000
.text:40100000 ; Segment type: Pure code
.text:40100000 _stext          .int 0x60000400         ; DATA XREF: call_user_startr
.text:40100004 dword_40100004  .int 0x60000500         ; DATA XREF: call_user_start+Ar
.text:40100008
.text:40100008 ; =============== S U B R O U T I N E =======================================
.text:40100008
.text:40100008
.text:40100008 call_user_start:
.text:40100008                 l32r            a3, _stext
.text:4010000B                 movi.n          a2, 0
.text:4010000D                 memw
.text:40100010                 s32i.n          a2, a3, 0
.text:40100012                 l32r            a3, dword_40100004
.text:40100015                 memw
.text:40100018                 s32i.n          a2, a3, 0
.text:4010001A                 ret.n
.text:4010001A ; End of function call_user_start
.text:4010001A
.text:4010001A


It's most certainly related to the compiler flags used, but to have a common ground it'd be awesome if you could post the binary you are working with.

Regards,
Fabian