Skip to content

Commit

Permalink
Merge pull request #1156 from DoctorWkt/platform-rosco-r2
Browse files Browse the repository at this point in the history
Kernel/platform/platform-rosco-r2: A port of FUZIX to the Rosco r2 m68k SBC.
  • Loading branch information
EtchedPixels authored Feb 6, 2025
2 parents 6c5fbd7 + 720a7d1 commit 49513f9
Show file tree
Hide file tree
Showing 19 changed files with 1,709 additions and 0 deletions.
70 changes: 70 additions & 0 deletions Kernel/platform/platform-rosco-r2/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

CSRCS = devtty.c
CSRCS += devices.c main.c libc.c
CSRCS += devch375.c devch375_discard.c

ASRCS = p68000.S crt0.S
ASRCS += tricks.S

DSRCS = ../../dev/mbr.c ../../dev/blkdev.c
DSRCS += ../../dev/devsd.c ../../dev/devsd_discard.c
DOBJS = $(patsubst ../../dev/%.c,%.o, $(DSRCS))

LSRCS = ../../lib/68000exception.c ../../lib/68000usercopy.c
LSRCS += ../../lib/68000relocate.c
LOBJS = $(patsubst ../../lib/%.c,%.o, $(LSRCS))

COBJS = $(CSRCS:.c=$(BINEXT))
AOBJS = $(ASRCS:.S=.o)
OBJS = $(COBJS) $(AOBJS) $(DOBJS) $(LOBJS)

CROSS_CCOPTS += -I../../dev/

all: $(OBJS)

$(COBJS): %.o: %.c
$(CROSS_CC) $(CROSS_CCOPTS) -c $<

$(AOBJS): %.o: %.S
$(CROSS_AS) $(ASOPTS) $< -o $*.o

$(DOBJS): %.o: ../../dev/%.c
$(CROSS_CC) $(CROSS_CCOPTS) -c $<

$(LOBJS): %.o: ../../lib/%.c
$(CROSS_CC) $(CROSS_CCOPTS) -c $<

tricks.S: ../../lib/68000flat.S

clean:
rm -f *.o fuzix.elf core *~ fuzix.dis

image:
$(CROSS_LD) -M -o fuzix.elf -T fuzix.ld p68000.o ../../start.o \
../../version.o ../../cpu-68000/lowlevel-68000.o tricks.o \
main.o ../../timer.o ../../kdata.o 68000exception.o \
devices.o ../../devio.o ../../filesys.o ../../process.o \
../../inode.o ../../syscall_fs.o ../../syscall_proc.o \
../../syscall_other.o ../../mm.o ../../flat.o ../../blk512.o \
../../tty.o ../../devsys.o ../../usermem.o ../../syscall_fs2.o \
../../syscall_fs3.o ../../syscall_exec32.o ../../syscall_exec.o \
blkdev.o mbr.o 68000relocate.o \
devsd.o devsd_discard.o \
devch375.o devch375_discard.o \
68000usercopy.o ../../cpu-68000/usermem_std-68000.o devtty.o \
libc.o ../../malloc.o ../../level2.o ../../syscall_level2.o \
../../select.o > ../../fuzix.map
$(CROSS_COMPILE)objcopy fuzix.elf -O binary ../../fuzix.bin
m68k-elf-objdump --disassemble -S fuzix.elf > fuzix.dis

IMAGES = $(FUZIX_ROOT)/Images/$(TARGET)

diskimage:
# Make a blank disk image with partition
dd if=$(FUZIX_ROOT)/Standalone/filesystem-src/parttab.40M of=$(IMAGES)/disk.img bs=40017920 conv=sync,swab
# Add the file system
dd if=$(IMAGES)/filesys.img of=$(IMAGES)/disk.img bs=512 seek=2048 conv=notrunc,swab
# Add the kernel
dd if=../../fuzix.bin of=$(IMAGES)/disk.img bs=512 seek=2 conv=notrunc,swab
# Make an emulator image of it
cat $(FUZIX_ROOT)/Standalone/filesystem-src/idehdr.40M $(IMAGES)/disk.img > $(IMAGES)/emu-ide.img
151 changes: 151 additions & 0 deletions Kernel/platform/platform-rosco-r2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# FUZIX Port to the Rosco r2 SBC

Warren Toomey - 2025/02/05

## Introduction

This is the port of FUZIX to the Rosco r2 m68k SBC:
https://github.com/rosco-m68k/rosco_m68k

It's a work in progress and some things don't work well yet.

## Building FUZIX

You will need the toolchain described in
https://github.com/rosco-m68k/rosco_m68k/blob/develop/code/Toolchain.md

At the top-level FUZIX directory, you can do:

```
make TARGET=rosco-r2 kernel # Build the kernel, which creates
# the file Kernel/fuzix.bin
make TARGET=rosco-r2 diskimage # Builds the libraries and applications,
# and then creates the filesystem image
# Images/rosco-r2/filesys.img
make TARGET=rosco-r2 kclean # Clean up the kernel build. Do this if
# you make any kernel config changes
make TARGET=rosco-r2 clean # Clean up everything
```

There is a shell script here called `mk_fs_img`. Once you have
`Kernel/fuzix.bin` and `Images/rosco-r2/filesys.img` you can run
this script to make the SD card image `sdcard.img` which has the
bootable kernel in partition 1 and the populated FUZIX filesystem
in partition 2.

## Booting with an SD Card

Copy the card image `sdcard.img` to your SD card. Under Linux I do:

```
cat sdcard.img > /dev/sdc; sync; sync
```

At boot time, the SD card should appear as `hda` with two partitions.
Use the boot device `hda2` and login as `root` with no password:

```
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-2025 Alan Cox <[email protected]>
Devboot
Motorola 68010 processor detected.
1024KiB total RAM, 917KiB available to processes (125 processes max)
Enabling interrupts ... ok.
SD drive 0: hda: hda1 hda2
CH375 device: not found
bootdev: hda2
...
login: root
```

## Booting with the CH375 Device and a USB Drive

If you have built the CH375 daughter board as described
[here](https://github.com/DoctorWkt/xv6-rosco-r2/tree/ch375/hardware)
then you can copy the FUZIX filesystem to a USB drive and mount it
as the root device.

However, as the Rosco r2 SBC boots from the SD card, you need to copy
the SD card image `sdcard.img` to both your SD card and your USB drive.

At boot time, the SD card should appear as `hdb` with two partitions.
Use the boot device `hdb2` and login as `root` with no password.

If you have installed 1M of expansion RAM on the daughter board and closed
jumper JP4, then the kernel will see the extra RAM and report that you have
2M of RAM.

```
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-2025 Alan Cox <[email protected]>
Devboot
Motorola 68010 processor detected.
2048KiB total RAM, 1941KiB available to processes (125 processes max)
Enabling interrupts ... ok.
SD drive 0: hda: hda1 hda2
CH375 device: hdb: hdb1 hdb2
bootdev: hdb2
...
login: root
```

## Configuration

Look in `config.h` for compile-time configuration defines.
`TTY_INIT_BAUD` is set for 115200 baud. `CONFIG_FLAT` means we have no MMU.
`CONFIG_SD` and `SD_DRIVE_COUNT` sets us up for one SD card.
`CONFIG_USB` supports my USB expansion board:
https://github.com/DoctorWkt/xv6-rosco-r2/tree/ch375/hardware

This line in `fuzix.ld`:

```
ram (rwx) : ORIGIN = 0x2000, LENGTH = 0x100000-0x2000
```

says that the kernel starts at $2000 and we have $100000 (1 Meg) of RAM.

## Booting

The Rosco ROM loads the kernel at address $40000. The code in `crt0.S`
copies the kernel down to $2000. Then, interrupts are enabled and the
BSS gets cleared. These functions are then called: `init_early()`,
`init_hardware()` and `fuzix_main()`.

## Devices

`devices.c` holds a tables of devices and associated functions. The
main ones are the block devices (0) and the tty device (2).
`device_init()` is called to probe devices and initialise them.

## The DUART

The code to use the XR68C681 DUART is in `devtty.c`. I have made the
`tty_setup()` function do essentially nothing. The Rosco ROM sets the
DUART up for 115200 baud. The Fuzix code then does something which
scrambles the 115200 baud setting. Until I can figure it out, I've
just disabled it.

## The SD Card

The kernel is configured to have SD card support. The file `p68000.S` has
assembly functions to bit-bang the SD card using the DUART:

```
.globl sd_spi_clock
.globl sd_spi_raise_cs
.globl sd_spi_lower_cs
.globl sd_spi_transmit_byte
.globl sd_spi_receive_byte
.globl sd_spi_transmit_sector
.globl sd_spi_receive_sector
```

and the high-level SD card code is in `Kernel/dev/devsd.c` and
`Kernel/dev/devsd_discard.c`.
63 changes: 63 additions & 0 deletions Kernel/platform/platform-rosco-r2/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* Enable to make ^Z dump the inode table for debug */
#undef CONFIG_IDUMP
/* Enable to make ^A drop back into the monitor */
#undef CONFIG_MONITOR
/* Profil syscall support (not yet complete) */
#undef CONFIG_PROFIL

#define CONFIG_32BIT
#define CONFIG_LEVEL_2

#define CONFIG_MULTI
#define CONFIG_FLAT
#define CONFIG_SPLIT_ID
#define CONFIG_PARENT_FIRST
/* It's not that meaningful but we currently chunk to 512 bytes */
#define CONFIG_BANKS (65536/512)

#define CONFIG_LARGE_IO_DIRECT(x) 1

#define CONFIG_SPLIT_UDATA
#define UDATA_SIZE 1024
#define UDATA_BLKS 2

#define TICKSPERSEC 100 /* Ticks per second */

#define BOOT_TTY (512 + 1) /* Set this to default device for stdio, stderr */
/* In this case, the default is the first TTY device */
/* Temp FIXME set to serial port for debug ease */

/* We need a tidier way to do this from the loader */
#define CMDLINE NULL /* Location of root dev name */

/* Device parameters */
#define NUM_DEV_TTY 2
#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */

/* Could be bigger but we need to add hashing first and it's not clearly
a win with a CF card anyway */
#define NBUFS 16 /* Number of block buffers */
#define NMOUNTS 8 /* Number of mounts at a time */

#define MAX_BLKDEV 2

/* Block dvices */
#define CONFIG_IDE
#define CONFIG_SD
#define SD_DRIVE_COUNT 1
#define CONFIG_CH375

#define plt_copyright()

/* Note: select() in the level 2 code will not work on this configuration
at the moment as select is limited to 16 processes. FIXME - support a
hash ELKS style for bigger systems where wakeup aliasing is cheaper */

#define PTABSIZE 125
#define UFTSIZE 16
#define OFTSIZE 160
#define ITABSIZE 176

#define BOOTDEVICENAMES "hd#"

#define TTY_INIT_BAUD B115200
51 changes: 51 additions & 0 deletions Kernel/platform/platform-rosco-r2/crt0.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Need to wipe BSS etc once we figure out our preferred boot method
*
* On entry we are loaded at $40000. We copy ourselves down to $400.
* We are in supervisor mode and the rest is our problem.
*/
#include "../../cpu-68000/kernel-68000.def"

.globl start
.globl start2
.globl __end
.globl __bss_start

.mri 1

start:
/* Position-independent code to copy from start to
* __bss_start down to $400. Code borrowed from the
* Rosco loader code.
*/
RELOC: /* position-independent load addr */
lea.l RELOC(PC),A0 /* PC-rel source addr (load addr) */
move.l #start,A1 /* absolute dest addr (run addr) */
move.l #__bss_start,D0 /* init section absolute end addr */
sub.l A1,D0 /* subtract dest addr for init length */
lsr.l #2,D0 /* convert to long words */
subq.l #1,D0 /* subtract 1 for dbra */
.INIT_LOOP:
move.l (A0)+,(A1)+ /* copy long word from source to dest */
dbra D0,.INIT_LOOP /* loop until __bss_start */

move.l #start2,A0 /* Use A0, otherwise the generated code */
/* is PC-relative which we don't want. */
jmp (A0) /* Jump to the copied start2 code */

start2:
or #$0700,sr
move.l #__bss_start,a0
move.l #__end,d0
sub.l a0,d0
lsr.l #2,d0
wipebss:
clr.l (a0)+
dbra d0,wipebss

lea udata_block0+UBLOCK_SIZE,a7
bsr init_early
bsr init_hardware
bsr fuzix_main
or #$0700,sr
stop: bra stop
41 changes: 41 additions & 0 deletions Kernel/platform/platform-rosco-r2/devch375.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*-----------------------------------------------------------------------*/
/* Fuzix CH375 USB block device driver */
/* 2025 Warren Toomey */
/* */
/* This one is different from the one in Kernel/dev as it assumes that */
/* the CH375 device will send interrupts. */
/*-----------------------------------------------------------------------*/

#include <kernel.h>
#include <kdata.h>
#include <printf.h>
#include <timer.h>
#include <stdbool.h>
#include <blkdev.h>
#include <devch375.h>

#ifdef CONFIG_CH375

extern uint32_t ch375_read_block(uint8_t *buf, uint32_t lba);
extern uint32_t ch375_write_block(uint8_t *buf, uint32_t lba);

uint_fast8_t devch375_transfer_sector(void)
{
bool success;
uint32_t lba= blk_op.lba;

/* Disable interrupts while we do the transfer */
/* but keep IRQ5 enabled as we use it */
irqflags_t irq = di();
irqrestore(4); /* IRQ4 is ignored, 5 is OK */

if (blk_op.is_read) {
success= ch375_read_block(blk_op.addr, lba);
} else {
success= ch375_write_block(blk_op.addr, lba);
}
irqrestore(irq);
return(success);
}

#endif
Loading

0 comments on commit 49513f9

Please sign in to comment.