UniBone
"UniBone" is a Linux-to-UNIBUS bridge, implemented with a BeagleBone Black micro Linux system.
UniBone can keep old PDP-11s running, by emulating devices and aiding in repair.
UniBone is very similar to its QBUS successor "QBone".
The articles here address different audiences: either they describe some aspects of UniBone for end users, or they explore technical details.
Dynamic discussion at the Google group.
UniBone - Auto Start
Power-On Sequence
A PDP-11 or VAX with UniBone/QBone installed will not run, until QUniBone software closes the so-called "GRANT chain" for Interrupts and DMA transactions.
The Power-On sequence to get a PDP-11+QUniBone system up and running is:
- PDP-11 power is switched ON.
- PDP-11 shows interactive console monitor or tries to boot. This fails, because system not yet complete operational.
- Unibone/QBone onboard Linux boots and connects to network. This needs more than a minute ... (Linux gurus?)
- User logs in into QUniBone wie ssh as root/root. QUnibone software must be started and selected device emulation begins.
Now the PDP-11 system is complete, UNIBUS/QBUS DMA and Interrupt Grant signals are handled correctly. - PDP-11 gets a 2nd Power-On signal by the starting emulation script, and can boot correctly this time.
Item 4 in this sequence can be automated by the "auto-start" feature, so no manual intervention is required too boot.
Auto-Start - Running an Emulation after Power-On
In short:
- The special script "autostart.sh" runs always once after Linux reboot.
- Selected emulation scripts are automatically started after UniBone/QBone power-up.
- Up to 16 scripts can be selected via 4 onboard DIP switches.
- You can preset up to 16 run configurations by editing the script "autostart.sh", see below.
- Interactive ssh sessions may connect to the running application.
The autostart sequence is:
1. After BBB power-on, an automatic (but hidden) login session is started,
Shell scripts .profile and autostart.sh execute the script corresponding to the DIP switch settings, these encode a number 0 to 15.
When looking onto UniBone/QBone PCB front, switch arrangement is:
"Switch up"=0, "down" = 1. Example: switches = "down,down,up,down" => mirror => 1101 => 1+2+8 => run script #11.
2. the selected "demo" emulation confirms startup by echoing DIP switch settings to the LEDs.
So when LED == DIP switches, the emulation runs!
3. The emulation is now running in background.
On further logins via ssh, you may connect to the terminal window of the running "demo" emulation (Emulation console).
See "man screen" for what is happening.
Editing autostart.sh
Assign your run scripts to DIP switch values in autostart.sh, function get_config() :
Your autostart.sh will not be erased on software update.
A sample file is given with all switch cases commented out:
[...]
####################################################################
# get_config() {
# Set up "config_info" and "config_cmd" for config "n"
# Called applications ("demo") should echo "n" onto the LEDs on start.
function get_config() {
# param $1: selection number from switches
# Adapt to your own needs!
n=$1
case $n in
#1)
# config_info="Just memory"
# config_cmd="./memory.sh --leds $n"
# ;;
#2)
# config_info="XXDP on RL1"
# config_cmd="./xxdp2.5_dl1.sh --leds $n"
# ;;
#3)
# config_info="RT11 5.5 single on RL1"
# config_cmd="./rt11v5.5sj_dl1_34.sh --leds $n"
# ;;
#4)
# config_info="11/34: RT11 5.5 FB on DU0:"
# config_cmd="./rt11v5.5fb_du0_34.sh --leds $n"
# ;;
#5)
# config_info="11/34: RSX11M4.8 on DU0:"
# config_cmd="./rsx11m4.8_du0+rl_34.sh --leds $n"
# ;;
#6)
# config_info="11/34: Unix V6 on RK05"
# config_cmd="./unixv6_dk0_34.sh --leds $n"
# ;;
*)
config_info=
config_cmd=
;;
esac
}
[...]
UniBone - Host File Sharing
Why "host file sharing"?
Any vintage computer emulator uses one binary file per emulated disk to save the disk's data blocks. This file is called the "image" of a disk.
UniBone/QBone uses disk images which are compatible to the SimH emulator.
When running, the emulated DEC computer puts a file system onto this disk image, creating a collection of hierarchically directories and files.
Mostly we run pre-installed images though.
The vintage file system is only accessible through the emulated machine's user interface.
Exchanging files between PDP's and the modern world is a permanent challenge.
Current solutions include
- Tools to externally manipulate disk images. There are a lot, well-known projects are DBIT's "PUTR", Don North's "xxdpdir" or Will's Work "DIAGDIR" .
Then there's the recent FSX (2019), quite complete. And RSX11M always had "FLX", the file transfer program. - Creating and dumping files on the vintage machine, by "catching output" and "typing input" text via a terminal emulator.
- Light weight communication programs via serial line.
There are lots of special reader/dumpers, and of course KERMIT. Even PDP11GUI falls into this category. - Host programs and perhaps special hardware to read vintage floppy disks.
- Setup of Ethernet networking on both vintage machine and modern computer:
For instance DECnet is an option (http://retrocmp.com/decnet), TCP/IP works with 2.11BSD UNIX or the Billquist port on RSX-11M .
"Host File Sharing" now is another approach: QUniBone's emulated disk image is permanentely analyzed and kept in sync with an external "host" directory.
The host directory is a regular place in the BeagleBone's Linux filesystem, and can be used by any Linux tool ... also remote accessed via sftp.
So the files visible for the DEC operating system can be manipulated under Linux, changes under Linux are written back to the DEC disk.
From DEC view, the DEC disk content changes "auto-magically" to reflect the current content on the Linux side.
The DEC machine does not need to know anything about the "host file sharing" mechanism.
This is an attractive approach as:
- there's no need to learn a special workflow for file converting.
- it is very easy to operate: file share just with the "COPY/DIR/DELETE" commands of DEC and Linux operating systems.
- it needs no additional hardware or software resources on the DEC PDP-11 or Linux side.
So we can exchange data even with older and very limited PDP-11s. - the PDP-11 can directly boot from a set of host files.
- implementations need only to deal with the DEC filesystem layout. The type of emulated disk does not matter.
QUniBones "file sharing" is a successor of the tu58fs emulator, with many enhancements.
Currently RT11 and XXDP filesystem can be used, hierarchical filesystems like Unix V6 or Files-11 are also possible.
How to use
To publish a QUniBone disk as "shared directory", only two additional parameter lines are necessary:
- shared_filesystem specifies the type of DEC file system on the disk image.
Currently RT11 and XXDP (soon) are implemented. - shared_dir is the location of the synchronized Linux host directory, relative to "demos" work path.
In an actual "demo" application, these parameter where set for a RL02 drive #0 like this:
>>p image RT11v53.rl02
>>p shared_filesystem RT11
>>p shared_dir shared_rl1
>>p
Parameters of device rl0:
Name Short Value Info
------------------ ----- ------------ -----------------------------------------------------------------------------
name name rl0 Unique identifier of device
type type RL02 Type
...
image img RT11v53.rl02 Path to binary image file. Empty to detach. ".gz" archive also searched.
shared_dir shd shared_rl0 Path to directory with shared files. Created on demand, empty to disable sharing.
shared_filesystem shfs RT11 Encode shared dir in this file system (empty, RT11, XXDP).
...
Generally, think of the Linux host directory as "user interface" to the DEC disk image.
This means:
- on startup, the host directory is re-initialized from the DEC side.
- if the DEC image is formatted/initilialized, all files on the host side get lost.
- After RESET of the emulated DEC machine all disk images are reopened and the host directories are initialized again.
- the host directory should be considered "volatile" ... don't keep important files there.
Multiple drives can be "shared" in parallel. As a shared file system is hold in-memory, the BeagleBones may be a limit later.
Creating images from host files
Normally the shared host directory is initialized from the DEC image.
The reverse operation is: Building a new image from downloaded DEC files.
This is quite straigth forward:
- Mount an filled, empty or non-existant image with the "p image <filename>"
- Clear all files in the host directory - the image gets synced and is now empty.
- Copy new files to the shared dir - the image gets synced and contains now a DEC file system with the desired files.
The image can now be used without attaching a Linux host directory.
Synchronizing
Files changes can occur simultaneously on the DEC disk image and the host directory.
Also file operations (like writing file content or directory entries) may take some time on the DEC side, as we have a slow CPU here.
As one consequence, synchronisation takes only place if both sides haven't touched their respective files for a certain period (1 second at the moment).
After that it's assumed file system operations are completed and data content is stable, so synchronization can begin.
Bottom line: it make take some seconds until changes appear on the other side.
Keep in mind the synchronisation of host and DEC directory is memory, CPU and SDcard intensive.
That's because for each change on each side, the complete DEC image is re-analyzed and possibly rewritten.
As the content of the shared DEC disk image changes auto-magically, the DEC OS must not cache the shared disk in PDP memory !
This is no problem on non-caching operating systems like RT11 or XXDP.
Maybe this will cause trouble on other filesystem types later, defintive for newer UNIXes.
About RT-11
The RT-11 operating system was used over the whole PDP-11's lifespan. It's filesystem is also accessible by RSX-11, RSTS and VAX/VMS with the EXCHANGE utility. This makes it a primary candidate for "file sharing".
However the RT-11 filesystem is quite different from modern Linux standard, a lot of mapping is needed.
The defining document is AA-PD6PA-TC "RT-11 Volume and File Formats Manual" from August 1991.
Directories: RT-11 has no subdirectories. Linux subdirectories are ignored and erased.
The directory can not grow indefinitely, it consists of max. 31 disk blocks of 512 bytes, with each block holding max. 72 file entries of each 7 words in size.
So the absolute maximum of file count is 2232 files. (For "directory extensions" see below).
Filenames: Filenames are saved in "Radix-50" compression: 3 letters can be saved in one 16 bit word.
The naming pattern is "6.3", and possible filename letters are "space", "A"-"Z", "0"-"9", "$" and "." .
So a Linux filename is heavily truncated and modified to be RT-11 compatible. For example:
"aaa_readme.txt.ba~" goes to "AAA RE.BA$" ...
The modified RT-11 name will also re-appear on the Linux side, as it is different.
And there's a special problem: two Linux file may map to the same RT-11 filename, with confusing results.
Best use only RT-11 compatible names under Linux, staying all UPPERCASE.
File protection: RT-11 files have a "protection bit" (E.PROT) for read-only status. Linux mapping is:
PROT <-> chmod 444
UNPROT <-> chmod 644
There is an other protecion bit E.READ, which just inhibits file write, not file deletion. This is ignored under QUniBone.
File time stamps: Under RT-11 only the file creation date is saved, not the time. The first possible date is 1-Jan-72, the latest date is 31-Dec-99.
if Linux date year is > 1999, it is truncated to 1999.
There is an "AGE" bit in the RT-11 directory entry for larger years, but this is ignored by all RT-11 monitors and also by QUniBone.
File sizes: RT-11 files have sizes in multiple of 512 byte blocks.
This is preserved under Linux, files are patched with 00s where necessary.
Host files with a size of 0 are not ignored under RT-11.
File allocation: Files under RT-11 are always saved in consecutive disk blocks.
This creates unused areas on the disk if files are deleted and the empty space can not be reused by smaller files.
RT-11 compresses the file system manually with the SQUEEZE utility.
As QUniBone rewrites the RT-11 file system on any Linux host dir change, SQUEEZE is never necessary.
Special files: A RT-11 disk has two special areas, which make a disk bootable and which are visible as Linux files:
$BOOT.BLK: Block 0 is the primary bootloader.
$MONI.TOR: Blocks 2..5 are a secondary bootloader.
These entries are generated by RT-11 utility COPY/BOOT.
You can make a RT-11 disk bootable by copying "good" $BOOT.BLK and $MONI.TOR to the image under Linux.
$VOLUM.INF: this Linux file contains information about the current RT-11 disk layout. It not present on the RT-11 disk, and re-created on any image change.
User file system modifications:
The RT-11 file system can be modified in two ways:
- You can have bigger directory entries: "extra bytes" in the directory entry. This area is accessible to application programs only, not by the RT-11 monitor itself. As experimental feature, QUniBone generates an extra Linux file for this directory extension, with suffix ".dirext".
- Files can have "prefix blocks", with additional fixed space for each file. RT-11 itself provides no support for prefix blocks, you need to write special applications to use it. As experimental feature, QUniBone generates an extra Linux file for prefix blocks if present, with suffix ".prefix"
Interleaving
On some disks reading and writing disk data requires CPU support opposed to DMA operation. This is the case of RX01 and RX02 floppies. Time to transfer one sector would cause the next disk sector to pass the read/write head, requiring a full disk rotation to appear again under the head. This would be result in very slow overall transfer, so between two sectors with ascending number a gap filled with a sector with other number is placed. This is called "sector interleaving".
Normally the disk is low-level formatted with an interleaved sector pattern, so interleaving is transparent to the file system. In case of RX01 and RX02 however floppy sectors are preformatted in strict ascending order. To its up to the file system to use sectors in an itnerleaved way. Thus the interlaving pattern is visible in the binary disk image, giving a quite confusing data layout in the images hex dump.
Decoding/encoding of the disk image is done by an additional "partition layout module" in the hostfile sharing software.
About XXDP
"XXDP" is the device-independend diagnostic package. It consists of a small operating system monitor and 100s of test programs.
Classic distribution is on 10MB RL02 platters, which is large enough to hold the full set of programs.
The "XXDP" file system is a single-user version of the early DOS-BATCH-11 operating system.
Only a single user directory is implemented, so like RT-11 above there are no subdirectories.
From user view its much like RT-11, regarding timestamps, 6.3 file names, file size in whole blocks, boot block and monitor.
Internals
To sync a DEC disc image with a Linuxfile system, several conversion states are necessary.
The drawing show the overall signal and data flow:
Synchronization between disk image and host file system takes place very often, on any change on any side. So optimization is a must-have.
- No multiple memory copies of the binary image and the cached or filesystem tree.
In-memory trees contain only structural information, file data content is fetched from the disk.
The decoded DEC filesystem is hold in-memory however. - No full scan operations to determine file system state. An event based message system greatly reduces CPU load.
While synchronizing, the DEC disk controller may not write or read the image to avoid data inconsistencies. A global lock is used here.
Also synchronization is only performed when both DEC image and Linux host directory were idle for a certain period ... assuming all pending file activies were finished then.
Known bugs:
- a file can not be "renamed" via sftp. It can be copied and deleted via sftp, but "renaming" produces wrong "inotify" events.
UniBone - Debugging
From painful experience you will know: A hardware/software system is only as good as its debugging tools.
And investing time into debugging tools is always a good idea: you will spend so much time in debugging, you deserve some comfort.
Therefore UniBone contains several mechanisms to diagnose whats its doing.
In contrast to regular "desktop" software, embedded code needs to run in strict timing, which may not be changed by the debugging process. And timing relations (in sub-microsecond resolution) must be made visible. So direct debug-printouts ("printf()") or Breakpoints are of minor use.
Non-invasive debugging on embedded devices like UniBone uses GPIO pins, whose levels are changed by software under certain conditions. Signals are then captured with an logic analyzer and evaluated independet of the running device.
***
UniBone software is distributed over 2 processors: the ARM is executing Linux and does all the high level emulation, while PRU is low level real-time UNIBUS interface.
***
PRU debugging: GPIO only
The PRU runs independently from main Linux ARM (thats the idea!). It communicates with the normal Linux program over a mailbox and is not directly reachable for Debugging. Regular debugging tools like "printf()" diagnostic or Eclipse based symbolic debugging are not available. The PRU has its own set of debugging tools, but I found it easier to rely totally on "GPIO debugging".
Debugging via GPIO means: connect a logic analyzer to some of the General Purpose IO pins, and trigger these pins under software control. Its like a high speed binary "printf()" on hardware level. The big advantage here is that we see the timing relations between hardware activity and program flow, in sub-microsecond resolution.
Watching the PRU register bus
The PRU has not enough pins to read and write 56 UNIBUS signals, so an GPIO multiplier is used with 8 read registers, 8 write registersand a REG_WRITE signal. So UniBone has a local data bus with 8 DATAIN, 8 DATAOUT, 3 ADDRESS and 1 WRITE signal. For debugging purposes it is exposed on pin headers:
Under C the PRU register latches are accessed by function calls like
buslatches_setbits(...) ;
buslatches_setbyte(...) ;
buslatches_getbyte(...) ;
By monitoring the accesses to these gpio-registers it easy to follow PRUs program flow.
The relation between UNIBUS signals and buslatches and latch pins is given in the circuit schematic.
PRU debug GPIO pin(s)
Additionally one unused PRU GPIO "1_12" can generated debug signals. You do that by inserting the expression "PRU_DEBUG_PIN0(1)" in your code.
For performance reasons "1_12" is automatically when PRU accesses its register bus.
A second GPIO "1_13" needs a modified BeagleBone to be usable.
PRU Example debugging session
Here is a real-world PRU debugging session. Problem was: the RL11 device emulator had a buggy DMA protocol: it set NPR, received NPG, but then did not raised SACK.
Apparently this logic expression in was wrong, but which term of it?
grant_mask &= (sm_arb.device_request_mask & ~sm_arb.device_forwarded_grant_mask);
I peppered the code in pru1_statemachine_arbitration.c with PRU_DEBUG_PIN0() statements and watched "GPIO 1_12".
Code from pru1_statemachine_arbitration.c
... 144: uint8_t sm_arb_worker_device(uint8_t grant_mask) { ... 174: // Always update UNIBUS BR/NPR lines, are ORed with requests from other devices.
175: buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.device_request_mask) ;
176: // now relevant for GRANt forwarding
177: sm_arb.device_request_signalled_mask = sm_arb.device_request_mask;
178:
179: // read GRANT IN lines from CPU (Arbitrator).
180: // Only one bit on cpu_grant_mask at a time may be active, else arbitrator malfunction.
181: // Arbitrator asserts SACK is inactive
182:
183: if (sm_arb.grant_bbsy_ssyn_wait_grant_mask == 0) {
184: PRU_DEBUG_PIN0(0); PRU_DEBUG_PIN0(0); PRU_DEBUG_PIN0(0);
185: // State 1: Wait For GRANT:
186: // process the requested grant for an open requests.
187: // "A device may not accept a grant (assert SACK) after it passes the grant"
188: if (grant_mask) PRU_DEBUG_PIN0_PULSE(50) ; else PRU_DEBUG_PIN0_PULSE(10) ;
189: PRU_DEBUG_PIN0(0); PRU_DEBUG_PIN0(0); PRU_DEBUG_PIN0(0);
190: if (grant_mask & sm_arb.device_request_mask) PRU_DEBUG_PIN0_PULSE(50) else PRU_DEBUG_PIN0_PULSE(10) ;
191: PRU_DEBUG_PIN0(0); PRU_DEBUG_PIN0(0); PRU_DEBUG_PIN0(0);
192: if (grant_mask & sm_arb.device_request_mask & ~sm_arb.device_forwarded_grant_mask)
193: PRU_DEBUG_PIN0_PULSE(50) ; else PRU_DEBUG_PIN0_PULSE(10) ;
194:
195: grant_mask &= (sm_arb.device_request_mask & ~sm_arb.device_forwarded_grant_mask);
196: if (grant_mask) {
197: PRU_DEBUG_PIN1(1);
198: // one of our requests was granted:
...
Commented Logic analyzer output:
Time resolution is 200MHz,
Channels are:
- "PRU_DBG0" is GPIO 1_12 / PRU_DEBUG_PIN0();
- REG_SEL, REG_WRITE. REG_DATOUT and REG_DATIN are the local PRU latch bus.
- NPR, SACK, BR4,5,6,7 etc are UNIBUS arbitration signals
- BBSYS, SMYN, etc are UNIBUS data signals (no activity here).
- ARM_DBG0,1,2,3 are GPIO pins used for ARM debugging., see below (not used here).
This subset of UNIBUS signals is of interest here:
- latch 1, bit #4 (mask 0x10): NPR
- latch 0: GRANT INs. BG4IN = bit #0, BR5 = bit #1, ... NPGIN = bit #4.
- latch 4, bit #4: MSYN
- latch 7: INTR, INIT, ACLO DCLO.
Comments in the LA screen shot are mostly line numbers in the code listing above.
You can follow the PRU signal processing loop by watching the REG_* signals. Here:
Code (line# or remote function) |
Latch operation | Meaning |
175: | latch 1 is written with 0x10 | emulated device sets NPR |
10ns later | NPR reaches UNIBUS DS8641 driver output and is visible on the bus. | |
188: |
long and short pulses |
Debugging: evaluated 3 logic terms which are relevant for generating SACK. "Short 10ns pulse = "false", long 50ns pulse = "true". |
do_event_initializationsignals() | latch #7 is read | check for ACLO, DCLO and INIT event. |
sm_data_slave_start() | latch #4 is read | emulated devcies MSYN for start of bus cycle. |
sm_intr_slave_start() | latch #7 is read, | emulated CPU checks for INTR |
sm_arb_worker_cpu() | latch#1 is read | emulated CPU checks device SACK |
main() | latch #0 is written | forward GRANTOUT signals |
... and so on ... |
PRU GPIOs enhance LA trigger logic
PRU debugging features are not jsut useful to debug PRU code itself. They also can be used to enhance the trigger capabilites of the logic anylzer.
"Triggering" means to generate an print-out or an logic-analyzer trace just for the error situation.
Bringing reliability from 99% to 99.9% is as much work as going from 50% to 90% and from 90% to 99%, hence the "90:90" rule (which better should be called "90:90:90:..."). When debugging for while, remaining errors gets more erratic and complicated than at first "power-on". Then setting up trigger conditions for a logic analyzer can be cumbersome or even impossible, as pre-history of many other conditions may be involved.
As UniBone is written in C/C++, its easy to write complex trigger conditions in C and make the final "trigger/no-trigger" condition visible via ARM/PRI_DEBUG_PIN GPIO pin.
"C code trigger conditions" can also be used to analyze behaviour of the PDP-11 itself: in PRU code access to UNIBUS addresses and DATA can be evaluated and converted to trigger conditions.
For example, triggering on UNIBUS cycles for a given address range (hre: DL11 console) may be as easy as
sm_data_slave_start() {
...
if (addr >= 0777560 && addr <= 0777566)
PRU_DEBUG_PIN0(1) ; // trigger to LA.
Luckily recompiling and restarting the PRU software is quite fast.
ARM debugging: LEDs and GPIO signals
ARM code (the regular Linux application compiled with "gcc") can also toggle GPIO pins for realtime debugging.
Everything described for the PRU GPIOs also applies here, especially the possibility to generate logic analyzer trigger signals.
All of the BeagleBone GPIOs can be used by ARM code, four of them are preconfigured. The code macros are ARM_DEBUG_PIN0 ... ARM_DEBUG_PIN3, which also drive the LEDs.
The BeagleBone exposes tons of GPIOs, some already routed out to additional pinheaders. To make these accessible, just generate ARM_DEBUG_PIN*, by copy&pasting existing code.
ARM debugging: device message printing
ARM code can be debugged like any other Linux-program with a symbolic debugger. UniBone has no graphical desktop, but development and debugging can be done on a remote PC, I use a cross-compile toolchain under Eclipse.
The emulator software is constructed from many intern "devices", which run on parallel threads.
Debugging multi-threaded applications is a challenge, as the most subtle errors occur from timing relations between different threads. Keywords here: race condition & Heisenbug. Not funny!
To allow debugging with least timing impact, two additional features were build into UniBone:
- Each device can print messages into a global trace buffer. The buffer can later be dumped to a file or console. Saving messages into a buffer has much less impact than direct printout.
To speed things up, the buffer entries contain just the raw data for delayed printf() formatting.
- Debug output verbosity can be fine tuned on a per-device. Message severity and device verbosity. In C++ code devices printed debug output with FATAL,WARNING,ERROR,INFO and DEBUG macros. Each device has a "verbosity level" which specifies which Macros to ignore. The "verbosity level" can be changed any time during runtime.
These severity levels exist:
Macro | Severity |
Default output |
Info |
FATAL() | 1 | Buffer+console | Program termination! |
ERROR() | 2 | Buffer+console | Real problem. |
WARNING() | 3 | Buffer+console | Possible problem. |
INFO() | 4 | Buffer+console | Entertaining activity report. Enabled by default for all devices with cmdline option "--verbose" |
DEBUG() | 5 | Buffer only | Enabled by default for all devices with cmdline option "--debug" |
Every C++ object derived from class "logsource_c" can use this message system.
ARM debugging: message printing example session
Lets say we debug the RL02 drive emulator (just the drive, not the RL11 controller).
Operation is shown for "demo" control program. Steps are:
- Instrumenting the code: add DEBUG() statements
- Test preparation: We set "verbosity" of the drive to "DEBUG" (level 5) and clear the debug log.
- Run a test: for debugging we watch drive activity while listing a small text file.
- Save results: printout the log buffer.
Instrumenting the code
Debug print statements are inserted on several code lines in source "rl0102.cpp":
DEBUG("Drive start seek from cyl.head %d.%d to %d.%d", cylinder, head,
destination_cylinder, destination_head);
...
DEBUG("Change drive %s state from %d to %d. Status word %06o -> %06o.",
name.value.c_str(), old_state, state.value, old_status_word, status_word);
...
DEBUG("Seek: head switch to %d", head);
...
DEBUG("drive seeking outward, cyl = %d", cylinder);
...
DEBUG("File Read 0x%x words from c/h/s=%d/%d/%d, file pos=0x%llx, words = %06o, %06o, ...",
sector_size_bytes / 2, cylinder, head, sectorno, offset, (unsigned )(buffer[0]),
(unsigned )(buffer[1]));
The DEBUG() statements remain in the code. They are only enabled if device "verbosity" is "DEBUG".
Test preparation
Setup the "rl0" device in "demo":
>>>sd rl0
Current device is "rl0"
Controller base address = 774400 *** Test of device parameter interface and states.
"UniBone devices are clients to PDP-11 CPU doing NPR/INTR Arbitrator
(CPU active, console processor inactive).
CPU is physical or emulated.
Memory access as Bus Master with NPR/NPG/SACK handshake.
Current device is "rl0"
UNIBUS unibuscontroller base address = 774400
UNIBUS memory emulated from 000000 to 757776. m i Install (emulate) max UNIBUS memory
m f [word] Fill UNIBUS memory (with 0 or other octal value)
m d Dump UNIBUS memory to disk
m ll <filename> Load memory content from MACRO-11 listing file (boot loader)
m ll Reload last memory content from file "dl.lst"
m lp <filename> Load memory content from absolute papertape image
m lp Reload last memory content from file "dl.lst"
ld List all defined devices
en <dev> Enable a device
dis <dev> Disable device
sd <dev> Select "current device"
p <param> <val> Set parameter value of current device
p <param> Get parameter value of current device
p panel Force parameter update from panel
p Show all parameter of current device
d <regname> <val> Deposit octal value into named device register
e <regname> Examine single device register (regno decimal)
e Examine all device registers
e <addr> Examine octal UNIBUS address.
d <addr> <val> Deposit octal val into UNIBUS address.
dbg c|s|f Debug log: Clear, Show on console, dump to File.
(file = unibone.log.csv)
init Pulse UNIBUS INIT
pwr Simulate UNIBUS power cycle (ACLO/DCLO)
q Quit >>>
>>>p v 5
Name Short Value Unit Access Info
--------- ----- ----- ---- -------- ------------------------------------------------------
verbosity v 5 writable 1 = fatal, 2 = error, 3 = warning, 4 = info, 5 = debug
>>> p
Parameters of device rl0:
Name Short Value Info
------------------ ----- ---------------------- --------------------------------------------------------
name name rl0 Unique identifier of device
type type RL02 Type
enabled en 1 device installed and ready to use?
emulation_speed es 10 1 = original speed, > 1: mechanics is this factor faster
verbosity v 5 1 = fatal, 2 = error, 3 = warning, 4 = info, 5 = debug
unit unit 0 Unit # of drive
capacity cap 10485760 Storage capacity
image img rt11v5.5_games_34.rl02 Path to image file
rotation rot 2400 Current speed of disk
state st 5 Internal state
powerswitch pwr 1 State of POWER switch
runstopbutton rb 1 State of RUN/STOP button
loadlamp ll 0 State of LOAD lamp
readylamp rl 1 State of READY lamp
faultlamp fl 0 State of FAULT lamp
writeprotectlamp wpl 0 State of WRITE PROTECT lamp
writeprotectbutton wpb 0 Writeprotect button pressed
coveropen co 0 1, if RL cover is open >>>dbg c
Debug log cleared. >>>
Run test
We boot the PDP-11 to RT11 from that drive. To exercise the drive under RT11, we list a small textfile then:
.type starts.com
ind datime
!.MODULE STARTS,03,<BL/SJ Startup command file)
!
! Select the editor of your choice. Take the default (KED) unless you are
! not using a VT100 compatible terminal. If you are using an incompatible
! terminal (or a hard copy terminal) select the following command.
!
!SET EDIT EDIT
!
! Get the revision levels of your MU's, if you have them
!
!R MSCPCK
set tt scope
set edit ked
The RL02 drive now has a lot to do: head positioning and transfering sector data via DMA.
Inspect results
Now we display the buffered message onto UniBone's "demo" console:
>>>dbg s
[07:26:27.568355 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0153] Drive start seek from cyl.head 15.1 to 16.1
[07:26:27.568380 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0178] Change drive rl0 state from 5 to 4. Status word 000235 -> 000234.
[07:26:27.574092 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0332] Seek: head switch to 1
[07:26:27.574105 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0340] drive seeking outward, cyl = 15
[07:26:27.574110 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0348] drive seek outwards complete, cyl = 16
[07:26:27.574141 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0178] Change drive rl0 state from 4 to 5. Status word 000334 -> 000335.
[07:26:27.574543 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0583] File Read 0x80 words from c/h/s=16/1/2, file pos=0x7700000000, words = 001124, 000020, ...
[07:26:27.575054 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0583] File Read 0x80 words from c/h/s=16/1/3, file pos=0x50000000000, words = 000104, 000020, ...
[07:26:27.575617 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0583] File Read 0x80 words from c/h/s=16/1/4, file pos=0x21200000000, words = 050513, 000020, ...
[07:26:27.576152 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0583] File Read 0x80 words from c/h/s=16/1/5, file pos=0xffe000000000, words = 122700, 000020, ...
[07:26:28.108880 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0583] File Read 0x80 words from c/h/s=16/1/34, file pos=0x35df00000000, words = 020000, 000020, ...
[07:26:28.109377 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0583] File Read 0x80 words from c/h/s=16/1/35, file pos=0x11c000000000, words = 062700, 000020, ...
[07:26:28.109831 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0583] File Read 0x80 words from c/h/s=16/1/36, file pos=0x2000000000, words = 012605, 000020, ...
[07:26:28.110295 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0583] File Read 0x80 words from c/h/s=16/1/37, file pos=0xe2c000000000, words = 103375, 000020, ...
[07:26:28.128894 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0153] Drive start seek from cyl.head 16.1 to 0.0
[07:26:28.128908 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0178] Change drive rl0 state from 5 to 4. Status word 000235 -> 000234.
[07:26:28.134829 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0332] Seek: head switch to 0
[07:26:28.134839 Dbg rl0This email address is being protected from spambots. You need JavaScript enabled to view it. :0361] drive seek inwards complete, cyl = 0
... and so on ...
>>>
UniBone - FAQ
Which BeagleBone will work?
At the moment, only the classic "BeagleBone Black" is supported "out-of-the-box".
"Black Wireless" is under community test.
"Green" ("BBG") is not 100% compatible to BBB and not working out of the box. Apparently the GPIO impedance is different, which is a problem with these nano-second timed PRU GPIO singals. However BBG can be made to run by using different terminator resistors on the PCB, but will not reach the speed and safety margin of BBB.
"Enhanced" (Blue): could not make a network connection with standard BBB SDcard image. Probably needs an adapted Debian installation.
Forget about the old BeagleBone "White", not even tested.
The exciting new "BBONE-AI" has to be checked out.
The best book about the BeagleBone?
http://derekmolloy.ie/tag/beaglebone-black/
$27 at amazon. Covers EVERYTHING. Thanks, Derek!
UNIBUS backplanes
UniBone needs a "SPC" Unibus slot. I can imagine 4 types backplanes, all looking exactly alike:
1. Standard expansion backplanes, like DD11-DK. These have SPC slots in every socket row on slots C-F.
2. CPU backplanes. These typically have special slots for some kind of processor boards. Then perhaps rows wired for core memory (11/05), or local memory (11/44, 11/84). The rows left after all that are SPC slots, for at least a serial console or one boot device.
3. Specially wired controller backplanes, for older multi-board controllers (RK11, DL11). These have no SPC slots.
4. QBUS backplanes. Don't even think of using these.
UNIBUS terminators
When doing the "bus latch" stress test, every UNIBUS line is set to random state, then all states are checked. If an M9302 or similar termintor with active "SACK" locgic is used, this test will fail on SACK line.
Powering UniBone outside a PDP-11
UniBone can be run outside UNIBUS. This is useful when doing program development or experimenting with Linux scripts and settings, you don't need to waste PDP-11 life time for these activties.
An UniBone runs on +5V only. Current draw well below 1.5 amp. There are these power options:
- Use the +5V jack on the BBB with a BBB power supply. Driver chips and the I2C panel power will not have +5V then, as they are fed by the UNIBUS +5V.
- Feed power to the "UNIBUS 5V", best on leads of the silver capacitors or to "5VUB" pins. Then all components are powered, you should hear the delay-relay clicking.
- Use a strong (> 2A) USB power supply and feed power to BBBs USB port.
- DO NOT power UniBone over BBB's USB connector from a PC USB ports. USB 2.0 data ports can drive only about 500mA, which is only sufficient for a bare BBB, not for BBB + UniBone.
In any case, the green "Power" LED will indicate 3.3V generated on the BBB is OK.
Power consumption will greatly increase when driving UNIBUS terminator arrays.
Using all space on SDcards > 16GB
The distributed file system image is made for a 16GB card. If it is dumped to a bigger card, you want to expand the file system to use all the extra space. That's an one-liner, with some info around:
df /
sudo /opt/scripts/tools/grow_partition.sh
reboot
df /
Will UniBone get damaged if powered off without shutdown?
In theory, Linux system must properly shutdown. And you see warnings for the BBB here and there.
On the other side, I never cared for that and power-cycled my BBBs hundreds of times without any damage.
The SDcard in use seems to have also some protection against power-loss, the journaled Linux-filesystem is also fool-proof.
Why does my UniBone not boot?
Well, most likely it does! But sometimes booting needs several minutes. I never inverstigated that, despite the Debian boot-time seems much too long. Specially without Ethernet-network communication Linux needs endless to start the user session.
When booting the BBB, watch for the blue LEDs. If the UBOOT bootloader starts properly from SDcard, all 4 LEDs are ON for a short moment. You must see this, and it never happens again. The power LED is steady all the time. While the kernel is booting two other LEDs flicker and pulse heavily. The green and yellow LED on the Ethernet port go off for a short period while Linux re-initializes the network. If the system is booted and idle, only on LEDs pulses in a semiregular pattern.
You debug BBB boot problems by attaching a RS232 adapter to the BBB-onboard console port and watch UBOOT/kernel messages.
My UniBone does boot, but I don't see any software as described?
On the BBB there is a SDcard-like memory chip, named "eMMC". It also contains a factory-installed Debian installation. So if something is wrong with your SDcard, or the boot-selection mechanism, you will boot THAT and not the UniBone software installation.
When your BBB is unplugged from the UniBone base board, it looses some resistors encoding the boot device. Then it will ALWAYS boot from the internal eMMC chip.
I seem to have network problems?
Two reasons:
A) The BBB has a bug in its Ethernet PHY, I wrote about it at
https://groups.google.com/forum/#!topic/unibone/fq_IpLIuWT8
Sometimes after powering on it doesn't contact the net, indicated by the yellow LED on the connector not shining.
I had this sometimes, in varying intensity. Never recognized a pattern. Problem is typically gone after the next power cycle (a simple "reboot" does not help).
At the moment there's no problem here, maybe it depends on the actual BBB in use.
B) If you have several BBBs in use, and jingle SDcard with Linuxes on it between them:
This may confuse your DHCP server or other network members. Reason is that the EhterNet MACID is located on the BBB hardware, while 'hostname" is located on the SDcard installation. The wrong assignment may persit in some caches for minutes, even hours.
You can log into your DHCP server, perhaps you see multiple "UniBOne" s in your DHCP table. Try the indicated numeric IP address instead.
As backup to all network problems you can use the two serial console ports on the UniBone, they are configured for auto-login sessions.
You can crimp a cable and connect with 9600 8N1.
Writing and backup SDcards
The net is full of tools how to image SDcards.
I create and restore SDcards under a Ubuntu VM running on Win10, using "dd" to /dev/sdb.
Once in a while I create damaged cards this way. To check, I replugin them after writing, and see wether the filesystem is popping up on the Ubuntu desktop.
Then do a "sudo fsck /dev/sdb" :
$ sudo umount /dev/sdb1
$ sudo fsck /dev/sdb1
fsck von util-linux 2.20.1
e2fsck 1.42.9 (4-Feb-2014)
...
I also change /etc/hostname directly on the SDcard this way, before it is running on the BBB.
The path on my VM to the Sdcard is then: "/media/joerg/rootfs/etc/hostname"
Booting disk images
UniBone emulates several kind of disk devices. However, you need an installed PDP-11 bootloader to boot from these.
These bootloaders are now dup,med into memory wehen installing a certain dik system, checkout the command files. So you don't need to have the correct BOOT ROM installed.
A PDP-11 disk image is booting, then crashing?
When starting one of the xxdp.sh, rt11.sh, rsx.sh etc. scripts, the PDP-11 may hung or crash at some point.
This may have hundreds of reasons. Some popular ones:
1. Verify the GRANT chain is closed on the backplane. Make all G727 grant cards good contact? Is the NPG chain on CAB1-CB1 closed on all un-occupied socket rows? Is UniBone plugged into a socket with OPEN CA1-CB1?
The UniProbe board is of great help here.
2. Some operating system (namely: RSX) need to be SYSGEN to the target hardware. RSX for 11/34 will not run in an 11/84. So model your physical PDP-11 in SimH first and try to boot the disk images there. Then switch to UniBone.
GRANT chain: Why is my machine not starting when UniBone is plugged in?
UniBone does close the GRANT chain in software, by monitoring pins and forwarding signals.
So if UniBone is not running, the GRANT chain is open.
Background:
UNIBUS systems acknowledge Interrupt and DMA request by routing the CPU acknowledge ("GRANT") not to all requesting cards in parallel, but only to the first card on the bus. This card has to forward the signals to the next, if it did not issue the request, and so on.
This mechanism is called "GRANT chain". On un-occupied backplane slots the GRANT signals must be forwarded by dummy controller cards.
The GRANT chain for Interrupts ("BG4,5,6,7" signals) is closed with G727 cards in row D, the DMA ("NPG") is closed on the backplane by connecting wire wrap pin CA1 with CB1.
When a PDP-11 is not using DMA and interrupts, it can run with open GRANT chain. However the common active terminator M9302 raises the SACK line on open GRANT chain, which allocated the bus and stops the machine. Thats a quick indicator for GRANT chain problems.
The LEDs on the UniProbe terminator show open BG4567 & NPG signals and raised SACK.
You can close the GRANT chain on UniBone by jumpers permanently, but then it can't do any Interrupts or DMA, no device emulation is possible anymore.
You also can configure UniBone Linux to autostart the device emulator scripts on power up. These scripts emulate a PDP-11 power cycle by stimulating ACLO and DCLO signals, this should reboot the PDP-11 again, this time with GRANT chain closed by running UniBone software.
Why can I boot XXDP from emulated disk drive, but no other OS?
XXDP disk drivers (at least RL11) don't use Interrupts, only DMA. So errors on the BG4-7 grant chain have no effect. In practice this means: XXDP is tolerant against missing G727 Grant Continuity cards, but no tolerance against broken NPG chain (CA1-CB1 slot jumpers).
Can't install software with "apt-get install" ?
QUnibone is using Debian "Jessie", 8.10. The paket repository was put offline mid 2024.
To fix, an mirror was copied to
http://files.retrocmp.com/qunibone-misc/debian-8.10.0-armhf-DVD-1/
and /etc/apt/sources.list was updated.
To get these fixes, either
- copy content of http://files.retrocmp.com/qunibone/02_bbb_config/03_debian-8.10.0-armhf/
to your QUniBone file system and execute "update-apt.sh" - or run ./update-files.sh
Using the serial ports
The UniBone PCB exposes 2 (of 4) serial ports.
Pin header "UART1" is Linux device "/dev/ttyS1", "UART2" is "/dev/ttyS2".
Both serial ports can be configured for Linux-auto-login, or for use by a simulated PDP-11 SLU (DL11).
To configure a port (here ttyS2) for auto login (default):
ln -sf /lib/systemd/system/getty@.service /etc/systemd/system/getty.target.wants/This email address is being protected from spambots. You need JavaScript enabled to view it.
reboot
To configure for use by DL11 emulator:
rm /etc/systemd/system/getty.target.wants/This email address is being protected from spambots. You need JavaScript enabled to view it.
Then reboot.
UniBone - Acceptance Test
If you received a UniBone hardware or build your own one, you should check wether it functions correctly.
Prerequisites
For non-UNIBUS tests UniBone can be operated standalone. Power needs are +5V, to connect use pins of tantal capacitors or "+5V UB" pin header. Attention: If you use the BeagleBone +5V jack, parts of the circuit are unpowered, as the relay will not close.
Do perform the non-trivial UNIBUS/PRU tests, UniBone must be placed into a SPC slot in an empty, terminated UNIBUS backplane (yes, this is a challenge). An expansion backplane DD11-DK or -CK is best.
One terminator is enough, but it must be passive: No Boot ROM or M9302. M9302 drives SACK active LOW, if any of the BG*IN or NPGIN is unconnected or HIGH, resulting in a loopback test error on latch 1.
The good news: Only +5V are required, no G727 continuity cards are needed, and the NPG chain may be open or closed.
Power On and Login
Wire BBB to Ethernet, then apply power to the DD11. The power relay must switch after 1 second delay. BBB produces 3.3V supply then and the green LED goes ON.
The blue LEDs on the BBB begin to flicker, as the Debian Linux is booting. After 30-60 seconds you can try to login via network.
joerg@vmubuprog:~$ ssh root@unibone
root@unibone's password: root
Have fun with UniBone!
Lost login: Fri Dec 14 15:28:24 2018
root@unibone:~#
If you can not login, try repowering UniBone. There's a known bug in the BBB's Ethernet interface, which prevents network communication sometimes ... never fixed and very annoying.
EEPROM, board pin config and I²C
There's a small EEPROM, accessed over I²C bus. As the UniBone PCB is a "cape" for the BBB, it needs the EEPROM to read out the board name. Then the Linux kernel should activate the correct configuration file to setup port pins of the Sitara CPU correctly. A kernel component named "cape manager" should do this ... it may or may not work in the Debian kernel in use. Doesn't matter. Sigh.
Read the EEPROM:
# hexdump -C /sys/bus/i2c/devices/i2c-2/2-0054/eeprom
Program the EEPROM:
# cat cape.eeprom >/sys/bus/i2c/devices/i2c-2/2-0054/eeprom
Check the EEPROM content:
# hexdump -C /sys/bus/i2c/devices/i2c-2/2-0054/eeprom
Reboot, login again, test wether the correct board configuration is loaded:
...
root@unibone2:~# cat /sys/devices/platform/bone_capemgr/slots
0: P----- -1 UniBone,00B0,Hoppe,UniBone
1: PF---- -1
2: PF---- -1
3: PF---- -1
4: P-O-L- 0 Override Board Name,00B0,Override Manuf,UniBone
With that test also the I²C interface for add-on panels is tested.
RS232 ports
UniBone exposes two serial RS232 ports. They are configured for regular Linux login session. To connect to the BBB via RS232, you need to crimp a simple cable:
The pinout is NOT the most used PC standard. See here for a product and docs, only GND, TXD and RXD are connected.
Connect the male DSUB-9 connector to your PC with a null-modem cable and start a terminal emulator with 9600 baud, no hardware hand-shaking.
You should see another Debian shell prompt both on UART1 and UART2 connector.
Logging in via RS232 may be useful if the Ethernet-bug occurs too often on your BBB.
Testing standard GPIOs
The important part of UniBone is the PRU controlled interface to the UNIBUS. But the user LEDs and switches are traditional GPIOs.
Test with the "demo" application, main menu point "tg" for "GPIO", then "lb" for "manual loopback".
In loopback mode, the 4 switches control the four LEDs: toggle them and the LEDs should respond. Pressing the button will enable the DS8641 driver array, resulting in active 2nd green LED.
PRUs and UNIBUS interface
The real important test is access to the UNIBUS. Signals are output through the LS377 register array and 8641 drivers onto 56 UNIBUS data lines, then read back through drivers, LVTH541 input latches and PRU pins. This tests also terminators and parts of the UNIBUS backplane.
Preparation:
- Put UniBone into an empty terminated UNIBUS backplane.
- set loopback jumpers onto the 5 BGIN/OUT and NPGIN/OUT lines (yellow in the image below)
Use again the "demo" application, main menu "tl" for "test bus latches", then ">>> * r" to test all UNIBUS signals endlessly with random patterns.
Run this test as long as possible, and terminate with ^C. The most likely reason for errors are solder failures on the SMD input/output latches. You may have open solder joints, or shortcuts between pins. To help in debugging, the test software prints the signal path for failed bits.
The first thing to check on an loopback-error is the physical voltage level on the UNIBUS.
If a voltage level is as expected, the output branch is OK and the input branch over 74lvth541 registers is defective. Else it's the output over these 74ls377's. Remember: on UNIBUS, a logical "1" is represented as 0 volts, a logic "0" is about 3.4 volts (except the BG and NPG signals).
To test the test, you can remove one of the yellow loopback jumpers while the test is running. It should stop with an error.
Its a good idea to bend and knock the board a bit while under test: this may expose bad solder joints.
Pro tip: As the UNIBUS lines need pullup by terminators, this test can be used to check a big part of your backplane: plug in only a single terminator at either end, plug UniBone to different SPC slots of the backplane and run this test. It will fail, if any of the 56 signals has no connection to the remote terminator. You even can test UNIBUS cables between separate backplanes this way.
And don't forget to remove the loopback jumpers on BG* and NPG after test!
Standalone memory test
If the loopback test succeeds, you can go more realistic: add a UNIBUS memory card and let UniBone exercise it. This tests not just static connections, but also implementation and timing of UNIBUS DMA cycles. On the other hand, only addresses, data and MSYN/SSYN signals are tested, and functions of the memory card! Still no G727 grants are needed.
Attention: a memory card needs more amps, and probably more voltages than just +5V.
Then execute memory operations as described. As there's no PDP-11 CPU active, work in "Arbitration inactive" mode.
Finally: run it in a PDP-11
If all went well, plug UniBone into a PDP-11.or boot operationg systems from emulated RL02.