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ビットモードへの道は次回へつづく