by 登 大遊, 2022/11/18, Quiita 初投稿記事
Microsoft 製 「Windows Dev Kit 2023」(Windows ARM64 開発キット、32 GB LPDDR4x RAM、512GB SSD) というハードウェアは、実に玄人志向であります。素人には、お勧めできません。なぜならば、PC 利用における極めて基本的な操作 (ディスクイメージの dd + gzip 的なバックアップ、復元) をするために必要な ARM64 版 dd ツールが (見渡す限り) 存在しないのです。そのため、自分でプログラミングして作る必要があります。昔 NEC PC-9801 等を購入した人は、自分でプログラミングして何でも作業していましたが、これは、そのような素晴らしい状況の再来であります。そこで、作ったプログラムとその使い方を共有いたします。
概要
Microsoft 製 「Windows Dev Kit 2023」(Windows ARM64 開発キット、32 GB LPDDR4x RAM、512GB SSD) は、素晴らしい製品ですが、内蔵の物理システムディスク (512GB SSD) のイメージのバックアップやリストア (開発のためのイメージング等) が一筋縄ではいきません。最大の問題は、ARM64 版 Windows 上 (PE 環境) で動作する dd ツールが存在しないことです。そこで、仕方が無いので、ARM64 版 Windows 上で動作する dd + gzip ツール (物理ディスクのイメージ化、イメージから物理ディスクへのリストア) を自作しました。自作したツールは、ネイティブの ARM64 バイナリとしてコンパイル可能で、1 つの EXE になっています。これは USB メモリ上で動作します。
解説はよいので早くソフトウェアを落手※ したいという方もいるかも知れません。しかし、自作途中のツールで、バグがあるとデータが消えてしまうという性質のものなので、バイナリは配布せず、ソースコードのみを配布することにしました。ただ、Visual Studio 2022 (フリー版 でもよい) があれば、ビルドをして、EXE を生成することは、それほど難しくないと思います。EXE は ARM64 用のネイティブなものが生成でき (内部的には .NET CLR が動作しているので厳密にいえばネイティブコードではなく Jit である)、Windows PE 環境で快適・高速に動作します。
マウソ・コーナー
※ 👉 「落手」とは、「手に入れる」という意味の日本語である。この日本語は、もちろん、英語の "Download" という単語の元になっている。その他にも、コンピュータ業界には、日本語の単語が英単語の元になっているものは、数多く存在する。たとえば、「秘伝ファイル」 は、もともと日本語版の Windows 発祥の機能であったが、これが 1990 年代に日本のマイクロソフト社 (なお、日本マイクロソフト社の起源は、出版社のアスキーである) によって、英語版 Windows にも移植された。英語版においては、"Hidden file" として、全世界の Windows に普及したのである。他にも著名な例として、「マウソ」 等がある。
早速、落手 (ダウンロード) しよう
ソフトウェアのソースコードは
https://github.com/IPA-CyberLab/IPA-DN-Cores/tree/8efad7b778153691eb745cfa8d1970dd894970b8/
に置いてあります。
これの Cores.NET\Cores.NET-VS2022.sln
を Visual Studio 2022 + .NET 6.0 でビルドします。ビルド方法は
https://github.com/IPA-CyberLab/IPA-DN-Cores/blob/8efad7b778153691eb745cfa8d1970dd894970b8/Cores.NET/Dev.Test/_Memo_BuildBinary.txt
のインチキ・メモの「Win32 - arm64」のとおりです。このテキストメモファイルは、登が自分の開発環境用に書いた個人的なメモのため、怪しい絶対パスが書いてありますが、これらは利用される方々の環境で読み替えてください。ビルドすると、Cores.NET\Dev.Test\bld\win-arm64\Dev.Test\
とかいうヘンなディレクトリに EXE ファイルが出てきます。これを空の 32GB くらいの USB メモリを入れて、Windows PE (Windows のインストール用 ISO イメージからブートした状態で表示される最小構成の Windows) 上で Shift + F10 を押してコマンドプロンプトを表示し、ここから実行することで、イメージの読み書きができます。イメージは、数十 GB のディスクイメージであれば、本ツールは、これを dd + gzip 圧縮することが可能なので、結構な倍率で圧縮でき、USB メモリに格納することができます。これにより、ネットワークを利用せずに快適にディスクイメージのバックアップとリストアが可能です。
このツールを起動すると、怪しげなプロンプトが表示されます。そこで、Cisco ルータのプロンプトのように、
> Raw?
と入れると、RawDiskEnum
、RawDiskBackup
、RawDisRestore
というようなコマンドが列挙され、存在することが分かると思います。ここで、コマンド名を入れて、Cisco ルータのプロンプトのように、
> RawDiskBackup
等と入れると、インチキ・ヘルプが表示されます。インチキ・ヘルプは、とても手抜きですが、それでも、本文書の意味が分かる方であれば十分に使いこなすことができることは間違いありません。
特に用心して利用すべきは、RawDisRestore
コマンドです。ここでリストア先の物理ディスクを指定します。物理ディスクの名前は、RawDiskEnum
コマンドで列挙できます。ここでは、ディスクの識別名と容量が列挙されますので、容量が異なれば、対象となる 1 台のディスクを、ディスクの徒党たちの中から見分けることができます。ただし、同じ容量のディスクが 2 台あるようなけったいな状況では、見分けることができません。この場合、ディスク番号は、diskpart
コマンド内のディスク番号と一致しているはずなので、diskpart の表示 (list 系) コマンドの結果をもとに見分けることになります。大変ですね。
その他にも、本ツールにはインチキ・コマンドが色々実装されていますが、これらは本ドキュメントのスコープ外です。
免責事項
本ツールは、開発途上のものであり、開発の途中状態で、Apache 2.0 ライセンスで公開されるものです。開発者はいかなる保証もいたしません。不具合が存在する可能性があります。不具合が発動したり、使い方を誤ると、ディスク上の情報が削除されてしまうリスクがあります。また、プログラムにミスがあり、データが破損するかも知れません。十分注意して使用してください。本ツールを使用する前に、ディスクのバックアップを行なってください。ただし、本ツールはそもそもディスクのバックアップを行なうためのものなので、これでは、自己矛盾です。そこで、他のツールを用いてバックアップを行なってください。しかし、そもそも他にディスクをバックアップするための ARM64 版 Windows で動作するツールがないので、本ツールを作成した訳ですから、やはり矛盾しているかも知れません。つまり、「使う前にディスクを完全にバックアップせよ」というようなよくある注意事項の類は、今回のように、そのツールが、まさにディスクを完全にバックアップするための唯一のツールである場合には、全く意味がないのであります。
ライセンス条文:
https://github.com/IPA-CyberLab/IPA-DN-Cores/blob/8efad7b778153691eb745cfa8d1970dd894970b8/LICENSE
背景
まず、Microsoft 製 「Windows Dev Kit 2023」 のディスクには、怪しい Windows 11 Pro (Teams とか OneNote 等の不要なものがてんこ盛り) がプリインストールされています。これをきれいにするだけでも一苦労です。
普通、複数台でまともな開発を行なうためには、きれいな開発環境を 1 台作り、そのディスクイメージを複数台の内蔵ディスクにイメージ展開する必要があります。
イメージのキャプチャ/展開を行なうためには、
(1) DVD/USB の Linux からブートして、dd + gzip を用いる。
(2) DVD/USB の Windows PE という特殊な Windows 環境上で (Windows のインストーラを DVD からブートした時に出てくるやつで裏コマンド Shift + F10 を押すと良い)、Windows 版の dd または dd 的なディスクイメージングツールを用いる。
(3) 外付け USB-SSD に Windows 11 ARM64 版を別に入れて、その Windows 上で Windows 版の dd または dd 的なディスクイメージングツールを用いる。
(4) 分解して内蔵 SSD を取り出す
のいずれかの作業が必要です。
(4) は、壊れるおそれがあります。常識的には (1), (2) です。それがダメな場合は (3) です。
問題
そこで、(1) を試そうとしたところ、なんと、この MS 製マシンでは、Ubuntu も Fedora もカーネルがブートできません。ヘンな Exception が出ます。安価なクラウドサーバーとして利用されることを避けるため、ファームウェアの側で、わざと何かやっている気がします。
次に、(2) は、Windows 11 ARM 版の ISO からブートできますが、これは当然 ARM で、かつ最小限の構成であり x86 エミュレーションも動作しないので、既存の Win32 版の dd ツールが動作しません。MS Sysinternals の disk2vhd は ARM 版があるので動きますが、これはパーティションごとのキャプチャは可能ですが、dd のように、ディスク全体のキャプチャができません。また、リストア機能もありません。
そして、(3) は、外付け USB-SSD のデバイスは Windows カーネルがブートした後に認識されるので、ブートの最中は認識されません。x64 版 Windows であればカーネルそのものに最小限の USB ドライバが入っているのでブートするのですが、ARM 版ではブートしないようです。そのため、外付け USB-SSD からは Windows カーネルは起動できませんでした。
(1), (3) がどうやっても起動不能なので、(2) 上で、ARM64 の Windows 版 dd 相当ツールがどうしても必要です。しかし、一応調べてみましたが、インターネット上には存在しないようです。
解決策
これでは、手詰まりです。仕方が無いので、写真のように、ARM64 版の Windows 版 dd 相当ツールを自作しました。ソースコードは上記 URL に掲載しています。これは、物理ディスクをイメージ化しますが、その際に透過的に gzip 圧縮も行ないます (圧縮をしないこともできます。コマンドラインオプションで指定します)。また、イメージ化されて作成された img.gz 的なファイルを物理ディスクにリストアするととき、gzip 圧縮を自動的に展開します。リストア時は、指定されたソースイメージファイルの最初の数バイトを読んで、gzip のヘッダがあるか否かを判定し、gzip 形式であれば自動的に展開するようにしています。このあたりにバグが潜んでいて、データが台なしになってしまう可能性もあります。ただ、自分で自分のマシンで試してみたところ、一応壊れずに動作しているようです。
この ARM64 用 dd + gzip 自作ツールでバックアップ/リストアをやってみたところ、無事、3 台のマシンを快適に構築することができました。
その他
- 本 dd + gzip ツールは、Linux 等における dd + gzip の生成結果と一応互換性があると思います。
- バックアップコマンド、リストアコマンドの両方で、
/truncate:xxxxxxxx
オプションが利用可能です。xxxxxxxx のところに数値を指定すると、ディスクサイズやイメージサイズがより大きい場合でも、指定されたバイト数分までしかコピーされません。これは、たとえば 10TB くらいのディスクの先頭 100GB くらいに意味のあるパーティションデータが入っており、残り 900GB をコピーするのは時間・容量の無駄である、というような場合におおいに有益です。 - Windows PE 環境だけでなく、実 Windows 環境でも、本 dd + gzip ツールは利用可能です。
- Windows カーネルの起動時に、すでに物理ディスクのパーティションがカーネルによって認識され、マウントされている場合は、マウントを解除するまで、その物理ディスクへの書き込みはできません (Windows カーネルによって、不整合を防ぐため、拒否されます)。そこで、リストア先のディスクに何か入っている場合は、
diskpart
→select disk
→clean
でそのディスク (の先頭のヘッダ) をゼロクリアし、同時に Windows カーネル的に強制アンマウントされた状態にすることが有益です。この重要な diskpart の clean コマンドを知らないと、いつまでたっても、物理ディスクへの書き込みが出来ずに夕方になってしまうことになるのです。※ select disk で異なるディスクを指定しないように十分注意すること。 - 本ツールは、上記のソースコードから、x64 版 Windows 用バイナリも作成可能である。これは通常の x64 版 Windows (Windows PE 環境も含める) で動作する。
最後に
この文章は、単なる雑多なメモであり、何も考えずに適当に書いて全く校正せずにアップロードしたものであるため、構成は、なっていない。
糸冬了!!