In order to get the correct offset into the firmware file, I need to subtract 0x80000 from the entry point because the Flash begins at address 0x80000.
I wrote a script in Linux to show me the first 20 lines of the disassembly at the entry point:
#!/bin/sh
objdump=/opt/sloeber/arduinoPlugin/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/arm-none-eabi/bin/objdump
# On the next line, we get the entry point from the second 32-Bit Little Endian integer
entry_point=`dd if=myfirmware.bin bs=4 skip=1 count=1 2> /dev/null | xxd -ps -u | tac -rs .. | xargs echo obase=10\; ibase=16\; | bc`
echo Raw address of entry point in decimal = ${entry_point}
echo Thumb entry address = $((entry_point-1))
echo In the sam3x8e, Flash begins at 0x80000, so subtract 524288, giving an entry point of $((entry_point-1-524288))
dd if=myfirmware.bin of=zero.bin bs=1 skip=$((entry_point-1-524288)) 2> /dev/null
${objdump} -b binary -m arm -D ./zero.bin > disassembly.txt
head -20 disassembly.txt
And here are the first few lines of the disassembly:
Disassembly of section .data:
00000000 <.data>:
0: 4a164b15 bmi 0x592c5c
4: 4293b510 addsmi fp, r3, #16, 10 ; 0x4000000
8: d001461c andle r4, r1, ip, lsl r6
c: e0012300 and r2, r1, r0, lsl #6
10: e0074b13 and r4, r7, r3, lsl fp
The first instruction is "bmi 0x592c5c" which means "If the negative flag is set, jump to address 0x592c5c". Given that the first instruction is a jump instruction, this makes me feel confident that I've found the correct entry point. I wonder though why the negative flag would be set though? Does the negative flag perhaps indicate something like brown out?
And just to see what's located at the jump address, I wrote the following script:
#!/bin/sh
# The next line converts the address from hex to dec
addr=`echo obase=10\; ibase=16\; $1 | bc`
objdump=/opt/sloeber/arduinoPlugin/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/arm-none-eabi/bin/objdump
echo Jump address in decimal = ${addr}
echo In the sam3x8e, Flash begins at 0x80000, so subtract 524288, giving a firmware file offset of $((addr-524288))
bytes_to_skip=$((addr-524288))
size_of_original=`stat -c %s ./myfirmware.bin`
if [ ${addr} -lt 524288 ] || [ ${addr} -gt 1048575 ]; then
echo You have specified an address past the end of the Flash
echo The Flash begins at address 524,288
echo The Flash ends at address 1,048,575
echo Internal ROM begins at address 1,048,576
echo Reserved begins at address 2,097,152
echo SRAM begins at address 536,870,912
exit 1
else
if [ ${bytes_to_skip} > ${size_of_original} ]; then
echo Specified address is within range of Flash however your firmware file is too small
echo Firmware size = ${size_of_original}
echo Jump address = ${bytes_to_skip}
exit 1
fi
fi
dd if=myfirmware.bin of=showfrom.bin bs=1 skip=$((addr-524288)) 2> /dev/null
${objdump} -b binary -m arm -D ./showfrom.bin > disassembly_showfrom.txt
head -20 disassembly_showfrom.txt
I run this script at the command line with: ./showfrom.sh 592C5C
And here's what I get back:
Jump address in decimal = 5844060
In the sam3x8e, Flash begins at 0x80000, so subtract 524288, giving a firmware file offset of 5319772
You have specified an address past the end of the Flash
The Flash begins at address 524,288
The Flash ends at address 1,048,575
Internal ROM begins at address 1,048,576
Reserved begins at address 2,097,152
SRAM begins at address 536,870,912
The address 0x592c5c is in the Reserved section. So when the microcontroller starts executing instructions from the Flash, the first thing it does is check if the negative flag is set, and if it is then it jumps to an address inside the Reserved section. Does anyone know what's going on here?