Note that because radare2 uses Capstone to disassemble ARM code, there are issues with the disassembly. arm-none-eabi-objdump -d compiledbinary.elf actually does a better job in some cases. For example, msr isn't decompiled correctly...
First, you have to either strip the default ELF binaries the default Makefiles build when you run make OR you need to just compile .bin files using something like:
make binaryname.bin
Once you have a .bin file, you can then load it into radare2 and disassemble it. Keep in mind you'll need to use the following flags to configure r2 to look for ARM, 16bit, and Cortex specific opcodes (-a arm -b 16 -e asm.cpu=cortex):
r2 -a arm -b 16 -e asm.cpu=cortex miniblink.bin
> aaa (to analyze the binary)
> afl (to show the functions it's found)
> pdf @fcn.000001f8 (to show main())
> pdf @0x00000230 (to show gpio_toggle())
Then, enter Visual mode if you'd like:
> VV
And walk through the graph using the n and N keys. Use p and P to change the graph view mode!
Left image here is Radare, Right is GDB:
This time, I'm trying to disassemble the Bitcrazy Crazyflie 1.0 firmware. The file is called cf1.elf.
First reason I'm trying to disassemble this is so I can run the code and have a breakpoint trigger in r2 when the code hites somewhere in this function: crtpCommanderRpytDecodeSetpoint in this file: src/modules/src/crtp_commander_rpyt.c on line 175
Second it to do the same, when any change happens to variable values inside the function crtpCommanderRpytDecodeSetpoint in the file src/modules/src/crtp_commander_rpyt.c.
This is the area of the code where I can see the setpoint variables being sent over the radio link.
Since I last touched this stuff, a GSoC happened in the r2 world. I'm not sure the status of that work, but if nothing else, it doesn't seem to support target extended-remote /dev/ttyACM0 which I was partially hoping someone would build.
Alas, I'll probably have to build it myself.
r2 -a arm -b 16 -e asm.cpu=cortex cf1.elf
Warning: Cannot initialize dynamic strings (oops. Not sure why this is happening...)
> aaa
> e asm.pseudo=true (to help n0bs like me read ARM ASM)
> afl (to show the functions it's found)
> pdf @main (to show main())
> pdf @sym.crtpCommanderRpytDecodeSetpoint (to show crtpCommanderRpytDecodeSetpoint())
And that matches these similar set of gdb commands (Except that r2 is way easier to read...):
arm-none-eabi-gdb cf1.elf
(gdb) disassemble main
(gdb) disassemble crtpCommanderRpytDecodeSetpoint
Well, because r2 has issues just connecting right to /dev/ttyACM0 where the Black Magic Probe is sitting with it's own GDB server AND since we actually want to see the packets being sent out by r2 and received by the BMP, we link everything up through some command line hackery:
Note: This assumes you have the Black Magic probe on /dev/ttyACM0 (gdb extended-remote target) and /dev/ttyACM1 (UART)
stty -F /dev/ttyACM0 raw -onlcr -iexten -echo -echoe -echok -echoctl -echoke
nc -vkl -p 2000 > /dev/ttyACM0 < /dev/ttyACM0
Remember: when youre done with this hackery, run this to get a sane terminal back on /dev/ttyACM0
stty sane < /dev/ttyACM0
r2 -a arm -b 16 -e asm.cpu=cortex -d gdb://127.0.0.1:2000/1 cf1.elf
>
Once that's

I've updated this with some notes on getting STM32F4 code decompiled correctly inside of radare.
In short, you've gotta define the
asm.cpuradare2 config variables correctly otherwise some opcodes will be marked asinvalidby radare2.