Sí, la memoria flash ATmega328 y los fusibles son programables en un chip nuevo, no programado (sin cargador de arranque) en su interfaz SPI. Así que necesitas controlar cuatro de los pines ATmega328; La interfaz SPI y RESET.
Lea la sección "31.8. Descarga en serie" en la hoja de datos completa de ATmega328 (no la hoja de datos de resumen), que comienza:
Las matrices de memoria Flash y EEPROM se pueden programar usando la
El bus serie SPI mientras RESET se lleva a GND. La interfaz serial
consta de pines SCK, MOSI (entrada) y MISO (salida).
Una forma de crear tu propio programador interno (ISP) es usar un Arduino. Hay ejemplos de cómo controlar la interfaz SPI del ATmega328 objetivo en la web, pero puede comenzar por leer el código en Uso de un Arduino como AVR ISP (programador en el sistema) . Es un programador ISP 'completo', que trabaja con avrdude, que es una aplicación de programación de código abierto. Necesitará averiguar cómo construir un binario que pueda leer avrdude. Potencialmente, la forma más fácil de comenzar es usar el ensamblador y el vinculador binutils gcc de GNU. Producirán un archivo binario que avrdude puede cargar sin otras "partes móviles" (aplicaciones).
Si quieres algo aún más mínimo, tendrás mucho trabajo por hacer. Sin embargo, un paso útil podría ser entender cómo funciona la carga SPI. Puede hacerlo extrayendo el código de carga de ese programa Arduino AVR-ISP, deseche el resto del programa. Llamemos a esto el 'programa de carga'. Luego, en lugar de implementar un protocolo para cargar el programa binario de avrdude, almacene el código binario que ha creado para representar su programa, en ese nuevo programa de carga como datos. Modifique el programa para cargar esos datos usando el código de carga. Esto le proporciona un sistema de carga autónomo, que necesita la cadena de herramientas avr-gcc sin utilizar el IDE de Atmel. Cuando cargue la carga combinada y los datos del programa binario en un Arduino, se cargará en un ATmega328.
Luego, puedes averiguar cómo quieres proceder a partir de ellos, sabiendo que tienes un sistema de carga en funcionamiento. Por ejemplo, podría inventar su protocolo ganado para hablar con su propio cargador y su propio formato para el código binario.
Editar:
Un gestor de arranque se carga en un ATmega no programado de esta manera. Sin embargo, no necesita un gestor de arranque si tiene algo que programará el flash ATmegas y los fusibles sobre SPI.
Hay varios cargadores de arranque de Open Source ATmega, por lo que puedes usar uno de ellos o usar uno como base de tu ganancia.
Le sugeriría que visite avrdude , que podría ser un ajuste adecuado para cargar el código. No he leído su fuente, pero sí un amigo cercano, y dijo que es muy complejo porque funciona con casi todos los chips Atmel que se han fabricado. Escribió un simple cargador SPI, que solo funcionó para un solo ATmega, desde cero en pocos días.
Recomiendo encarecidamente mirar GNU binutils para AVR. Obtiene todo esto cuando descarga e instala el IDE de Arduino. Incluyen un ensamblador, que será mucho más productivo que ensamblar a mano las instrucciones de AVR, y un enlazador que producirá archivos binarios "adecuados" que los programas como avrdude pueden cargar. Los binutils también tienen herramientas útiles como un desensamblador (para archivos de código binario con el formato correcto).
Edit 2:
@AndrewP ha señalado que un sistema como Raspberry-Pi se puede conectar electrónicamente a un Atmega (ya sea con un poco de cambio de nivel o ejecutando el ATega a 3.3 V) para que pueda manejar la interfaz SPI directamente. O, si tiene una PC suficientemente antigua, también puede usar el puerto paralelo.
(Personalmente, sugeriría mirar los cables FTDI USB a SPI, o su hardware de interfaz USB de propósito general que le permitiría programar la interfaz SPI desde una PC host a través de USB)
(Además, IIRC avrdude se ejecuta en el R-Pi. No lo he comprobado, pero es probable que haya una versión de los binutils GNU para el R-Pi ya compilado y listo para instalar).