Does anybody know any resources about programming custom bootloaders for Arduinos / AVR chips?

I was planning on making a project that would involve using a WiFi network / the Internet to upload code over the internet. I've seen Ariadne, but it looks like it hasn't been updated in 6 years. Considering that it's still supposedly in a beta state, it's probably not going to get completed. This a bit of a problem because that means I don't really have a reliable way to reset the Arduino over the internet as well.

The solution to me is to create my own bootloader, however looking at the source code of optiboot it seems like it's quite a departure from regular C programming. Unfortunately I cannot find any proper sources about programming a bootloader for AVR chips, which is why I'm asking here. Does anybody know anywhere I can go so I can learn about AVR chips and how bootloaders should be written? For reference I know a considerable amount of C++, and it would probably only take me a couple of hours to learn the C equivalents of certain C++ things (i.e. std::cout vs printf).

Can't really help there, but have doubts a boot loader would have been written in C or C++.

Optiboot looks to be written in C, but there are a lot of compiler directives and in-line assembly mixed in. There was an emphasis on keeping it small enough to fit in a minimal amount of memory.

This is the most active version of Ariadne:

It is not under active development, but it is not 6 years dead like the version you found.

I have used it a lot and found it to be very nice. There is plenty of room for improvement, but I do not consider it "unfinished".

All the ones I've looked at are at least partly C (with some assembly).

Other examples:

Ah, I see. Thank you for sending me a more up to date version of the bootloader. It still raises the concern about having to manually use the reset button as far as I can tell, though, so I would still like to know how to make my own bootloader, or at the very least understand the general gist of the Ariadne bootloader so I can modify it to do what I want it to do.

Yes, that's what I thought too, considering all of the macros I saw. It seems to be the same idea for the Adriadne bootloader, and it looks almost completely foreign as a person who has only written complex code for proper x86-64 systems, not microcontrollers.

edit: Adriadne source code is actually somewhat readable to me but it's still somewhat confusing. Would be great if I could get a starting point to learn about the functions of the Adriadne bootloader

You can configure your sketch so that you send it a command over the network and then it does a watchdog timer reset to activate the bootloader. This allows you to upload to the board remotely without any need for a manual reset. However, you must be careful that this reset functionality is working in every sketch you upload to the board. If you upload a sketch without the reset functionality, or with the reset functionality not working, then you will need to get physical access to the board so that you can manually reset it.

My original plan was to add some sort of integration with the Arduino IDE (since it's open source) as a small project of mine that would add WiFi-Uploading capabilities to the IDE Application. My goal is to make it all run under the hood so somebody who has only ever touched the Arduino IDE can use it without any hassle. I've never used any of this kind of code before (since I've never had to automatically reset the Arduino) but it looks like it's just a simple command to reset the Arduino, so would it work to add the functionality to the sketch behind the scenes when somebody uses the "verify" or "upload" button?

I think still regardless to the fact that I can use the Adriadne bootloader just fine, it would be nice to learn how to make my own bootloader for fun, so if anybody else has resources it would still be appreciated if I could have them

When it comes to Wi-Fi, a lot of work has been done in the OTA area. In this case, the bootloader is not really involved. The exception is that with AVR you do need the bootloader to provide the ability for the application to write to flash:

But other than that the bootloader doesn't know anything at all about the network.

Some resources on OTA:

The Arduino IDE already has support for these "network ports". They show up just like the serial ports, and there is even the ability to add "user fields" for authentication.

This system has recently been reworked significantly. You can read about that here:
https://arduino.github.io/arduino-cli/latest/platform-specification/#properties-from-pluggable-discovery

The watchdog timer is often used as a failsafe system to prevent any chance of the microcontroller locking up. You set a timer duration and if the timer is not reset before that duration expires, the watchdog resets the microcontroller.

But you can also use it to reset the microcontroller by intentionally allowing a time out

Here is a small demonstration sketch:

// Demonstrates the use of the AVR watchdog timer.
// Blink the onboard LED at 1Hz by repeated WDT timeout resets.

// WARNING: There is a bug in the older bootloader used on the Pro Mini, old/clone Nanos, and some other boards that cause running this sketch to "brick" the board (recoverable by burning the bootloader).
// If the bootloader doesn't reset the watchdog then this will cause a perpetual reset loop after the first blink and the LED will blink rapidly
// See: https://github.com/arduino/ArduinoCore-avr/issues/150

const byte LEDPin = LED_BUILTIN;

#include <avr/wdt.h>

void setup() {
  pinMode(LEDPin, OUTPUT);
  digitalWrite(LEDPin, HIGH);
  delay(500);
  digitalWrite(LEDPin, LOW);
  wdt_enable(WDTO_500MS);  //enable the watchdog timer with a 500 millisecond timeout duration
}

void loop() {}  // Do nothing, allowing the watchdog to time out

More information here:

https://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html

Yeah! I have done a bit of tinkering around with Ariadne and avr_boot and found it very interesting even though I didn't really know what I was doing.

So does that mean that you can just upload code to an Arduino over the internet with the stock bootloader and IDE? I thought that since you had to use a custom bootloader it would require tweaking. Or is this implementation limited compared to serial ports and I would still have to add functionally for uploading code to flash memory?

Read a little bit more into the links you sent. Are these not compatible with the Arduino Uno? One of the links you sent said it required 64kB of flash memory, however the other one seems like a simple sketch that can be run, correct me if I'm wrong.

I don't know anything about doing it over the Internet. My small experiments have all been within my LAN. I know that it is doable with Ariadne (though it is likely not very secure against a concerted attack), but I don't know what the situation is with the Wi-Fi OTA options. I'm sure there is a lot of info about it related to the ESP8266 and ESP32 though.

I do know that Arduino provides an OTA capability through Arduino IoT Cloud:

Not for the AVR boards (with the exception of the Yun). But, yes with the MKR1000, ESP8266, and ESP32 it works right out of the box. Just upload the example sketch that comes with the library and the network port pops up in the Tools > Port menu of the Arduino IDE.

Yes, the ArduinoOTA library requires more flash memory than the Uno has to offer. This approach only allows you to use half of the flash at a time because the newly uploaded sketch must be uploaded to the other half, combine that fact with the networking stack being pretty big, and you see that it is difficult to fit on the more resource constrained microcontrollers.

Which one is that?

the arduino-esp8266 documentation about how to use OTA Updates.

Security isn't my biggest concern. Pretty much just had the idea spring up when I was in one of my computer tech classes and my teacher was showing off some web server being able to interface with a microcontroller. Since we were online the idea of uploading code over the internet to an Arduino came to my head (although probably not very practical in this situation, I thought it would be a cool project) and I wanted to make that happen as a fun project for myself. I wasn't aware that there was already implementation in the Arduino IDE to do just that, though :​(

That can only be used on an ESP8266 board. There is also one for ESP32:

https://docs.espressif.com/projects/arduino-esp32/en/latest/ota_web_update.html

which AVR chips? what WiFi module?

over Internet it is better to use download of the update https://github.com/jandrassy/ArduinoOTA#ota-update-as-download

I'll have to check the exact specifications later but I'm sure I can find a resource now that I know they exist. I'll keep this open for an answer as I'm still curious on creating a custom bootloader. Can't remember which AVR chip is on the Arduino Unos though.

ATmega328p with 32kB flash.
what WiFi module?

Again, I'll have to get that information later. It's fine now though, I can do my own research afterwords.

I didn't think that Optiboot departed very much from "regular C." I mean, it has a bunch of conditional code so as to work with many possible cpus and configurations, but the actual code is pretty straightforward. The only inline asm is for actually writing flash, and for implemented the soft uart.
There is some documentation in the wiki: HowOptibootWorks · Optiboot/optiboot Wiki · GitHub

There are the other Arduino bootloaders: ATmegaBoot and stk500v2 boot
There are also Microchip (nee Atmel) App notes on writing bootloaders, including "some" info in the datasheets.

However, when creating an OTA-uploadable board, it's getting INTO the bootloader that is the tricky part. After that, all you have to do is make sure you stay there long enough for however long your network connection takes to establish (and maybe setting up the network as well? You don't have a lot of space - max bootloader size on a 328 is only 4k.)