Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building/porting ELKS in ROM #1795

Open
fhendrikx opened this issue Feb 4, 2024 · 19 comments
Open

Building/porting ELKS in ROM #1795

fhendrikx opened this issue Feb 4, 2024 · 19 comments

Comments

@fhendrikx
Copy link

Description
Hi, Following the instructions given here:
https://github.com/ghaerr/elks/blob/master/BUILD.md

When I select the option to build a ROM, the compile fails with an error about undeclared elements. However, as far as I can tell, these are in the linuxmt/config.h file, and this is included in the init/main.c file.

How to reproduce ?
Enabled the option to build a ROM in the menuconfig (Kernel Settings > Build kernel as ROM bootable).

Raw data
The compiler says:

init/main.c:71:30: error: ‘OPTSEGSZ’ undeclared here (not in a function)
 static unsigned char options[OPTSEGSZ];
                              ^~~~~~~~
init/main.c: In function ‘parse_options’:
init/main.c:388:34: error: ‘DEF_OPTSEG’ undeclared (first use in this function)
  fmemcpyb(options, kernel_ds, 0, DEF_OPTSEG, sizeof(options));
                                  ^~~~~~~~~~
init/main.c:388:34: note: each undeclared identifier is reported only once for each function it appears in
At top level:
init/main.c:71:22: warning: ‘options’ defined but not used [-Wunused-variable]
 static unsigned char options[OPTSEGSZ];
                      ^~~~~~~

Additional information
Both of these values are defined in the config: ./elks/include/linuxmt/config.h

This is included in the file in question, so everything should work.

Thanks

@fhendrikx fhendrikx added the bug Defect in the product label Feb 4, 2024
@ghaerr
Copy link
Owner

ghaerr commented Feb 4, 2024

Hello @fhendrikx,

I'll try to reproduce this and comment. For the 8018x ROM build, which is the only officially supported build at the moment, normally one builds that using:

cp 8018x.config .config
make clean
make

There are likely issues between the make menuconfig method of building a ROM version and the pre-built 8018X configuration. This could likely be that only CONFIG_ARCH_8018X/CONFIG_ROMCODE combo is supported for the ROM addresses which are defined in elks/include/linuxmt/config.h.

Thank you!

@fhendrikx
Copy link
Author

Hi @ghaerr,

Thanks for the tips. I also needed to "source env.sh" first, but otherwise, this is working.

Thank you for your help.

@fhendrikx
Copy link
Author

Hi @ghaerr

I just tried the "emu86-rom.config" config. Running make gives me:

(cd ../.. ; ia16-elf-ld.gold  -M  -T /home/ferry/elks/elks/elks/elks-small.ld \
	arch/i86/boot/crt0.o \
	init/main.o '-(' fs/fs.a kernel/kernel.a lib/lib.a net/net.a fs/romfs/romfs.a arch/i86/kernel/akernel.a arch/i\
	-o arch/i86/boot/system > arch/i86/boot/system-full.map ; \
	ia16-elf-nm arch/i86/boot/system | sed -e '/&/d; /!/d' | sort > \
		arch/i86/boot/system.map; \
	elf2elks --symfile arch/i86/boot/system.sym arch/i86/boot/system)
arch/i86/drivers/block/blk_drv.a(init.o):function device_init: error: undefined reference to 'bios_conv_bios_drive'
arch/i86/drivers/block/blk_drv.a(genhd.o):function add_partition: error: undefined reference to 'bios_drive_map'
arch/i86/drivers/block/blk_drv.a(genhd.o):function add_partition: error: undefined reference to 'bios_drive_map!'
arch/i86/drivers/block/blk_drv.a(ll_rw_blk.o):function blk_dev_init: error: undefined reference to 'bioshd_init'
ia16-elf-nm: 'arch/i86/boot/system': No such file
elf2elks: error: cannot open input file `arch/i86/boot/system': No such file or directory
make[2]: *** [Makefile:98: boot/system] Error 1
make[2]: Leaving directory '/home/ferry/elks/elks/elks/arch/i86'
make[1]: *** [Makefile:75: Image] Error 2
make[1]: Leaving directory '/home/ferry/elks/elks/elks'
make: *** [Makefile:13: all] Error 2

Interestingly, the config "emu86-rom-full.config" works just fine.

It's probably useful to mention that I'm keen to eventually build an elks ROM image for a barebones (no BIOS) SBC based on the 8086 or 80286 (in real-mode only).

I should probably drop a question about the best approach in Discussions, rather than hash it out any further here.

@ghaerr
Copy link
Owner

ghaerr commented Feb 4, 2024

I just tried the "emu86-rom.config" config. Running make gives me

Ok, I see now: it seems a prior enhancement has compromised the ROM build, when the ROM build doesn't support the BIOS disk driver. Let me fix that.

Interestingly, the config "emu86-rom-full.config" works just fine.

Yes, that includes the BIOS disk driver, which provides the undefined references in your link error(s) above.

I'm keen to eventually build an elks ROM image for a barebones (no BIOS) SBC based on the 8086 or 80286 (in real-mode only).

That shouldn't be too big a deal, I suggest starting rom the "emu86-rom.config" after I post a fix for what you've just identified.

I should probably drop a question about the best approach in Discussions, rather than hash it out any further here.

That's Ok, we can continue here, thank you!

@fhendrikx
Copy link
Author

Thank you.

So, the SBC we're building is not intended to be IBM PC compatible, so no BIOS.

My understanding at present is that we'll need to:

  • Modify the timer stuff
  • Add a driver for storage (probably CF)

@ghaerr
Copy link
Owner

ghaerr commented Feb 5, 2024

the SBC we're building is not intended to be IBM PC compatible, so no BIOS.

Yes, so you'll want to run a "headless" console that will likely do I/O to/from a serial port. See CONFIG_CONSOLE_HEADLESS in elks/arch/i86/drivers/char/Makefile for more details. Other settings will be in emu86-rom.config.

Modify the timer stuff

To get an idea of which files might need changing (or replaced with versions specific to your architecture), check out elks/arch/i86/kernel/Makefile:

ifeq ($(CONFIG_ARCH_IBMPC), y)
OBJS += irq-8259.o timer-8254.o
endif

ifeq ($(CONFIG_ARCH_PC98), y)
OBJS += irq-8259.o timer-8254.o
endif

ifeq ($(CONFIG_ARCH_8018X), y)
OBJS += irq-8018x.o timer-8018x.o
endif

These pertain to the PIC (interrupt controller) and PIT (timer).

Add a driver for storage (probably CF)

The 8018X port contains a version of the SSD driver accessing CF using a low-level SPI hardware interface. See the files referenced in elks/arch/i86/drivers/block/Makefile for more details:

ifeq ($(CONFIG_BLK_DEV_SSD_SD8018X), y)
    OBJS += ssd.o ssd-sd.o spi-8018x.o
endif

@ghaerr ghaerr changed the title Compile issue Building/porting ELKS in ROM Feb 5, 2024
@ghaerr ghaerr added discussion and removed bug Defect in the product labels Feb 6, 2024
@fhendrikx
Copy link
Author

Thanks for the further tips!

Do you know if there is any wiring information about this SPI interface? Keen to understand how it is wired.

@ghaerr
Copy link
Owner

ghaerr commented Feb 8, 2024

Do you know if there is any wiring information about this SPI interface? Keen to understand how it is wired.

Hello @cocus, do you have any info you can share on how your SPI interface was wired for the ELKS 8018X CF card reader?

@cocus
Copy link
Contributor

cocus commented Feb 8, 2024

Do you know if there is any wiring information about this SPI interface? Keen to understand how it is wired.

Hello @cocus, do you have any info you can share on how your SPI interface was wired for the ELKS 8018X CF card reader?

Sure. It's not a CF, but rather an SD card. Here's the link to the EasyEDA project for my entire SBC, but I'll comment on what I did.

I've used a cheap Arduino SD card adapter (the one that has a 3V3 regulator but it doesn't have any voltage level translators). It's wired as follows:
image
image
image
image

You need to be able to drive the SCLK, MOSI and /CS; while you should be able to "read" the MISO.

Since the 80C188EB runs at 5V, and since I didn't want to use a voltage level translator, I just added some resistors in series with each pin where the CPU "talks to" (i.e. drives these pins). On the module itself, you have some resistors acting as "pull ups" (not sure why), so I removed them and converted to pull downs (I think I used 1.5K, but using 1K should suffice, it'll get 2.5V for the IO). Nonetheless, the only output signal from the SD card goes straight to the CPU because the CPU recognizes 3V3 as a high value (i.e. a 1).
After that, and because this CPU lets you use those pins as "GPIOs", I just wrote an assembly driver that bitbangs the data and samples the input data as well while toggling the clock line. You need to set up these GPIOs as inputs or outpus, and telling the processor exactly that you want to use them as GPIOs. I have a dummy function that only toggles the clock (because the SD requires a lot of dummy clocks while initializing it). Then this assembly code is called by C code on the SD driver, where it does more or less what the petit-fs (from elm-chan) does to initialize the SD card (i.e. card presence, switching to SPI mode, wrappers for block read and write, etc.).

Hope this helps!

@fhendrikx
Copy link
Author

@cocus Thanks for the information... sadly, the link to your project doesn't work (it just loads the home page), even when I'm logged in.

@cocus
Copy link
Contributor

cocus commented Feb 8, 2024

@cocus Thanks for the information... sadly, the link to your project doesn't work (it just loads the home page), even when I'm logged in.

Try this https://oshwlab.com/cocus/80c188eb-sbc

@fhendrikx
Copy link
Author

@cocus thank you, appreciate the link. Will take some time to go through it. :)

@cocus
Copy link
Contributor

cocus commented Feb 8, 2024

@cocus thank you, appreciate the link. Will take some time to go through it. :)

Please let me know. I don't think you'd need all of the stuff I added on that schematic. Mostly because some of those were chips that I had laying around, or were things I wanted to test (hence why you'd see a lot of 0ohm resitors scattered around).

@ghaerr
Copy link
Owner

ghaerr commented Feb 8, 2024

That's pretty cool @cocus that you got ELKS running on hardware that you designed, I didn't realize that! :)

Did you use the ADC for anything interesting? And what is the "Arduino module", is that additional Arduino-based hardware, outside this SBC, required for the SD access?

@fhendrikx
Copy link
Author

I'm guessing he's using a module like: https://www.aliexpress.com/item/1005004916894706.html

@cocus
Copy link
Contributor

cocus commented Feb 8, 2024

That's pretty cool @cocus that you got ELKS running on hardware that you designed, I didn't realize that! :)

This was the second time I've done a "retro" computer, last one was a Z180 with a CPLD but didn't get much love (lost interest). I actually followed some other SBCs, in particular the one from https://web.archive.org/web/20200229050813/kswichit.com/C188/c188sbc.htm (The site was up before, but not now, so I had to use web.archive.org, really sad!).
I didn't want to screw any of the critical components, like the RAM or FLASH. But I took some liberties, like not using a CPLD, using a register to buffer the access to even more devices on the IO map (this idea came from the original Modem where I took the 80C188EB from, although I can say it's not a good idea, no need to complicate things further :) ).

Did you use the ADC for anything interesting? And what is the "Arduino module", is that additional Arduino-based hardware, outside this SBC, required for the SD access?

I've tried to use the ADC by poking it from basic, seems to have worked, but really cumbersome. That ADC came from the same modem I took the chips from, so it's not intended for general purpose, rather for high speed signal acquisition.
The arduino module is just a simple 3.3V regulator (because SDs work at that voltage, and lower), and some resistors. Like this one https://aliexpress.com/item/1005005377729431.html

@fhendrikx
Copy link
Author

fhendrikx commented May 13, 2024

Hi @ghaerr

Given a 1MB address space, and the desire to load ELKS (kernel+system) from ROM, what is the ideal address space layout on the 8086 family of processors?

What do existing ROM-based systems do? It says somewhere that ROM-based systems only need 128k. What does the address space look like in these instances?

The reason I'm asking is that we're looking at how to map RAM/ROM and what configuration would work best for ELKS. We have the ability to map stuff dynamically on our prototype, but that might not be of any use after boot.

Thanks!

@ghaerr
Copy link
Owner

ghaerr commented May 13, 2024

Hello @fhendrikx,

The 8018x port is booted from ROM, which might be a good place to start for your design, as it is quite similar. The configuration file for it is 8018x.config of which the pertinent parts are as follows (these are 8086 segment values, not hardware addresses):

#
# ROM-CODE kernel-loader
#

CONFIG_ROM_SETUP_CODE=0xe000
CONFIG_ROM_KERNEL_CODE=0xe060
CONFIG_ROM_SETUP_DATA=0x0060
CONFIG_ROM_KERNEL_DATA=0x0080
CONFIG_ROM_BASE=0xe000
CONFIG_ROM_CHECKSUM_SIZE=64

The exact layout and boot process of ELKS in ROM is a bit complicated to explain, you'll also want to refer to elks/arch/i86/boot/setup.S and look for CONFIG_ROMCODE. Other details are in elks/include/linuxmt/config.h under the same CONFIG_ROMCODE.

The quick answer to your question is that the 8018X 64-128k ROM starts at hardware address 0xE0000 and contains the ELKS kernel code segment, while the data segment starts at hardware address 0x00000 with the ELKS kernel data segment at 0x00600. The RAM can be as small as 128k and I think the kernel can be made to fit in 64k ROM.

You can build the 8018x version by copying 8018x.config to .config and running make. It can be emulated by using the EMU86 8086 emulator using the ELKS-provided shell script emu86.sh.

[EDIT: Actually I think EMU86 won't emulate the 8018X port, as the hardware PIC and PIT are different than IBM PC. Instead, use the emu86-rom.config as .config and make, which will produce the ROM image. This is explained in emu86.sh].

Thank you!

@fhendrikx
Copy link
Author

fhendrikx commented May 13, 2024

Thank you for that detailed explanation, really appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants