Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Blend XMODEM -UEFI de XMODEM-/KernelvmKansai8
Search
Toshifumi NISHINAGA
November 18, 2017
Programming
2
510
Blend XMODEM -UEFI de XMODEM-/KernelvmKansai8
UEFIでXMODEMを実装しようと頑張った話です。
Toshifumi NISHINAGA
November 18, 2017
Tweet
Share
More Decks by Toshifumi NISHINAGA
See All by Toshifumi NISHINAGA
BareMetalで遊ぶRaspberry Pi 5 PCIe編/KernelVM Tokyo17
tnishinaga
0
1.6k
probe-rsの紹介と最近の貢献紹介/CELF-02-03
tnishinaga
1
320
SecurityCamp2023基板作るコース講義資料/Security Camp 2023 Lecture Materials
tnishinaga
8
2.4k
RP2040のPIOを使う話/KernelVM Hokuriku 6
tnishinaga
3
1.2k
JTAGでArmプロセッサをデバッグする方法のつづき/KernelVM_Tokyo16
tnishinaga
0
360
CMSIS-DAPの概要と使い方/KernelVM Online5
tnishinaga
0
1.6k
JTAGでarmプロセッサをデバッグする話/KernelVM Online4
tnishinaga
4
3k
ARM入門/arm introduction
tnishinaga
15
12k
俺の仮想マシンルーターがこんなに遅いはずはない/ KernelVM online 1
tnishinaga
0
2.7k
Other Decks in Programming
See All in Programming
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
120
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
100
OSSで起業してもうすぐ10年 / Open Source Conference 2024 Shimane
furukawayasuto
0
110
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.3k
Contemporary Test Cases
maaretp
0
140
Duckdb-Wasmでローカルダッシュボードを作ってみた
nkforwork
0
130
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
360
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
350
カンファレンスの「アレ」Webでなんとかしませんか? / Conference “thing” Why don't you do something about it on the Web?
dero1to
1
110
イマのCSSでできる インタラクション最前線 + CSS最新情報
clockmaker
4
1.3k
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.2k
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
120
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
93
16k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
130
Keith and Marios Guide to Fast Websites
keithpitt
409
22k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
Producing Creativity
orderedlist
PRO
341
39k
We Have a Design System, Now What?
morganepeng
50
7.2k
10 Git Anti Patterns You Should be Aware of
lemiorhan
655
59k
Fireside Chat
paigeccino
34
3k
Mobile First: as difficult as doing things right
swwweet
222
8.9k
Building an army of robots
kneath
302
43k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
24k
Transcript
Blend XMODEM UEFI de XMODEM 2017/11/18 KernelVM@Kansai8
$ who @tnishinaga
今回の話 AARCH64ボードのUEFI上でXMODEMを動かします
今回の話 AARCH64ボードのUEFI上でXMODEMを動かします
今回の話 AARCH64ボードから 発表がておくれるほどに受けた 数々のご褒美(?)についてのお話
そもそもの動機 1. AARCH64の勉強がしたい a. UEFIから起動するOSもどきを作ってみたい 2. 手元にあるHiKey Boardでやりたい 3. 毎回SDカード抜き差しするの大変
4. リモートからプログラムを送りたい
リモートからプログラムを 送りたい!
リモートからプログラムを送る方法たち • シリアル転送(X/Y/Z MODEM, Kermit) ◦ メリット:追加部品がいらない。パソコン側の設定もいらなくて楽。 ◦ デメリット:遅い。実装が面倒。 •
ネットワークブート(PXE(TFTP)ブート) ◦ メリット: 速い。安心(UEFI側の実装がちゃんとしてれば)。 ◦ デメリット: USB-NIC購入(1000円くらい)が必要(Hikey boardはNICを持たない)。 パソコン側の設定がちょっと必要。 ◦ https://wiki.linaro.org/Boards/Hikey/Setup/TFTPBoot
XMODEM • X,Y,Z MODEM中で最も単純なバイナリ転送プロトコル • 大抵のシリアル通信アプリケーション(minicom, TeraTerm)か ら使える • 一部、効率や機能が不十分
◦ でも今回のようにプログラムを送りつけるだけなら問題なし
XMODEMの通信フロー • 送信側が受信側からNAKを受 け取ると通信開始 • 送信側がデータを送信、受信側 がACKを返して1ブロックずつ転 送 • 送信側がEOTを送ると受信側
はACKを返して転送終了 Receiver Sender Block data 1 ACK Block data 2 NAK NAK EOT ACK
XMODEMのエラー通信フロー • 受信ブロックが壊れている場合 はNAK(再送要求)を送る • 送信側はNAKを受け取ると、前 回のブロックを再送する • 再度受け取ったブロックが正常 ならACKを返して通信再開
• 送信側は一定回数以上NAKを 受け取ると通信を諦める Receiver Sender Block data 1 NAK Block data 1 NAK NAK ACK
ね? 簡単でしょ?
簡単じゃなかった
ご褒美1 Q. UEFIの文字コードはUTF-16。 1byte read/writeをするにはどうすれば? A. “SERIAL IO PROTOCOL”を使う
SERIAL IO PROTOCOL • ボードのシリアルポートを直接Read/Writeできる ◦ http://wiki.phoenix.com/wiki/index.php/EFI_SERIAL_IO_PROTOCOL • 使い方 ◦
LocateHandleでSERIAL_IO_PROTOCOLのハンドラを取得 ▪ シリアルポートが複数ある場合、各ポートに対応した複数のハンドラが取得できる ◦ HandleProtocolで任意のハンドラからSERIAL_IO_PROTOCOLを取得 ◦ SERIAL_IO_PROTOCOLのRead/Writeを使って読み書きすればOK ▪ https://github.com/tnishinaga/baremetal_hikeyboard/blob/master/uefi_serial_echo_sampl e/main.c
ご褒美2 Q. どうやって一定時間ごとに 受信待ちループを解除してNAK送信するの? (UEFIアプリは割り込み処理が大変) (受信側スタート厳しくない?) A. SERIAL_IO_PROTOCOLのSetAttibutesで タイムアウトを設定する
SetAttributes • タイムアウト設定できる ◦ 0にするとデフォルト • NAK送信→受信待ち→タイム アウト→NAK送信→... とすれば行ける!! http://wiki.phoenix.com/wiki/index.php/EFI_SERIAL_I
O_PROTOCOL#SetAttributes.28.29
うまく動かない デバッグしないと
ご褒美3 Q. シリアル1本XMODEMで使ってるよね? どこでPrintf debugするの? A. シリアルを2本生やせば良いのでは?
シリアルを2本生やす • QEMUならオプションでUSBやPCIバスにシリアルデバイスを 生やせる......? ◦ qemu-system-aarch64 FOOBAR \ -chardev pty,id=pts0
-device isa-serial,chardev=pts0 -chardev pty,id=pts1 -device isa-serial,chardev=pts1
生えない
シリアルが2本生えない • AARCH64はisa-busに繋げない • USB, PCIにはつなげるが、UEFI側が認識しない • QEMUのコードを読むとVirtマシン*には元々1本しかシリアル ポートがマッピングされていない(?) ◦
https://github.com/qemu/qemu/blob/master/hw/arm/virt.c *: Linaroの出してるQEMUようUEFIイメージはVirtマシン専用
ご褒美4 Q. どうやってシリアルを2本生やすの? A. x86_64のQEMUに生やす
x86 QEMUでシリアルを2本生やす • x86_64のQRMUならシリアルを2本生やせる ◦ qemu-system-x86_64 -cpu qemu64 \ -drive
if=pflash,format=raw,unit=0,file=/usr/share/ovmf/ovmf_code_x64.bin,readonly=on \ -drive if=pflash,format=raw,unit=1,file=/usr/share/ovmf/ovmf_vars_x64.bin \ -hda fat:rw:. \ -chardev pty,id=pts0 -device isa-serial,chardev=pts0 \ -chardev pty,id=pts1 -device isa-serial,chardev=pts1 • ちゃんとUEFI側でも認識する ◦ 片方をデバッグ、片方をXMODEM通信用にしてデバッグ開始
MINICOM vs TMUX
ご褒美5 • ptsをめぐる争い a. QEMUがシリアルポートをptsにつなげる b. minicomでptsを開く c. QEMUを終了する(minicomはptsを開いたまま) d.
tmuxで新しいウィンドウを開く e. tmuxとminicomの入出力が繋がり入力を奪い合う • 対応 a. デバッグ中は今開いてるターミナルだけで頑張る
データの一部 消えてない?
ご褒美6 • 問題 a. 送信側はNAKを受け取ってデータを送ろうとしてる b. 受信側はデータを受け取れずタイムアウトしてNAKを送る c. NAKを受け取った送信側はデータを再送する d.
以降繰り返し e. (データが闇に消えてる気がする) • 対策 a. タイムアウトを数回繰り返すまで待ってからNAKを送るようにした b. ちょっとぎこちないがx86のQEMU上ではデータを受け取れた
後は実機に持っていくだけ!
動かない。
ご褒美7 • 問題 a. ご褒美6と同じく、データを受け取れずNAKを送り続けている b. デバッグしたいがシリアル1本しか無い • 対策 a.
ファイルに書き出せば良いのでは?
UEFIでのファイル読み書き 1. HandleProtocolとmainの引数のimage handleから LOADED_IMAGE_PROTOCOLを取得する 2. 再度HandleProtocolとLOADED_IMAGE_PROTOCOLのDeviceHandleからボ リュームのEFI_FILE_IO_INTERFACEを取得する 3. EFI_FILE_IO_INTERFACEのOpenVolumeでストレージのルートを開いた
EFI_FILE_PROTOCOLを得る 4. EFI_FILE_PROTOCOLのOpenでファイルを開く 5. EFI_FILE_PROTOCOLのWriteでファイルに書き込む 6. EFI_FILE_PROTOCOLのCloseでファイルを閉じる
これでログが取れるね!
None
書き込みデータがお かしい
ご褒美8 • 問題 ◦ 書き込んだ文字列が謎のデータに化けてる ◦ 実機だけ発生。QEMUでは発生しない。 • 対策 ◦
実機のファームウェアをアップデートしてみよう
HiKey boardをアップデートしよう • HiKey BoardのUEFIファーム導入方法は以下参照 ◦ https://github.com/96boards/documentation/wiki/HiKeyUEFI
ご褒美9 Q. 同じようなファイルのダウンロード先 が複数(Debian, Android, release, snapshot...) あるけど何処のをつかえばいいの? A. UEFI
Shellを使いたいなら uefi-openplatformpkgのlatestをつかえば良い (reference-platformのはちょい使いづらい)
HiKey boardをアップデートしよう • openplatformpkgなどからファイルを取得する ◦ wget https://builds.96boards.org/snapshots/reference-platform/components/uefi-staging/latest/hikey/release/hisi-i dt.py ◦ wget
https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/l-loader.bin ◦ wget https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/fip.bin ◦ wget https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/ptable-linux-4g.img ◦ wget https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/ptable-linux-8g.img ◦ wget https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/nvme.img • boot-fat.uefi.imgは空のFATパーティションを用意する ◦ 既にBOOTパーティションにGRUB等が書き込まれている場合はShellが正しく 起動しなくなる ▪ dd if=/dev/zero of=boot-fat.uefi.img bs=1M count=64 && mkfs.vfat boot-fat.uefi.img
None
HiKey boardをアップデートしよう • openplatformpkgなどからファイルを取得する ◦ wget https://builds.96boards.org/snapshots/reference-platform/components/uefi-staging/latest/hikey/release/hisi-i dt.py ◦ wget
https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/l-loader.bin ◦ wget https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/fip.bin ◦ wget https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/ptable-linux-4g.img ◦ wget https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/ptable-linux-8g.img ◦ wget https://builds.96boards.org/snapshots/hikey/linaro/uefi-openplatformpkg/latest/nvme.img • boot-fat.uefi.imgは空のFATパーティションを用意する ◦ 既にBOOTパーティションにGRUB等が書き込まれている場合はShellが正しく 起動しなくなる ▪ dd if=/dev/zero of=boot-fat.uefi.img bs=1M count=64 && mkfs.vfat boot-fat.uefi.img
HiKey boardをアップデートしよう • その後 ◦ ドキュメントを参照しながらファームを更新する ▪ https://github.com/96boards/documentation/wiki/HiKeyUEFI ◦ UEFI
Shellを使いたいだけならboot-fat.uefi.img の書き込みまでで止めて良 い
正しく 書き込めるようになった
これでログが取れるね!
時間切れ
まとめ • XMODEMはプロトコルは簡単だがUEFIでの実装結構大変 • UEFIではSERIAL_IO_PROTOCOLを使うと バイト単位でシリアル読み書きできる • SERIAL_IO_PROTOCOLでタイムアウト使ったときの 受信データの扱いは不安 •
ptsはtmux等との奪い合いが起こる。仲良くしてほしい。 • UEFIでシリアルを使うアプリのデバッグ大変 • 実機のUEFI実装にはバグがあるかも。 エミュレータでの動作と比較検証大事。