在 8 位元微控制器上託管網站
在現代網頁開發的世界中,我們通常將可用的龐大運算能力和頻寬視為理所當然。然而,Maurycy 最近的一個專案展示了 8 位元架構的極強韌性,他在一個 AVR64DD32 微控制器上託管了一個功能完備(儘管速度很慢)的網站。這個專案是處理極端限制條件的典範教學,迫使開發者必須以創意的方式來實作網路與協定。
硬體:AVR64DD32
為了實現這一點,Maurycy 使用了 AVR64DD32,它是 Arduino 板上著名的 Atmega328 的現代親戚。雖然它仍然是 8 位元核心,但與其前身相比,它提供了幾項優勢,包括更好的週邊設備和約 1 美元的低成本點。
關鍵規格:
- CPU: Single 8-bit AVR core @ 24 MHz
- RAM: 8 kB
- Flash: 64 kB
- EEPROM: 256 bytes
- Voltage: 1.8 - 5.5 Volts
克服網路瓶頸
主要的障礙之一是網際網路連接的實體層。雖然乙太網路 (10BASE-T) 是標準選擇,但事實證明它對 AVR 來說太快了。因為 10BASE-T 使用曼徹斯特編碼(Manchester encoding)——其中 0 表示「10」,1 表示「01」——因此對於 10 Mbps 的數據速率,實際線路速度為 20 Mbps。由於 AVR 的週邊設備和 IO 引腳最大速度僅為 12 MHz,該晶片根本無法產生所需的訊號。
為了繞過這一點,該專案利用了 Serial Line Internet Protocol (SLIP) (RFC 1055)。SLIP 是一種古老且輕量級的標準,用於透過序列連接進行網路運作。它的運作方式是將封包包裝在特定的位元組 (0xC0) 中,並使用簡單的轉義序列 (0xDB) 來處理與包裝位元組衝突的數據。
在 Linux 主機端,連接是使用 slattach 建立的,它將 USB 轉序列適配器轉換為網路介面。這使得 MCU 可以使用基本的序列鏈路來與網路的其他部分進行通訊。
實作 TCP/IP 堆疊
在建立實體連接後,軟體挑戰轉向了 TCP/IP 堆疊。在 8 kB 的 RAM 上實作完整的堆疊是一項艱鉅的任務,但該專案透過幾項策略性的省略來簡化了過程:
IP 層
實作 IP 標頭 (40 bytes) 是相對直接的。透過忽略封包分段(packet fragmentation)——這在現代作業系統中很大程度上已被禁用,並在 IPv6 中被移除——作者能夠簡單地透過交換接收封包的來源與目的地地址來產生回應標頭。
TCP 層
TCP 比 IP 複雜得多。它需要微控制器追蹤連接狀態、管理丟失封包的重傳,並處理眾多的邊緣情況。作者花了幾天時間實作了一個自定義的、輕量級的 TCP 實作,以使伺服器能夠運作。
HTTP 層
為了保持實作極簡化,作者繞過了完整的 HTTP 解析器。相反,伺服器被硬編碼為無論請求什麼 URL,都只發送單一回應。這使得網站可以在只有一個頁面的情況下正常運作。
路由與公開存取
由於 MCU 缺乏公開的 IPv4 地址,且位於 CGNAT 之後,作者使用了 WireGuard 和反向代理的組合。
- The VPS: 一個具有公開 IP 地址的虛擬私人伺服器充當入口。
- The Tunnel: WireGuard 在 VPS 與本地 Linux 路由器盒之間建立了一個虛擬網路鏈路。
- The Proxy: Linux 路由器將
/mcu路徑下的請求代理到 MCU 的本地地址。
這種架構確保了訪客不會直接衝擊 MCU 脆弱的 TCP/IP 堆疊,為防止 SYN floods 和基本的 DDoS 攻擊提供了一層保護。
社群洞察與硬體演進
該專案激發了關於 8 位元微控制器演進的討論。雖然 AVR DD 系列功能強大,,但一些社群成員指出,新興的 PIC32 CM 提供了 ARM Cortex-M0+ 核心,同時保留了 AVR DD 的許多週邊設備功能。這表明了向 32 位元架構的轉移,旨在提供更多效能,同時保持引腳相容性或高能效。
儘管有這些進步,該專案突顯了「用 AVR 微控制器做些無聊的事」中永恆的吸引力。正如一位用戶所說,看著 HTML 流式傳輸到頁面上實時發生的過程,喚起了對撥號上網時代的懷舊感,提醒我們,網際網路可以仍然使用最基本的組件從零開始構建。