Thursday, November 24, 2011

Booting Beagleboard by BBC BASIC

The RPC is the only machine I have left with a serial port (well, except the BBC Micro that's coming up to its 30th birthday next year, and it can't quite manage 115200 baud).

Below is a very short BBC BASIC program that assembles some code and uploads it to the BB internal memory. You have to hold down the USR button on powerup/reset to get it to talk. (The slowest part in development was noticing out that the initial boot sequence uses 8E1 protocol, and not the 8N1 that the x-loader and u-boot and linux do.)

I wanted to get into the boot process as early as possible without continuously re-flashing the NAND ROM, and also avoiding plugging an SD card into the somewhat worn out socket.

Brunel OS is an idea I've been thinking about for years, with a concept based on an Eiffel inspired language that handles multi-threading by simply only alowing one thread at a time access to any object and allowing threads to pass through multiple memory maps (somewhat different to the process model of other operating systems I've had experience of).

So, an example of loading a very small program into internal RAM of the BeagleBoard from a Risc PC:

SYS"OS_SerialOp", 0, &106, &fffffe00
SYS"OS_SerialOp", 1, %011000
SYS"OS_SerialOp", 5, 18
SYS"OS_SerialOp", 6, 18

PROCassemble

REM Receive ASIC ID (and ignore it, for the time being)
FOR R%=1 TO 58
  REPEAT
    SYS"OS_SerialOp", 4 TO ,J%;F%
  UNTIL (F% AND 2) = 0

  PRINT RIGHT$( "0"+STR$~J%, 2 );
NEXT

PRINT "Sending boot command"
PROCput( 2 )
PROCput( 0 )
PROCput( 3 )
PROCput( &f0 )
PRINT "Boot command sent"
DIM B% 4
!B%=P%-code%
PROCput( B%?0 )
PROCput( B%?1 )
PROCput( B%?2 )
PROCput( B%?3 )
PRINT "Length sent ";!B%
T%=0
FOR Q%=code% TO P%
  SYS"OS_SerialOp", 4 TO ,J%;F%
  IF (F% AND 2) = 0 THEN
    PROCshow( J% )
  ENDIF
  PROCput( ?Q% )
  T%+=1
NEXT
PRINT "Transmission finished "; T%; " bytes"

REM Kind of terminal (one way, at the moment)
REPEAT
  REPEAT
    SYS"OS_SerialOp", 4 TO ,J%;F%
  UNTIL (F% AND 2) = 0
  PROCshow( J% )
UNTIL 0

END


DEF PROCput( C% )
REPEAT
SYS"OS_SerialOp", 3, C% TO ; F%
UNTIL (F% AND 2) = 0
ENDPROC

DEF PROCshow( C% )
    R%+=1
    IF C%>31 OR C%=10 OR C%=13 THEN
      VDU C%
    ELSE
      PRINT "<";~C%;">"
    ENDIF
ENDPROC


DEF PROCassemble
DIM code% 1000
FOR I%=0 TO 1
P%=code%
[OPT 3*I%
  MOV r9, #&49000000
  ORR r9, r9, #&00020000
  ADR r1, welcome
.write_loop
  LDRB r2, [r1], #1
  CMP r2, #0
  STRNEB r2, [r9]  ;This can overflow the buffer, but it's not important yet
  BNE write_loop

.loop
  B loop
.welcome
  EQUS "Welcome to Brunel OS 0.0.0-1"+CHR$10+CHR$13
  EQUB 0
  ALIGN
]
NEXT
ENDPROC

Output:
04010501343007561302010012150100000000000000000000000000000000000000001415010000000000000000000000000000000000000000Sending boot command
Boot command sent
Length sent 64
Transmission finished 65 bytes
Welcome to Brunel OS 0.0.0-1

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home