こんにちは、ユーマと申します。
リンカスクリプトの実験をしていたところ、VMA(仮想アドレス)とLMA(物理アドレス)について混乱したので質問させていただきました。
まず確認なのですが、
VMA = プログラムが実際にメモリにロードされた時に動作するはずであるアドレス
LMA = プログラムが実際にロードされるアドレス
という認識でOKでしょうか?
つまり、僕はVMA = リンカに対して指定するアドレスでLMA = ローダに対して指定するアドレスだと思っています。
組み込みOSなどでは、ROMにプログラムを書き込んでおいて(このアドレスがLMA)、プログラム実行開始直後にRAMにコピーするという処理が行われているようなので(このアドレスがVMA)、僕の認識と一致すると思います
ですが、なんだかもやもやします。
VMAとLMAを分ける理由というのはなんなのでしょうか?
二つがなければ困る理由はあると思うのですが、理解が浅くいまいちピンときません。
また、最近Ubuntuの上でglibcに頼らずにCプログラミングしています。
その時にリンカスクリプトも自作していたのですが、その時にもVMAとLMAに対する不思議な現象(?)が起きました。
.text 0x8048000 : 0x8000000 { *(.text) } みたいな感じに指定してプログラムを実行していたのですが、実際に動作しているプログラムは8048000台のアドレスでした。
(実行しているアドレスを調べるために次のような関数をmain関数の中で使いました。返り値に呼び出し元のアドレスが返ります。)
この指定ではVMA = 0x8048000、LMA = 0x8000000になるはずで、僕の予想は0x8000000に近いものになると思っていました。(LMAはローダがプログラムを読み込む番地のはずだから)
ですが、実際にプログラムが読み込まれているのは0x8048000。
LMAを基準にローダがプログラムをメモリに読み込んでいないような気がします。
VMAを基準にしてローダがプログラムを読み込むなら、そもそもLMAなどはいらないのでは?と思ってしまいます。
ここで指定しているVMA・LMAとは何なのでしょうか?
なにかとんでもない勘違いをしているのは決定的なのですが、自分ではよくわかりません。
僕がよくわかっていないので文章も読みずらいと思いますが、よろしくお願いいたします。
VMAとLMAについて
Re: VMAとLMAについて
「VMA LMA」でググった結果、
組み込みシステムにおけるアドレスの考え方 (VMA, LMAについて) - FPGA開発日記
などいろいろ出てきました。
このサイトの情報と照らし合わせて考えると、
ここでの「ローダがプログラムを読み込む」というのは、
CPUによるプログラムの実行開始前に用いる、ローダ用のアドレス空間を用いて読み込むことであり、
プログラムから取得できるアドレスはCPUによるプログラムの実行中に用いるアドレス空間、
すなわちVMAのアドレス空間が用いられると考えられます。
また、これは予想ですが、
リンカスクリプトはLMAの指定が必要な組み込みプログラムの開発でも使えるようにLMAを指定する機能があるが、
パソコンのOS上ではローダがその時の空きメモリの位置などに基づいてプログラムをメモリ上のどこに置くかを
自動的に決定するため、LMAの指定は無視される、と考えられます。
なお、プログラムをメモリ上のどこに置いても、
x86などではCPUの機能によりプログラムから見えるアドレス(仮想アドレス)を同じにすることができます。
組み込みシステムにおけるアドレスの考え方 (VMA, LMAについて) - FPGA開発日記
などいろいろ出てきました。
このサイトの情報と照らし合わせて考えると、
ここでの「ローダがプログラムを読み込む」というのは、
CPUによるプログラムの実行開始前に用いる、ローダ用のアドレス空間を用いて読み込むことであり、
プログラムから取得できるアドレスはCPUによるプログラムの実行中に用いるアドレス空間、
すなわちVMAのアドレス空間が用いられると考えられます。
また、これは予想ですが、
リンカスクリプトはLMAの指定が必要な組み込みプログラムの開発でも使えるようにLMAを指定する機能があるが、
パソコンのOS上ではローダがその時の空きメモリの位置などに基づいてプログラムをメモリ上のどこに置くかを
自動的に決定するため、LMAの指定は無視される、と考えられます。
なお、プログラムをメモリ上のどこに置いても、
x86などではCPUの機能によりプログラムから見えるアドレス(仮想アドレス)を同じにすることができます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: VMAとLMAについて
すごくわかりやすい回答ありがとうございます。
「LMAは実行開始前に用いるローダ用のアドレス空間」「VMAはプログラムから取得できる実行中のアドレス空間」と理解すると、今までの謎が解けました
また、一般的なOS上で動くアプリケーションなどはLMAは基本的に使われないが、組み込みOSなどでは使われることが多いということですね!たしかにLMAが無視されていると考えると辻褄が合いますね...
長い間の謎が解けたのでスッキリしております。
ありがとうございました!
「LMAは実行開始前に用いるローダ用のアドレス空間」「VMAはプログラムから取得できる実行中のアドレス空間」と理解すると、今までの謎が解けました
また、一般的なOS上で動くアプリケーションなどはLMAは基本的に使われないが、組み込みOSなどでは使われることが多いということですね!たしかにLMAが無視されていると考えると辻褄が合いますね...
長い間の謎が解けたのでスッキリしております。
ありがとうございました!