When doing V6 code reading, I think it would be efficient to know how to use the pdp11 emulator simh and the cross-compiler, so here’s a summary. What we’re doing is:

  1. Use a cross-compiler to create an a.out-pdp11 format executable file for pdp11.
  2. Run it with simh to check the memory and register contents. (Boot by assigning the executable file to simh’s virtual disk.)

Note that pdp11 is basically written in octal.

Cross-compiler

I used the following binutils and gcc. Here’s the installation procedure for OS X.

  • binutils 2.23
  • gcc 3.4.6
$ wget http://ftp.gnu.org/gnu/binutils/binutils-2.23.tar.gz
$ tar xvf binutils-2.23.tar.gz
$ cd binuitls-2.23
$ ./configure --target=pdp11-aout --prefix=/hogehoge
$ make
$ make install
$ brew install libmpc
$ brew install gmp
$ brew install mpfr
$ wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.8.2/gcc-4.8.2.tar.gz
$ tar xvf gcc-4.8.2.tar.gz
$ cd gcc-4.8.2
$ mkdir work # From a separate directory
$ cd work
$ ../configure --target=pdp11-aout --prefix=/hogehoge
$ make
$ make install
$ pdp11-aout-acc hello.c -O0 -S -o hello.s   # Cross-compile
$ pdp11-aout-as hello.s -o hello.o           # Assemble
$ pdp11-aout-objdump -d hello.o              # Disassemble

simh

It’s a pdp11 emulator. For V6, it might be efficient to search for the symbol table with nm /unix in advance.

  • c simh mode -> simulation mode
  • ctrl-e simulation mode -> simh mode
  • set cpu 11/40 CPU setting
  • att rk0 hoge.dsk Disk setting
  • boot Boot
    • boot rk0
  • run Start execution
    • run 1020 Execute from address 1020
  • d(ata) Data placement
    • d 001002 046114 Write 046114 to address
  • e(xamine) Memory, register contents
    • e pc pc contents
    • e pc-sp Register list
    • e r5 r5 contents
    • e KDPRR0-KDPDR7 MMU
    • e -m 0:20 Memory contents (assembler)
    • e 0:20 Memory contents (binary)
    • -m(instruction), -a(ASCII), -x(hex)
  • s(tep) Step execution
  • br(reak) Breakpoint
    • break 012345
  • q(uit)

Playing

After starting simh, assign it to a virtual disk with att and boot.

sim> set cpu 11/40
Disabling XQ
sim> att rk0 hello.o
sim> boot rk0

HALT instruction, PC: 000034 (HALT)
sim> e -m 0:30
0:      BR 20
2:      000012
4:      HALT
6:      HALT
10:     000020
12:     HALT
14:     HALT
16:     HALT
20:     INC R1
...

The reason the bootstrap loader can execute a.out format files directly is because the header of the executable file (a.out format) is structured as shown below, and 0407 can be regarded as the br 020 instruction. 020 (octal) = 16 bytes, jumping right after the header. This way, the bootstrap loader doesn’t have to write an a.out loader. Well designed.

offset(bytes) meaning
0              Magic number (0407, 0410, 0411, whether to share text segment, etc.)
2              Text segment size
4              Data region size
6              bss size
8              Symbol table size
10             0
12             Unused
14             Relocation flag