pdp11 toolchain blues
I've been working on a RL01 disk bootloader for FUZIX, and having a kernel binary (even if broken) to load is the next step.
Fuzix kernel compiles with pdp11 GCC + binutils but all attempts to link have failed so far.
Using this fuzix.ld to assume a kernel at 0x1000:
MEMORY
{
ram (rwx) : ORIGIN = 0x1000, LENGTH=0xc000
}
SECTIONS
{
.text :
{
*(.text .text.*)
*(.rodata .rodata.*)
} > ram
.data :
{
*(.data .data.*)
} > ram
.bss :
{
__bss_start = .;
*(.bss .bss.*)
__end = .;
} > ram
}
I get an esoteric error:
pdp11-aout-ld -M -o fuzix.aout -T fuzix.ld \
crt0.o \
../start.o ../version.o ../lowlevel-pdp11.o \
main.o ../swap.o ../timer.o ../simple.o ../kdata.o devices.o \
../tty.o ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
pdp11.o ../syscall_proc.o ../syscall_other.o ../mm.o \
../devsys.o ../usermem.o ../syscall_exec16.o ../syscall_fs2.o \
tricks.o ../syscall_fs3.o \
../usermem_std-pdp11.o devtty.o libc.o > ../fuzix.map
../syscall_other.o:../syscall_other.o:(.text+0x2c8): relocation truncated to fit: 16 against `.text'
../syscall_other.o:../syscall_other.o:(.text+0x2e4): relocation truncated to fit: 16 against `.text'
../syscall_other.o:../syscall_other.o:(.text+0x360): relocation truncated to fit: 16 against `.text'
../syscall_other.o:../syscall_other.o:(.text+0x4a4): relocation truncated to fit: 16 against `.text'
../syscall_fs3.o:../syscall_fs3.o:(.text+0x4e6): relocation truncated to fit: DISP16 against symbol pagemap_mem_used' defined in .text section in ../simple.o
make[2]: *** [Makefile:32: image] Error 1
Something about address sizes in linking?
Is the kernel too large for the PDP-11, or am I misusing the toolchain / linking parameters? LD is not my strong suite.
That looks a first glance like a linker bug. The DISP16 one especially looks odd because a 16bit displacement on a 16bit machne cannot, as far as I can see, actually overflow - it can hit any address.
If you objdump syscall_other.o can you see what the actual failing items are ?
Checking into the objects that it fails on (fails on different things depending on the order of input objects on the command line). 0x2c8 in syscall_other.o doesn't actually reference any address but all the errors are for stack manipulation instructions.
2c8: 10a6 mov r2, -(sp)
2e4: 10a6 mov r2, -(sp)
360: 65c6 0002 add $2, sp
4a4: 10a6 mov r2, -(sp)
over in syscall_fs3.o
4e6: 0087 rts pc
A switch from GCC 7.2.0 down to GCC 4.9.4 while keeping the latest binutils seems to have fixed this.
pdp11-aout-objcopy fuzix.aout -O binary ../fuzix.bin joel@rand:~/FUZIX % ls -l Kernel/fuzix.bin -rwxr-xr-x 1 joel joel 36680 Jan 2 19:45 Kernel/fuzix.bin
https://sourceware.org/bugzilla/show_bug.cgi?id=22859
For at least one bug I've found now I am trying to get gcc/gas for pdp-11 behaving and build stuff. I'm still looking at the other bits having also broken gcc twice so far 8)
GCC bugs for completeness https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84437 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84438
Although neither break later PDP11 just early ones
I'm a rank amateur who has been poking around the PDP-11 stuff mostly in GNU as. Looking around in gcc PDP-11 bug reports, I found those regarding the -m10 option. Using the git version of gcc (9.0.0 20180808), the errors with regards to the -m10 option seem to no longer be the case. I posted my results with the relevant bug reports.
The "relocation truncated to fit" one still occurs with the test case with the bug report. Since gcc 4.9.4 apparently works, I'll poke around naively and try to find what changed in the upcoming days.
Thanks - much appreciated.
I've been toying with linking C to some rl ard rx bootloaders, with @captnapalm 's suggestion. The 7.3.0 GCC with most recent binutils appears to build correct code. So far successful. I can "make kernel" successfully. Apps require additional makefiles still.
The PDP-11 binutils have been patched recently. It's worth a try again.
thanks for the heads up
Still seems to be broken. The moment a reference crosses 15bits in size I get an error
So for example in start.c
ptab_end = &ptab[maxproc];
blows up, despite &ptab[maxproc] being within 16bits but shrinking maxproc a bit "fixes" that one when it goes under 0x8000. I guess nobody uses the PDP11 toolchain to build binaries over 32K
Interestingly with the current toolchain if I put the data first then the negative displacements and the like stop it blowing up which may mean we have a workaround.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93719 filed 8)
I'm the original author of the pdp11 target in binutils, so I'd like to follow this discussion.
@larsbrinkhoff At the moment I am seeing "16" relocations fail if they go above 32K, which I think is just the howto table but I'm not a binutils person so I am poking in the dark. Ditto in a few cases with "DISP16", which I really don't understand since PDP-11 is 16bit and wraps so I don't understand what it is trying to check, or what I should dump out to see what is going on ?
I'm not a binutils person either, but I'd say your patch to howto_table_pdp11 looks right or at least in the right direction.
I've been working on the pdp11 port of binutils recently to add a --imagic option to output code for separate instruction and data spaces. At the suggestion of Paul Koning, maintainer of the gcc pdp11 port, I have also implemented a pdp11-elf32 target with the goal of compiling C++ for the PDP11 (that's at pre-alpha status and I'm working on the newlib port so I can try g++). The biggest piece of that addition was to hook into the ELF relocation, so I'll see if a similar problem happens there. I definitely don't qualify as a binutils expert at this point, but I have been reading a lot of code. I accepted an invitation to become the maintainer of the pdp11 port.
@slcasner cool - and if ELF relocation works I can just switch to elf and use the binutils elf -> raw binary conversion which is how 68K kernels get done today
With binutils 2.41 and GCC 13.2.0 it seems to build a valid kernel, with .data moved back to its normal spot after .text. Produces a ~37 kB binary file. Loaded into simh, a call to outchar early on works. Sure to be more bugs.
PDP-11 simulator V3.12-3
sim> load fuzix.tap
sim> g
FUZIX version 0.5
Copyright (c) 1988-2002 by H.F.Bower, D.Braun, S.Nitschke, H.Peraza
Copyright (c) 1997-2001 by Arcady Schekochikhin, Adriano C. R. da Cunha
Copyright (c) 2013-2015 Will Sowerbutts <[email protected]>
Copyright (c) 2014-2023 Alan Cox <[email protected]>
Devboot
HALT instruction, PC: 000002 (HALT)
sim>
Until the disk boot loaders are working, it may be helpful to load the kernel binary directly into RAM. SIMH expects a PDP-11 load tape file for its "load" command. This bin2load utility https://github.com/jguillaumes/retroutils/tree/master/bin2load is able to convert a binary file to that format.
$ ./bin2load -f ../fuzix.bin -o fuzix.tap -b 1000
Yay I will try and build a tool chain again when I get a bit of time. Thanks for the tap pointer
GCC 13.2.0 seems to be generating incorrect code with -Os optimization at least
ttyready_t tty_writeready(uint8_t minor)
{
uint8_t c = *uart_txstatus;
return (c & 0x80) ? TTY_READY_NOW : TTY_READY_SOON;
}
into
00000000 <_tty_writeready>:
0: 9fc0 016e movb *$172 <_uart_txstatus>, r0
4: 9000 movb r0, r0
6: 00a1 clc
8: 0c00 ror r0
a: 7417 fff2 ash $-16, r0
e: 0087 rts pc
if optimization is turned off it still fits at 47 kB text, and I can trace things working through ptab_alloc()