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
520
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.7k
probe-rsの紹介と最近の貢献紹介/CELF-02-03
tnishinaga
1
350
SecurityCamp2023基板作るコース講義資料/Security Camp 2023 Lecture Materials
tnishinaga
8
2.5k
RP2040のPIOを使う話/KernelVM Hokuriku 6
tnishinaga
3
1.2k
JTAGでArmプロセッサをデバッグする方法のつづき/KernelVM_Tokyo16
tnishinaga
0
380
CMSIS-DAPの概要と使い方/KernelVM Online5
tnishinaga
0
1.7k
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
Mermaid x AST x 生成AI = コードとドキュメントの完全同期への道
shibuyamizuho
0
160
責務を分離するための例外設計 - PHPカンファレンス 2024
kajitack
3
690
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
220
バグを見つけた?それAppleに直してもらおう!
uetyo
0
180
Security_for_introducing_eBPF
kentatada
0
110
CSC305 Lecture 26
javiergs
PRO
0
140
HTTP compression in PHP and Symfony apps
dunglas
2
1.7k
Cloudflare MCP ServerでClaude Desktop からWeb APIを構築
kutakutat
1
540
創造的活動から切り拓く新たなキャリア 好きから始めてみる夜勤オペレーターからSREへの転身
yjszk
1
130
KubeCon + CloudNativeCon NA 2024 Overviewat Kubernetes Meetup Tokyo #68 / amsy810_k8sjp68
masayaaoyama
0
250
Refactor your code - refactor yourself
xosofox
1
260
PHPUnitしか使ってこなかった 一般PHPerがPestに乗り換えた実録
mashirou1234
0
180
Featured
See All Featured
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
365
25k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Designing for Performance
lara
604
68k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
Writing Fast Ruby
sferik
628
61k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
170
Automating Front-end Workflow
addyosmani
1366
200k
Embracing the Ebb and Flow
colly
84
4.5k
Unsuck your backbone
ammeep
669
57k
Practical Orchestrator
shlominoach
186
10k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
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実装にはバグがあるかも。 エミュレータでの動作と比較検証大事。