a.out → simh バイナリ変換ツール
#!/usr/bin/ruby
(ARGV[0] && ARGV[1]) || abort("usage: ruby bin2load.rb <a.out> <outfile>")
class LdaFile < File
def write_dat(data)
cksum = 0
data.each do |d|
write [d].pack("C")
cksum += d
end
return cksum
end
def write_sec(saddr, data)
return if data == nil || data.size <= 0
write_sec_h saddr, data
end
def write_sec_h(saddr, data=[])
cksum = write_dat [1,0]
cksum += write_dat [data.size+6].pack("v").unpack("C*")
cksum += write_dat [saddr].pack("v").unpack("C*")
cksum += write_dat data if data.size > 0
cksum = -(cksum & 0xff)
write [cksum].pack("C")
end
end
fin = File.open(ARGV[0],"r")
fout = LdaFile.open(ARGV[1], "w")
magic, text_sz, data_sz, bss_sz, syms_sz, entry_adr, unused, flag =
fin.read(2*8).unpack("S*")
fout.write_sec entry_adr, fin.read(text_sz).unpack("C*")
fout.write_sec entry_adr+text_sz, fin.read(data_sz).unpack("C*")
fout.write_sec entry_adr+text_sz+data_sz, Array.new(bss_sz, 0)
fout.write_sec_h entry_adr
fin.close
fout.close
PDP-11のブートスストラップのお勉強
static const uint16 boot_rom[] = { 0042113, /* "KD" */ 0012706, BOOT_START, /* MOV #boot_start, SP */ 0012700, 0000000, /* MOV #unit, R0 ; unit number */ 0010003, /* MOV R0, R3 */ 0000303, /* SWAB R3 */ 0006303, /* ASL R3 */ 0006303, /* ASL R3 */ 0006303, /* ASL R3 */ 0006303, /* ASL R3 */ 0006303, /* ASL R3 */ 0012701, 0177412, /* MOV #RKDA, R1 ; csr */ 0010311, /* MOV R3, (R1) ; load da */ 0005041, /* CLR -(R1) ; clear ba */ 0012741, 0177000, /* MOV #-256.*2, -(R1) ; load wc */ 0012741, 0000005, /* MOV #READ+GO, -(R1) ; read & go */ 0005002, /* CLR R2 */ 0005003, /* CLR R3 */ 0012704, BOOT_START+020, /* MOV #START+20, R4 */ 0005005, /* CLR R5 */ 0105711, /* TSTB (R1) */ 0100376, /* BPL .-2 */ 0105011, /* CLRB (R1) */ 0005007 /* CLR PC */ };
0012741, 0177000, /* MOV #-256.*2, -(R1) ; load wc */
PDP-11のobjdumpが変だな
UNIX V6関連情報
simhで軽く遊ぶ
sim> set cpu 11/40
Disabling XQ
sim> show cpu
CPU, 11/40, NOFIS, idle disabled, autoconfiguration enabled, 256KB
メモリ256KB。フルフルに積んでるぜ^^、て感じ。
PDP-11のクロス環境とhello world
UNIX V6のコードを読み始めたが、やはりPDP-11上でいろいろ動かして試してみたい。
とりあえず、ネットの情報を集めて PDP-11のクロスコンパイル環境を構築してみた。
動作環境はsimhのPDP-11のエミュレーション環境。
■gccのPDP-11クロス環境 (Mac OS X 10.9.x)
以下のバージョンでビルドに成功した。
環境は基本的に、以前ARM用に作ったものをベースにしている。
http://oodiarydiary.blog.so-net.ne.jp/2014-03-16
gcc-4.8.2 のビルドにはgmp, mpfr, mpcが必要。
すでにインストール済みだったので今回は省けた。
(1) binutils-2.24
展開したディレクトリの下で
$ mkdir build
$ cd build
$ CFLAGS=-Wno-error=deprecated-declarations ../configure --target=pdp11-aout --disable-nls --prefix=/usr/local/pdp11-aout
$ make
$ sudo make install
(2) gcc-4.8.2
展開したディレクトリの下で
$ mkdir build
$ cd build
$ ../configure --target=pdp11-aout --disable-nls --disable-threads --disable-shared --disable-libssp --enable-languages=c --with-gmp=/usr/local/gmp --with-mpfr=/usr/local/mpfr --with-mpc=/usr/local/mpc --prefix=/usr/local/pdp11-aout
$ make
$ sudo make install
■PDP-11上で動かす
以下のサイトの記事をまんま参考にした。
http://ancientbits.blogspot.jp/2012/07/programming-barebones-pdp11.html
上記の記事では、PDP-11用のリンカスクリプトを作って、
最後にa.outファイルを生成するが、このままでは動かない。
ヘッダー部を削るために、この人は独自に作ったbin2loadというコマンドを作った。
今回は手順通りにこれを使ってPDP-11上でhello worldまで動かせた。
GOOD!!
次回は、テストプログラムを作りながら動きを確かめてみよかなと。
UNIX v6のコード読み始める(PDP-11の勉強っすね)
言語仕様の好み
LCDつきマイコンボード(Olimex)
U-BootのMLO部分の処理シーケンスを調べる(BBB)
U-Bootのソースを読んでいるが、#ifdefの嵐で読みづらい・・・。 しかも、信じられないくらいのCPU数、ボード数に対応してるから、今知りたいBBBに関係ないソースがほとんど。 ソースだけの検索結果はごみが多すなので、*.o ファイルからnmでシンボル情報を抜き出して、 関数の呼び出し関係を調べている。(これも面倒・・・) 今知りたいのは起動シーケンスで、大きな処理の順番としては、 MLO -> u-boot.img となっている。が、知りたいのはMLOの部分だけ。 MLOはビルド後に生成される spl/ フォルダーの下に、必要な情報がある。 この中の、u-boot-spl.lds (リンカースクリプト)を読むと、 エントリーポイントが_startで、それが入っている *.o が arch/arm/cpu/armv7/start.o と分かる。 さて、MLO の処理はざっくりいうと、 (1)_start -> (2) lowlevel_init -> (3) _main になっている。 lowlevel_init は、UART、タイマー、クロックその他の初期化をしているようだ。 ここの処理が終わると、シリアルが初期化されて文字が出るようになる。 _main以降は、u-boot.img に橋渡しするための、いろんな部分の初期化をやっているようだが、 今の興味の対象はシリアルの初期化までなので、lowlevel_initの中まで。 流れを簡単にすると以下のとおり。 --------------------------------------------------------------------------------------------- _start: arch/arm/cpu/armv7/start.S -> lowlevel_init: arch/arm/cpu/armv7/lowlevel_init.S -> s_init: arch/arm/cpu/armv7/am33xx/board.c -> save_omap_boot_params() arch/arm/cpu/armv7/omap-common/boot-common.c -> watchdog_disable() arch/arm/cpu/armv7/am33xx/board.c -> timer_init() arch/arm/cpu/armv7/omap-common/timer.c -> set_uart_mux_conf(): board/ti/am335x/board.c -> setup_clocks_for_console() arch/arm/cpu/armv7/am33xx/clock_am33xx.c -> uart_soft_reset() arch/arm/cpu/armv7/am33xx/board.c -> preloader_console_init(): common/spl/spl.c -> serial_init(): drivers/serial/serial.c -> get_current() drivers/serial/serial.c -> default_serial_console(): drivers/serial/serial_ns16550.c -> prcm_init() arch/arm/cpu/armv7/am33xx/clock.c -> set_mux_conf_regs() board/ti/am335x/board.c -> rtc32k_enable() arch/arm/cpu/armv7/am33xx/board.c -> sdram_init() board/ti/am335x/board.c ---------------------------------------------------------------------------------------------