what header files should be included first for each board type?
The various hardware register definitions come in through the "#include <avr/io.h>" statement in Arduino.h.
io.h in turn includes one of the many io*.h files from avr/include/avr, depending on the setting of the -mmcu switch on the compile statement. These in turn are automatically generated from xml "device description" files provided by Atmel.
So if you say -mmcu=atmega328p
, you'll get iom328p.h sucked into your program, which defines all of the hardware registers "and stuff, and support" that are present on the ATmega328p.
You can read a statement like: "#if defined(UBRRH) || defined(UBRR0H)"
as "if there is a single UART, or there is a UART0, then (create the datastructures arduino uses for dealing with the first serial port.)"
As of relatively recently, most of the arduino core code will check for the existence of particular peripherals by looking for the definition of a significant register from that peripheral, rather than doing conditional compilation based on board or cpu type.
So on an Arduino MEGA, the code will define data for Serial3, *not* because it's a MEGA, or because it has a m1280 cpu, but because UBRRH3 is defined, which means that "elsewhere" knows that a UART3 exists...
PS: this also means that io.h pulls in a LOT of register definitions that you probably do NOT want to add to your autocomplete word list for the average Arduino user!