HobbyOSs / opennask

nask clone assembly, it can boot tiny OS with Linux
https://github.com/HobbyOSs/opennask/wiki/%E5%8B%95%E4%BD%9C%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF
GNU General Public License v3.0
20 stars 3 forks source link

リンカーを使用したビルド環境の構築 #9

Closed hangingman closed 7 years ago

hangingman commented 7 years ago

ここを参考に、cmakeを使用したnask形式ファイルとC言語ファイルのリンクを行う。

hangingman commented 7 years ago
OSNAME=os

ASRC=./src/asm
CSRC=./src/c
OBJ=./obj
LS=./ls

IMG=$(OSNAME).img
OSSYS=$(OBJ)/$(OSNAME).sys
IPL=$(OBJ)/ipl.bin

BINOPT=-nostdlib -Wl,--oformat=binary
QEMUOPT=-m 32 -localtime -vga std -fda

$(IMG) : $(OSSYS) $(IPL)
    mformat -f 1440 -C -B $(IPL) -i $(IMG) ::
    mcopy $(OSSYS) -i $(IMG) ::

$(OSSYS) : $(ASRC)/head.s $(ASRC)/func.s $(CSRC)/bootpack.c
    gcc $(ASRC)/head.s -nostdlib -T$(LS)/head.ls -o $(OBJ)/head.bin
    gcc $(CSRC)/*.c $(BINOPT) -c -o $(OBJ)/boot.o
    as $(ASRC)/func.s -o $(OBJ)/func.o
    ld -o $(OBJ)/boot.bin -e Main --oformat=binary $(OBJ)/boot.o $(OBJ)/func.o
    cat $(OBJ)/head.bin $(OBJ)/boot.bin > $(OSSYS)

$(IPL) : $(ASRC)/ipl.s
    gcc $(ASRC)/ipl.s -nostdlib -T$(LS)/ipl.ls -o $(IPL)

run        : $(IMG)
    qemu $(QEMUOPT) $(IMG)
debug    : $(IMG)
    qemu -s -S $(QEMUOPT) $(IMG) -redir tcp:5555:127.0.0.1:1234 &
img        :;    make $(IMG)
clean    :;    rm $(OBJ)/*
set(QEMU "qemu-system-i386" CACHE INTERNAL "")
set(QEMUOPT "-m" "32" "-localtime" "-vga" "std" "-fda" CACHE INTERNAL "")
set(BINOPT "-nostdlib" "-Wl,--oformat=binary" CACHE INTERNAL "")
# 各日付のディレクトリに1つos.imgを作る
set(NASK ${root_BINARY_DIR}/src/opennask)
set(03_day_harib00i_OS ${root_BINARY_DIR}/projects/03_day/harib00i/os.img)
set(03_day_harib00i_SYS ${root_BINARY_DIR}/projects/03_day/harib00i/os.sys)
set(03_day_harib00i_IPLB ${root_BINARY_DIR}/projects/03_day/harib00i/ipl.bin)
set(03_day_harib00i_IPLS ${root_SOURCE_DIR}/projects/03_day/harib00i/ipl10.nas)
set(03_day_harib00i_HEADB ${root_BINARY_DIR}/projects/03_day/harib00i/asmhead.bin)
set(03_day_harib00i_HEADS ${root_SOURCE_DIR}/projects/03_day/harib00i/asmhead.nas)
set(03_day_harib00i_BOOTB ${root_BINARY_DIR}/projects/03_day/harib00i/boot.bin)
set(03_day_harib00i_CCO ${root_BINARY_DIR}/projects/03_day/harib00i/boot.o)
set(03_day_harib00i_CCS ${root_SOURCE_DIR}/projects/03_day/harib00i/*.c)

add_custom_target(03_day_harib00i_run
  COMMAND ${QEMU} ${QEMUOPT} ${03_day_harib00i_OS}
)
add_custom_target(03_day_harib00i_debug
  COMMAND ${QEMU} -s -S ${QEMUOPT} ${03_day_harib00i_OS} -redir tcp:5555:127.0.0.1:1234 &
)
add_custom_target(03_day_harib00i_ipl
  COMMAND ${NASK} ${03_day_harib00i_IPLS} ${03_day_harib00i_IPLB}
)
add_custom_target(03_day_harib00i_sys
  COMMAND ${NASK} ${03_day_harib00i_HEADS} ${03_day_harib00i_HEADB}
  COMMAND gcc ${03_day_harib00i_CCS} ${BINOPT} -c -o ${03_day_harib00i_CCO}
  COMMAND ld -o ${03_day_harib00i_BOOTB} -e _HariMain ${03_day_harib00i_CCO} ${03_day_harib00i_FUNCO}
  COMMAND cat ${03_day_harib00i_HEADB} ${03_day_harib00i_BOOTB} > ${03_day_harib00i_SYS}
)
# need to install mtools
add_custom_target(03_day_harib00i_img
  COMMAND mformat -f 1440 -C -B ${03_day_harib00i_IPLB} -i ${03_day_harib00i_OS}
  COMMAND mcopy ${03_day_harib00i_SYS} -i ${03_day_harib00i_OS}
)
hangingman commented 7 years ago

思うに、最低限必要なステートメントは、以下の2つ

以下は、引数で与えられるように思う

/*入力オブジェクトファイル
入力ファイルを増やすときはここに追加*/
INPUT(bootpack.o nasmfunc.o)

/*出力オブジェクトファイル*/
OUTPUT(bootpack.bim)

/*エントリーポイントファイル
これを設定するとstartupルーチンが.textセクションの先頭にくる*/
STARTUP(startup.o)

/*出力フォーマット
"binary"でtext,data,bssだけのシンプルな構成になる。*/
OUTPUT_FORMAT(binary)

/*セクション*/
SECTIONS
{
  /*textセクションのメモリ上での開始位置*/
  . = 0x280000;
  .text : 
  {
    /*textセクションを全部*/
    *(.text);
    /*textのサイズをシンボルに代入*/
    _b_tsize = SIZEOF(.text);
  }

  /*dataセクションのメモリ上での開始位置*/
  .data 0x310000 :

  /*dataセクションのファイル上の開始位置*/
  AT ( ADDR(.text) + SIZEOF(.text))
  {
    /*.dataのスタートアドレスをシンボルに代入*/
    _b_dstart = SIZEOF(.text) ;
    /*.dataセクションを全部*/
    *(.data);
    /*.dataのサイズをシンボルに代入*/
    _b_dsize = SIZEOF(.data);
  }

  /*bssセクションのメモリ上での開始位置
  ディフォルトではdataの終端から*/
  .bss ( 0x310000 + SIZEOF (.data) ) :
  {
    *(.bss);
    _b_bsssize = SIZEOF(.bss);
  }
}

/*
NOTE
リンカスクリプト内のシンボル
各シンボルはstartup.oに参照される。
  _b_tsize  .textセクションのサイズ
  _b_dstart .dataセクションの開始位置
  _b_dsize  .dataセクションのサイズ
  _b_bsssize    .bssセクションのサイズ
*bimヘッダの定義ではbssセクションのサイズは64bitであるが、
quad命令がいつもエラーるので32bitにしてむりやり64bit化している。
もしもbssセクションのサイズが32bitを超える仕様のモノを作るとしたら
再考の余地がある(そんなデカい必要は無いと思うが)
*/
hangingman commented 7 years ago

Macのldはリンカスクリプトが使用できない。やっぱりMacはクソ。

hangingman commented 7 years ago

ld の正しいオプションは -T でした

hangingman commented 7 years ago

Windows上の検証によると、実際qemuを動かして変化が現れるのはharib01aからになる。 3日目 harib00iのコンパイル

hangingman commented 7 years ago

リンカスクリプトですべて解決済み! NKT

(N)長く(K)苦しい(T)戦いだった……