3日目 その2
32ビットモードへの移行 その1
asmhead.Sを書きますがOS自作本のasmhead.nasとほとんど同じです。
違うのはbootpackの転送元アドレスです。
asmhead.nasではファイルの最後にbootpackラベルがありbootpack.hrbがそのラベルの直後に連結されるので転送元アドレスとしてbootpackラベルが指定されています。
asmhead.Sではbootpackはasmheadを含む1セクタ後(今はたまたまasmheadが1セクタでおさまってるので)に書き込まれているので、0x8200+ 0x200で0x8400を転送元アドレスとしています。
bootpack.cはOS自作本をそのまま流用。
nasfunc.nasに対してasmfunc.Sを作成します。
.file "asmfunc.S" .code32 .globl io_hlt io_hlt: hlt ret
次にbootpack.cのリンカースクリプトです。
セグメントを考えるとCSはベースアドレスが0x280000でDSはベースアドレスが0x0になっているので、スクリプトのSECTION部は、
SECTIONS { .text 0x00: { *(.text) } /* Executable codes */ .data 0x280000 + SIZEOF(.text): { *(.data) } /* Initialized data */ .rodata : { *(.rodata*) } /* Constant data (R/O) */ .bss : { *(.bss) } /* Uninitialized data */ }
でOKのように見えますが、これではダメです。というのもこのスクリプトでリンクすると.data以降が実際に0x280000以降にある巨大なバイナリができてしまいます。仮にこの(FDサイズを越える)バイナリが読み込めたとしても.dataセクションは0x280000 + 0x280000 + SIZEOF(.text)の位置に読み込まれてしまうため使いものになりません。
そこでload Address(LMA)を指定するAT属性を使用して次のように書きます
SECTIONS { .text 0x00: { *(.text) } /* Executable codes */ .data 0x280000 + SIZEOF(.text): AT ( ADDR (.text) + SIZEOF (.text) ) { *(.data) } /* Initialized data */ .rodata : AT ( ADDR (.text) + SIZEOF (.text) + SIZEOF (.data) ) { *(.rodata*) } /* Constant data (R/O) */ .bss : AT ( ADDR (.text) + SIZEOF (.text) + SIZEOF (.data) + SIZEOF(.rodata)) { *(.bss) } /* Uninitialized data */ }
これで.data以降のセクションは、アドレス解決に関しては0x280000ベースでおこなわれ、出力ファイル内の位置は.textの直後ということになり、正しくリンクされました。
32ビットモードへの道は次回へつづく