ステップバイステップで教える:Qemuを使用してARMシステムをシミュレートする方法


これはダオ兄弟の011オリジナルです

序文

少し前に、仕事の必要性のために、私はARMシミュレーターについていくつかの調査をしました。調査の目的は、プロジェクトに関わっている人が多いため、ARM開発委員会の人員であればリソースが比較的少なく、代わりにシミュレーターを利用できることが望まれる

調査中、私は情報の確認、テスト、検証に多くの時間を費やしました。実際の検証中に、現象が発見されました。多くの記事は簡単または詳細な操作手順を示していますが、ほとんどの記事は操作の背景と各ソフトウェアのバージョンを明確に記述していないため、記事全体を読む必要があります。 、すべての操作手順を実行すると、作成者が何を表現したいのか、操作の目的は何かを理解できます

私の意見では、どの記事でも、最初に読者にこの記事を読みたい理由、またはこの記事を読むことでどのような利益得られるかを知らせる必要があります

操作性の高い記事の場合は、作業プラットフォームの背景、達成すべき目標全体的な手順を明確に説明する必要がありますこのようにして初めて、記事を読んだ人は、まず頭の中でマクロの枠組みを確立し、次にその枠組みを理解して実際の運用に取り掛かることで、理解しやすくなります。

もちろん、学習習慣や読書習慣は人それぞれです。上記は私の個人的な気持ちですが、混乱しないように、もっと整理された記事が好きです。

Qemuのトピックに戻ると、この記事は主に、以下を含む調査結果を整理して要約することを目的としています。

なぜARMシミュレーションシステムが必要なのですか?Qemu
とは
何ですか?Qemuはができますか?または、それは何に適していますか?
Ubuntu 16.04システムで、Qemuを使用してARM仮想マシンを構築する手順は何ですか?
HelloWorldプログラムを作成し、仮想マシンに配置して実行します。

なぜARMアナログシステムが必要なのですか

ARMプラットフォームでのソフトウェア開発作業は、次の2つのカテゴリに分類できます。

アプリケーション開発
システム開発(カーネル、ファイルシステム、ドライバー)

アプリケーション開発

組み込みプロジェクトを開発するときは、通常、最初にx86プラットフォームでほとんどの関数を開発し、次にそれらをクロスコンパイルして、ARMプラットフォームで実行可能プログラムまたはライブラリファイルを取得します。次に、これらのファイルをARMボードにコピーしscpコマンドまたはNFSリモートマウントを使用して実行します

一般的に、アプリケーションプログラムは、ハードウェア製品のさまざまなリソースと周辺機器を使用して、データ収集、外部デバイスの制御、ネットワーク送信などの特定の機能を完了します。主な機能は、さまざまな外部デバイスと対話することです。

システム開発(BSP)

システム開発の最終的な目標は、システムブートローダーブートローダー、カーネルカーネル、ファイルシステムrootfs、システム内のすべてのデバイスのドライバーなど、アプリケーションを実行するための基本的な実行環境を準備することです実際のプロジェクト開発では、システム開発が難しく、開発が完了すると、基本的にボードの変更が難しく、コードのライフサイクルが長くなります。

上記の2つの分類は、主に開発作業の内容の観点から分類されます。見ることができるように:

アプリケーション開発:柔軟性の向上、要件の変更の増加(製品マネージャーまたはプロジェクトマネージャーは、要件を変更することがよくあります)。
システムソフトウェア開発:需要はより安定しており、多くのコードが公式に提供されているかオープンソースであり、作業内容はカスタマイズと調整です。

システムソフトウェアの開発では、ブートローダーやカーネルを毎回コンパイルすると、ARM開発ボードで検証されるので面倒です。ARMシミュレーションシステムを使用してx86で直接シミュレーションできる場合は、作業効率が大幅に向上します。

Qemuとは何ですか?

Qemuはオープンソースでホストされる仮想マシンであり、ほとんどすべてのハードウェアデバイスをシミュレートできる純粋なソフトウェアを介して仮想シミュレーターを実装します例:QemuはARMシステム(CPU、メモリ、IOデバイスなど)をシミュレートできます。次に、このシミュレーションレイヤーで、ARM仮想マシンを実行できます。このARM仮想マシンは、ハードウェアを処理していると見なしますが、実際には上記のハードウェアはQemuによってシミュレートされています

Qemuが純粋なソフトウェアで実装されているという理由だけで、すべての命令は変換を経る必要があるため、パフォーマンスは非常に低くなります。したがって、実稼働環境では、KVMはハードウェア支援の仮想化テクノロジーであり、主に厄介なCPUとメモリの仮想化を担当し、Qemuは担当するため、ほとんどのプラクティスはKVMと協力して仮想化作業を完了することです。 I / O仮想化。、2つは互いに協力して、独自の利点を発揮し、互いに補完し合います。この部分は焦点ではないので、詳細には紹介しません。

Qemuの2つのモード

Qemuには2つの実行モードがあります

  1. ユーザーモード:動的コード変換メカニズムを使用して、さまざまなホストアーキテクチャのコードを実行します。例:x86プラットフォームでARMコードの実行をシミュレートします。つまり、ARM命令を記述し、シミュレーター全体に渡します。命令全体がx86プラットフォームの命令に変換され、x86CPUで実行されます。

  1. システムモード:コンピューターシステム全体をシミュレートし、他のVMM(Xen、KVM)を使用して、ハードウェアが提供する仮想化サポートを使用して、ホストのパフォーマンスに近いフル機能の仮想マシンを作成します。

Qemuは何ができますか?または何に適していますか?

Qemuは純粋なソフトウェアシミュレーションを使用するため、その強みは、次のような外部の特定のハードウェアデバイスを含まないシナリオをシミュレートすることです

ブートローダーをカスタマイズする方法を学びたい
、Armシステムでファイルシステムを切り取り、ファイルシステム
マウントする方法を学びたい、Linuxカーネルを構成および調整する方法を体験し
たい、デバイスを学びたいLinuxシステムのツリー;

これらのシナリオでは、Qemuを使用してARMシステムをシミュレートするのが非常に適しています。

Ubuntu 16.04システムでは、Qemuを使用してARM仮想マシンを構築します

Qemu仮想マシンを使用するためのいくつかのオプション

Qemuを使用してARM仮想マシンを実行するには、次の2つのオプションがあります

  1. 簡単な方法:他の人(カーネルとルートファイルシステムを含む)によってコンパイルされたイメージファイルを直接ダウンロードして、直接実行します。


    欠点は、誰かがコンパイルしたものがあなたのニーズに合わない可能性があり、カスタマイズできないことです。
  2. 複雑な方法:カーネルコードとルートファイルシステムコード(例:busybox)を自分でダウンロードし、コンパイルします。


    利点は、実際のニーズに応じてカーネルとルートファイルシステムのモデルを調整できることです。

2番目の複合モードでは、2つのオプションがあります

2-1。カーネルコードとルートファイルシステムコードはすべて手動でコンパイルされ、最後にこれらのコンパイルされた結果はフォルダに手動で編成されて独自のルートディレクトリを形成します
。2-2。buildrootのフレームワーク全体を使用すると、手動で構成する必要があります(たとえば、マシン上のクロスコンパイラの場所、出力パス、システムの切断)。その後、ワンクリックでシステム全体をコンパイルでき、マシンに直接書き込むことができます。 !!

上記のいくつかの動作モードの選択は、実際のニーズに応じて選択できます。システム構築のプロセス全体にすでに精通している場合は、buildrootツールを使用します。システムの構築をより完全学びたい場合は、手動でコンパイルして段階的に操作し、数回練習します。大きくなる牛です。

以下、実際の操作2-2通りに行います。すべての命令部分について、スクリーンショットを撮らずにコードを直接貼り付けるので、コピーに便利です。

テストプラットフォーム

私の作業用コンピューターはWin10で、VirtualBox 、64ビットシステムを介してUbuntu16.04仮想マシンをインストールしました

次の操作は、Ubuntu 16.04仮想マシンで正常にコンパイルできます。もちろん、いくつかの基本的なツール(たとえば、build-essential、make、およびその他の基本的なツールについてはここでは詳しく説明しません)。

クロスコンパイラをインストールする

x86プラットフォームでコンパイルしており、実行中のプラットフォームはARMシステムであるため、クロスコンパイラの役割を詳細に説明する必要はありません。これら2つのプラットフォームの命令セットは異なるため、クロスコンパイルが必要です。 ARMシステムで実行を取得します。のプログラム。

sudo apt-get install gcc-arm-linux-gnueabi 

インストール結果を確認する

dpkg -l gcc-arm-linux-gnueabi 

表示は次のとおりです。

一部の記事では、クロスコンパイラを自分でダウンロードしてから、環境変数を手動で設定することを推奨しています。手動でダウンロードしたクロスコンパイルツールチェーンは、カーネルのコンパイル時にエラーを報告したため、apt-getを使用して直接インストールすることをお勧めします

カーネルカーネルをコンパイルします

カーネルカーネルの役割も自明です。これはWindowsオペレーティングシステムと同等です。このオペレーティングシステムがなければ、ハードウェアは鉄くずの山になります。システムが起動すると、カーネルがメモリにロードされ、カーネルのエントリアドレスから実行されます。

  1. カーネル
    バージョンをダウンロードします:linux-4.14.212.tar。
    記事の最後に、すべてのソフトウェアパッケージのダウンロードアドレスをリストします。

  2. 既製vexpress開発ボードの使用設定ファイルを

make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_defconfig 

この操作により、vexpress_defconfigが構成ファイルとして.configとして保存されます。カーネルをコンパイルするときは、この構成の構成に従ってコンパイルしてください。

カーネルを調整する必要がある場合は、以下を実行します。

make menuconfig

実際のニーズに応じてカーネルをカスタマイズします。例:ネットワークとNFSを構成し、システムの起動時にホストにディレクトリを自動的にマウントできます。

  1. カーネルをコンパイルします
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm

カーネルファイルarch / arm / boot / zImageがコンパイルされ、Qemuの起動時にこのイメージファイルを指定する必要があります。

ルートファイルシステムを作成します

カーネルが起動し、最終ステップに到達したら、ルートファイルシステムマウントしてから、ファイルシステムで指定されている実行プログラム(例:/etc/rc.local)を実行する必要があります。

ファイルシステムがない場合、カーネルは実行の最後にパニック...というプロンプトを表示します

  1. busyboxをダウンロード

    バージョン:busybox-1.20.2.tar.bz2。

  2. rootfsルートディレクトリを作成します

mkdir -p rootfs/{dev,etc/init.d,lib} 
  1. busybox-1.20.2のファイルをrootfsのルートディレクトリにコピーします。主にいくつかの基本的なコマンドです。
cp busybox-1.20.2/_install/* -r rootfs/ 
  1. クロスコンパイルツールチェーンのライブラリファイルをrootfsのルートディレクトリのlibフォルダーにコピーします
sudo cp -P /usr/arm-linux-gnueabi/lib/* rootfs/lib/ 
  1. ルートファイルシステムミラーの作成
    ルートファイルシステムミラーは、上記のrootfsのルートディレクトリにあるすべてのファイルをこのハードディスクにコピーするハードディスクと同等です。

(1)512Mのディスクイメージを生成する

qemu-img create -f raw disk.img 512M 

(2)ディスクイメージをext4ファイルシステムにフォーマットします

mkfs -t ext4 ./disk.img 

(3)rootfsのルートディレクトリにあるすべてのファイルをディスクイメージにコピーします。
操作手順は次のとおりですマウントポイントの作成-マウント-ファイルのコピー-アンマウント。

mkdir tmpfs 
sudo mount -o loop ./disk.img tmpfs/  
sudo cp -r rootfs/* tmpfs/
sudo umount tmpfs 

(4)fileコマンドを使用して確認します

file disk.img

Qemuを使用してARM仮想マシンを起動します

1.仮想マシンを起動します

このコマンドは少し長いので、テスト時に直接コピーして貼り付けることをお勧めします。

qemu-system-arm -M vexpress-a9 -m 512M -kernel ./linux-4.14.212/arch/arm/boot/zImage -dtb  ./linux-4.14.212/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd disk.img

2.仮想マシンを停止する
Ubuntuの別のターミナルウィンドウで、killallコマンドを使用して仮想マシンを停止します。

killall qemu-system-arm

もちろん、psコマンドを使用してqemu-system-armのプロセス番号を検索し、kill-9を使用して仮想マシンを停止することもできます。

HelloWorldアプリケーションをテストする

  1. Ubuntuの任意のディレクトリに、HelloWorld実行可能プログラムhello.cを記述します。
#include <stdio.h> 
int main() 
{     
    printf("HelloWorld! \n");
    return 0; 
} 
  1. hello.cをクロスコンパイルして、実行可能プログラムhelloを取得します。
arm-linux-gnueabi-gcc hello.c -o hello 

fileコマンドを使用してhelloプログラムを確認します。

file hello

  1. killコマンドを使用して仮想マシンを停止します。

  2. hello実行可能プログラムをディスクイメージdisk.imgに
    コピーします操作手順は次のとおりです。マウント-ファイルのコピー-アンインストール。

sudo mount -o loop ./disk.img tmpfs/  
cp hello tmpfs/ 
sudo umount tmpfs 
  1. helloプログラム
    実行し、仮想マシンを再起動します。このとき、ルートディレクトリの下にhelloファイルが表示され、直接実行して出力結果を確認できます。

総括する

上記の操作手順では、アプリケーションを起動する前に、ARMシステムに必要なすべてのプログラムを手動でコンパイルして操作します読んだ後はわかりやすく、自分の手で操作するとさらに印象的です。

ここでの操作の一部をさらに深める必要があります。たとえば、システムの起動後、ホストマシン(Ubuntuシステム)のフォルダが自動的にマウントされるため、helloなどの実行可能プログラムをマウントディレクトリにコピーできます。その後、ARMシステムで直接実行され、次の一連の操作を実行する必要はありません(仮想マシンの停止-ディスクイメージのマウント-ファイルのコピー-アンインストール-仮想マシンの起動)。

最後に、この要約があなたに少しの利益と改善をもたらすことを願っています!

ソフトウェアのダウンロードアドレス

  1. linux-4.14.212.tar.xz
    リンク:https
    ://pan.baidu.com/s/1d8RxjMkYQhPtbZgiybD8Gw抽出コード:b6ft

  2. busybox-1.20.2.tar.bz2
    リンク:https
    ://pan.baidu.com/s/1oPeH7juEWuFR6y1Qpna_BA抽出コード:9kh6


【原文】

記事が良いと思う場合は、転送して友達と共有してください。

組み込み開発における10年以上のプロジェクトの実際の戦闘経験要約して共有します。あなたが失望することはないと信じています!

写真を長押しすると、各記事に乾物があります。

転載:転載へようこそが、著者の同意なしに、この声明を保持し、元のリンクを記事に記載する必要があります。




推奨読書

[1] gdbの基本的なデバッグ原理は非常に単純です
[2]プロデューサーモードとコンシューマーモードのダブルバッファリングテクノロジー
[3]詳細なLUAスクリプト言語。デバッグの原理を完全に理解できます
[4]段階的な分析-Cオブジェクト指向プログラミングでそれを実装する方法

おすすめ

転載: blog.csdn.net/u012296253/article/details/111908443