任天堂Switch遊戲機採用的NVIDIA Tegra X1處理器,被美國一位電子工程師Kate Temkin查驗出有漏洞;在正常情況下,電腦裝置在開機之後,就會執行內建的開機啟動程式(bootloader),執行其作業系統。而Kate找到方法,讓Tegra X1處理器在開機時進入復原模式(Recovery Mode,或者說「工程模式」,簡稱RCM),進而從USB執行其他程式。
用比較粗糙的方式來比喻,就像個人電腦預設會啟動Windows系統,但是在開機時調整設定,就能從USB隨身碟啟動其他系統軟體、執行非Windows軟體。
因為這個漏洞會影響到所有採用 Tegra X1處理器的裝置(如:平板、車載電腦),Kate在第一時間就知會NVIDIA ,後來在她的部落格釋出稱為Fusée Gelée(法文,「果膠火箭」之意)的開機啟動程式(launcher,也有「火箭發射器」之意),以及Atmosphère(大氣層)開放原始碼韌體。
這是Kate公佈在YouTube的Fusée Gelée啟動影片(片長3秒)。
轉述某個淘寶「大氣層」賣家的商品說明,2018年5月之前購買的Switch遊戲機,或者在5月之後購買,美版、港版、日版機器序號在XAJ700438, XAW100875和XAW700之前,都存在此漏洞。
此破解方式的缺點:每次重新開機時,都需要讓主機進入復原模式並從USB執行自製韌體。問題是,Arduino怎麼會跟Switch改機扯上邊?先來認識一下32位元的Arduino控制板。
採用SAMD21系列微控器的Arduino控制板
Arduino Zero是Arduino官方於2014年推出的32位元控制板(如下圖),外觀尺寸與Uno控制板一致,採用SAMD21系列32位元48 MHz微控器,所有數位和類比腳最高僅容許3.3V。
Arduino Zero的微控器是ATSAMD21G18,它有兩個特點:
- 內建USB介面:可擔任USB主控端(Host)或週邊(Device),能用程式設置成滑鼠、鍵盤、儲存媒介(隨身碟)…等裝置。
- 記憶體容量夠大:內含32 KB SRAM(主記憶體)和256KB Flash(快閃記憶體),除了裝載控制板本身的控制程式,還有空間承載Fusée Gelée韌體。
後來,一位暱稱atlas44的玩家,釋出使用Arduino語言開發,編譯後能在採用SAMD21晶片的控制板執行的“Sam Fusee Launcher”,於是Arduino板就變成了能從USB注入(inject)自製韌體的改機工具了。
繼Arduino官方採用新處理器系列,陸續有廠商跟進。像美國知名的Adafruit和SparkFun Electronics電子零組件供應商,都有推出SAMD21系列控制板,例如SparkFun SAMD21 Mini Breakout、Adafruit GEMMA M0、還有下圖的Adafruit Trinket M0:
這是號稱世界最小,已預先燒錄Arduino Zero的開機啟動程式(bootloader)的控制板Nerdonic Exen Mini,基板的背面有Micro USB母座和Reset按鍵:
為注入Fusée Gelée程序而生的SAMD21控制板
有些改機玩家使用上述的微型SAMD21控制板,加上鈕扣型電池,變成攜帶式自製韌體注入工具;有些人則拆開Switch主機,直接從Switch主機板取得3.3V電源並自內部連接USB,像Hackaday這篇”Nintendo Switch gets internal Trinket hardmod“報導的改機方式,為了塞進Switch主機,Trinet M0控制板的Micro USB插座事先被焊除掉:
接著有玩家和廠商,順勢推出沒有Micro USB插座的SAMD21控制板,像這個SwitchME控制板(圖片來源:reddit) :
這是附帶CR2032電池座的微型SAMD21控制板“SAMD V2 Fusee Payload Injector”(圖片來源:Hackaday)
這個叫做Dragon Injector的設計概念恨酷,整體外觀收納成Switch遊戲卡匣的模樣(圖片來源:gbatemp.net)。
未完,待續…
#include
int i1 = 0;
int i2 = 0;
int i3 = 0;
int i4 = 0;
int i5 = 0;
int i6 = 0;
int i7 = 0;
const byte ROWS = 4; //four rows
const byte COLS = 2; //three columns
const byte LEDs[11] = {
B1111110,
B0110000,
B1101101,
B1111001,
B0110011,
B1011011,
B1011111,
B1110000,
B1111111,
B1111011,
B0000000
};
char keys[ROWS][COLS] = {
{‘1′,’2’},
{‘3′,’4’},
{‘5′,’6’},
{‘*’,’7′}
};
byte rowPins[ROWS] = {13, 12,11,10}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
DDRD = B11111111;
pinMode(7,OUTPUT) ;
}
void loop(){
char key = keypad.getKey();
if (key==’1′){
i1=i1+1;
}
if (key==’2′){
i2=i2+1;
}
if (key==’3′){
i3=i3+1;
}
if (key==’4′){
i4=i4+1;
}
if (key==’5′){
i5=i5+1;
}
if (key==’6′){
i6=i6+1;
}
if (key==’7′){
i7=i7+1;
}
if (key==’*’){
LEDs[i1];
delay(1000);
LEDs[11];
delay(500);
LEDs[i2];
delay(1000);
LEDs[11];
delay(500);
LEDs[i3];
delay(1000);
LEDs[11];
delay(500);
LEDs[i4];
delay(1000);
LEDs[11];
delay(500);
LEDs[i5];
delay(1000);
LEDs[11];
delay(500);
LEDs[i6];
delay(1000);
LEDs[11];
delay(500);
LEDs[i7];
delay(1000);
LEDs[11];
delay(500);
}
if (key){
digitalWrite(7,HIGH);
delay(1000);
}
}
我想要請問一下,我希望可以讓我統計按下幾次數字鍵(2*4)小鍵盤,輸出到七段顯示器,並且只要有按下小鍵盤,就讓二極體亮一下,請問程式何者有錯?雖然編輯沒有問題,但是無法跑出正確結果???