Issue title: Build sketches without bootloader
 Issue body: 
### Basic Infos
Is it possible to compile sketches without eboot bootloader?
### Description
Hey,

I would like to use the rboot bootloader (https://github.com/raburton/rboot) to have multiple ROMs on my ESP written using Arduino. For this, I need the compiled .elf, but without the eboot bootloader so I can create my own image using esptool2. Is there any flag or anything I can comment out to accomplish this?

Thanks in advance,
Niklas
 Comments: 
 Comment 0: You need to edit the build recipes in platform.text, probably specifically 

```
recipe.objcopy.hex.pattern
```

Though I suspect it won't support any of the OTA updatery functionality.
You may also need to update some addresses of things (I don't know how large the rboot binary is, if it's more than a single page (4k) things will get more complicated and you'll need to edit the linker files.
 Comment 1: Thanks for the fast answer, the platform.txt was exactly what I was looking for!

First, I made a copy of the nodemcu board config and edited the corresponding linker script by increasing the irom0_0_seg address from 0x40201010 to 0x40202010 (rboot is a bit bigger than eboot).

I changed 
`## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elfraw" [...]`

so I get the .elfraw without the bootloader, that seems to work.

Then I use esptool2 to create my own binary:

`esptool2 -bin -debug -boot2 -1024 -dio /tmp/arduino_build_236811/sketch.ino.elfraw ~/rboot_test/rom0.bin .irom0.text .text .data .rodata`

I upload everything using esptool:
`esptool.py --port /dev/ttyUSB0 -b 921600 write_flash --flash_mode dio --flash_size 1MB 0x0 rboot.bin 0x02000 rom0.bin 0x82000 rom1.bin`

The rboot loader seems to work fine, however, the actual rom crashes:

Serial dump:
`rBoot v1.4.2 - john50@example.com
Flash Size:   8 Mbit
Flash Mode:   DIO
Flash Speed:  40 MHz

Everything up to date.
Booting rom 0.

Fatal exception (3): 
epc1=0x4000438f, epc2=0x00000000, epc3=0x00000000, excvaddr=0x40202010, depc=0x00000000
`

So, any idea why this happens? 

Best regards,
Niklas
 Comment 2: What's at 0x4000438f? :)
A map file from the linker is useful for finding things like that.

Did you follow the rboot 'Linking user code' section?
A quick glance through rboot's code suggests there shouldn't be any major barriers to doing what you're trying to.
 Comment 3: Thanks for the hint!

I generated the map using xtensa-lx106-elf-nm

`40004b1c A SPIRead
400043c8 A SPI_read_status
40004a4c A SPIWrite
4000443c A SPI_write_enable
40004400 A SPI_write_status`

For now I use the addresses from the provided rboot example.
One question: Why do I need to specify the SPI mode, size and clock for creating the binary? I never had problems using other clock rates or bigger flash sizes. Actually, the board I'm developing with has 8MB of flash, even though it's not supported by esptool I can program it without any problems setting the flash size to 1MB, 2MB or 4MB. Might this be a problem?
 Comment 4: It's crashing in the middle of a SPIRead call, which I suspect means it hasn't left rboot, which would mean the sketch is irrelevant.
Do you have a binary from something that's not the Arduino system that works?

 Comment 5: I believe there's a PR of nodemcu firmware (the one with lua integrated)
with a working rboot. I seem to recall an effort to expose the rboot api in
an attempt to implement OTA updates (the firmware doesn't have OTA
capability yet).
You could try taking a look at how that was done.

On Apr 3, 2017 10:21 PM, "Julian Davison" <john50@example.com> wrote:

> It's crashing in the middle of a SPIRead call, which I suspect means it
> hasn't left rboot, which would mean the sketch is irrelevant.
> Do you have a binary from something that's not the Arduino system that
> works?
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/esp8266/Arduino/issues/3111#issuecomment-291362648>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AQC6BrlQQJOyZIGSj7DfQq8-tez286GPks5rsZstgaJpZM4MyG91>
> .
>

 Comment 6: So, I tried a few more things, for example I'm able to execute my "standalone" roms using the eboot bootloader, having the john50@example.com. So the problem must be with rboot.

I had a close look on the actual bootloading thing, both eboot and rboot are using "jx a3" for setting the instruction pointer. I noticed this line in eboot that is missing in rboot:

`register uint32_t sp asm("a1") = 0x3ffffff0;`

Can someone explain me what it does?

Best regards,
Niklas
 Comment 7: I expect (given the surrounding lines) that it's initialising the 'stack pointer' or 'sp' to be the end of RAM
 Comment 8: Are you using the right flash mode (DIO)? Most are QIO.
 Comment 9: @NiklasFauth did you get this to work? To be honest, I would love to move to rboot, it is better known and has better features vs. eboot (at least at first glance).
In addition, I fully support your effort to have multiple images flashed. The OTA process would certainly be safer, because you would always write the "other image", and then just change the boot address to point to it. Then, if for some reason the boot of the new image failed, you could fall back to the "old image". As  I explained in my previous comment, I understand that the Nodemcu Lua project uses rboot successfully.
I believe that the current approach with eboot is different. During OTA, there is a fixed "emtpy" area at which the new image is flashed. Then, during boot, the new image is copied over the old normal image.
The consecuence of that is, if there is a power outage during the copy process, the ESP could get soft-bricked.

 Comment 10: Reference: #905
 Comment 11: That's issue #905 :)

Should we be looking at switching to rboot?
It's been a while since I've looked at it, but does it some how detect that 'the boot of the new image failed'? Aside from checks that the image is correct (such as a checksum) I'm not sure how the bootloader would know...
 Comment 12: For reference, the solution for #905 is to only mark the update as complete when the copy process has completed successfully; until it has, each startup results in the copy being tried again.
 Comment 13: @davisonja I don't know the specifics, maybe it's possible to do something similar with eboot as well.
Even so, I like rboot better. It's open source and well known.
The way I understand the Nodemcu logic is that you don't mark the update as complete until very late in the boot process. I think in our case it would be just before calling setup.
The point of the logic is to not just make sure that the update finished successfully, but to also make sure that the new image actually boots, at least up until a certain point. If the new image fails to boot, then you mark the update as failed, and roll back to the previous image.
Example: say that the new image was built wrongly (wrong layout, a code change in main, whatever). You update the ESP, the process succeeds. But then it won't boot anymore => the ESP is soft-bricked.

The Nodemcu logic is something along these lines:
The flash has 2 image slots, call them 0 and 1.
Boot from current image (say slot 0). Update slot 1 with broken image, process succeeds. Boot to image in slot1. Boot process fails (i.e.: doesn't reach the point where the image is marked "good"), fall back to reboot from image in slot 0.
=> no soft brick.

I think there are other details as well, such as if there is an immediate reboot with boot reason crash, then the new image is also discarded and the previous image is booted. I'm not sure of the specifics, it's been a long while since that discussion.
 Comment 14: @devyte  Okay, that makes sense. As long as the new image knows to mark itself as being okay, that would work happily.

I'm happy to look at rboot as an alternative. eboot is very simple and, I think, fits nicely with the relatively simple approach of arduino (not overly complex, but functional), but it might be nice to have the option of using rboot for those who would like more complex behaviour.
 Comment 15: Integrating rboot might be easier if you work within the context of makeEspArduino or platform.io. I can imagine that shoehorning another link step into Arduino IDE build process can be done, but would be quite hacky (you somehow need to tell Arduino to compile bootloader files, but not link them into the sketch). Alternative would be to put rboot elf file into the repository, as it is done now with eboot, but one would probably loose a fair bit of rboot's configurability that way.
I would prefer to keep the option of using eboot in Arduino, but i'm not religious about this. If rboot can be integrated nicely, I would not mind.
 Comment 16: I think eboot should be the default. It's simple, it works, and it does
what the vast majority of novice users want - which is not to say we can't
improve it :)

rboot offers a wider range of functionality that, in my opinion, is well
beyond a novice users use-case, but baked in, or a documented process to
use, rboot would be useful enough it's worth pursuing.

On Fri, Sep 8, 2017 at 8:53 PM, Ivan Grokhotkov <john50@example.com>
wrote:

> Integrating rboot might be easier if you work within the context of
> makeEspArduino or platform.io. I can imagine that shoehorning another
> link step into Arduino IDE build process can be done, but would be quite
> hacky (you somehow need to tell Arduino to compile bootloader files, but
> not link them into the sketch). Alternative would be to put rboot elf file
> into the repository, as it is done now with eboot, but one would probably
> loose a fair bit of rboot's configurability that way.
> I would prefer to keep the option of using eboot in Arduino, but i'm not
> religious about this. If rboot can be integrated nicely, I would not mind.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/esp8266/Arduino/issues/3111#issuecomment-328044461>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AAN_A6iOM9A6K1Ubh07iBxXGwYjixFpCks5sgQCUgaJpZM4MyG91>
> .
>

 Comment 17: > That's issue #905 :)
> 
> Should we be looking at switching to rboot?
> It's been a while since I've looked at it, but does it some how detect that 'the boot of the new image failed'? Aside from checks that the image is correct (such as a checksum) I'm not sure how the bootloader would know...

Hey,

this thread is old but I would like to share my thought about rboot.

At work we are dealing with [RAUC](https://rauc.readthedocs.io/en/latest/). Which is for Linux the equivalent of rboot for whatever you want to call the flash content of an ESP.

Anyway I quite like RAUC and it has nice features like failovers, bundle signitures, compatability strings and so on. It also has a mark-good command which tags the running image ...well: as good. But defining conditions to trigger this command is up to the architects/users.

Whats does a successful boot mean? That LEDs are blinking? All drivers were loaded successfully? That there's a wifi connection? That there's a internet connection? That the correct credentails for whatever are present?

This is not easy to define or check, especially not for the bootloader. rboot does its best to verify you have a working slot (to use RAUC terminology) - which is more than eboot does - and boots it, what then happens might be: hang, watchdog, reboot, backup slot - which, to my understanding, is not possible with eboot. If a slot fails, its up to programmer of that slot, not the bootloader. RAUC (and rboot - if configured correctly) try to maintain the device reachable as well as possible and this is a huge advantage over eboot.

With rboot it is possible to realize nearly all what RAUC can do - especially fallback on broken updates (experiences it quite often that an OTA bricked my ESPs and I had to reprogram them by serial).

So I would relly like to see rboot beeing available to Arduino.
 Comment 18: I would say - for this usecase - a boot was successfull if setup() was started.
I opt for a precompiled rboot replacing eboot so as to not change the general behaviour.
So pros can "precompile" their bells-and-whistles rboot while for the general arduino user additional "nice-to-have" rboot features could gradually be implemented ...
 Comment 19: I am also trying to achieve the same i.e. building Arduino scratch without eboot that can be loaded by boot_v1.6.bin esp8266 NON-OS-SDK. I tried following but didn't get the expected result. 

I opened elf2bin.py script that is responsible to generate final binary and commented section in main() that was trying to include eboot.

#        wrapper(
#            elf=args.eboot,
#            segments=[".text", ".rodata"],
#            to_addr=4096
#        )

Well It builds fine and I could generate bin file. But If I try to use that bin file from from boot_v1.6.bin available in the SDK, It seems to be resetting board in a loop.

I loaded boot_v1.6.bin at address 0x0
I loaded my hello.ino.espino.bin at address 0x01000 (as boot_v1.6.bin expect user binary to be at this address and my user binary built using esp8266 SDK loaded at this address)

Can you please guide me how to build user binary (arduino sketch) without eboot that can be loaded by standard SDK boot loader.



 Comment 20: Hi Again,
I took an another approach today. I took elf image of my sketch from output directory and tried to convert it in to bin as per NonOS SDK procedure

My Sketch Elf File Name: hello.ino.elf

Step 1: Run objcopy command to generate following files as per Make file rules
`xtensa-lx106-elf-objcopy.exe --only-section .text -O binary hello.ino.elf eagle.app.v6.text.bin
xtensa-lx106-elf-objcopy.exe --only-section .data -O binary hello.ino.elf eagle.app.v6.data.bin
xtensa-lx106-elf-objcopy.exe --only-section .rodata -O binary hello.ino.elf eagle.app.v6.rodata.bin
xtensa-lx106-elf-objcopy.exe --only-section .irom0.text -O binary hello.ino.elf eagle.app.v6.irom0text.bin`

Step2: Run gen_appbin.py available in tools directory of nonos sdk to create binary file eagle.app.flash.bin
`tools\gen_appbin.py hello.ino.elf 1 2 0 4 1`

Step3: Flashed following as per nonos SDK OTA guidelines
`boot_v1.6.bin:             0x00000;
eagle.app.flash.bin:       0x01000;
esp_init_data_default.bin: 0x3FC000;
blank.bin:                 0x3FE000;`

Run the board. But it did not work (no output on console except for some junk).

This is a standard Makefile procedure of nonos SDK to convert elf file to in bin that can boot with SDK bootloader, so I am not able to understand why this process did not work. Can someone please throw some light on to what might have gone wrong?
 Comment 21: I see one major difference in the linker script between SDK and Arduino. In case of nonos SDK, IRAM has only one segment (.text) whereas Arduino splits IRAM in to  two segment .text and .text1.

Do I need to do objcopy for .text1 as I am doing for .text segment? If Yes, How to I use it in gen_appbin.py, does that script need to be updated?
 Comment 22: I now changed objcopy command to include both sections (.text and .text1) as follows 

from
`xtensa-lx106-elf-objcopy.exe --only-section .text -O binary hello.ino.elf eagle.app.v6.text.bin`
to 
`xtensa-lx106-elf-objcopy.exe --only-section .text* -O binary hello.ino.elf eagle.app.v6.text.bin`

But still no success. From Theoretical point of view it should work but I believe something else is also missing. 

Any pointer will help to get it working
{'source': 'GithubIssues', 'repo_name_with_owner': 'esp8266/Arduino', 'issue_id': 219065594, 'repo_stars': 15398.0}