ghaerr / elks

Embeddable Linux Kernel Subset - Linux for 8086
Other
984 stars 106 forks source link

[integration] Adding a random NE2K card on a 80c188 #1017

Closed cocus closed 2 years ago

cocus commented 2 years ago

Hi all! After some really exciting development, we have some really cool support for embedded 8018x CPUs. My board wasn't conceived as a SBC, nor as something you could use beyond the intended usage the manufacturer gave to it. Of course that doesn't stop me to use it as I would like to. I have the entire address/IO mapped out, and I took out all the ICs that weren't useful for my usage. Now it's the time to add a network card, and for such task I have 3 different ISA cards that I could use. Note that this device doesn't even have an ISA connector, so I would have to hack up a connector, or route all the necessary pins from it to the network card. Since it's an 8 bit bus, I can't use any of the cards in NE2K mode, but rather NE1K. I can use one of the following cards:

All of them have a coax+twisted pair connectors, and an I2C EEPROM. This might contain the configuration stored by a DOS software whenever they were last used, and I think I need to boot a DOS machine with the appropriate software for them to reset their config or at least know what's configured.

I'm a complete noob to the ISA bus, but I understand that the address and data bus is routed there, alongside some control signals like R/W, etc. IRQs are also there, but my board doesn't have an IRQ controller, but the CPU does handle that. So if I know that the card wants to use IRQ3, I could connect the appropriate IRQ3 pin into one of the 4 external IRQ pins on my CPU and deal with the IRQ mappings in software (well, there's NO support for external IRQs yet, so this would be the first thing using it). I also know that an 8MHz clock needs to be feeded there. I don't have that, but I think I could either derive it from the CPU clock with two flip flops (it's a 32MHz crystal, but the F_CPU is 1/2 of it) or understand if there's some kind of timer that I could use on the CPU to generate 8MHz constantly. Besides that, I should provide 5V and probably 12V. I will double check if the pins for these things are used.

I would like to understand if any of the above cards have some advantages over another card, so I could pick one to begin working on this.

After picking one up, I need to understand how to enable its appropriate driver on ELKS and which parts of it need to be modified.

All help and tips would be greatly appreciated.

Thanks!

EDIT: I checked that none of these cards use the -12V or 12V rails, DMA related lines, nor the 8MHz clock; just the some address lanes, low-order data and some IRQ lines. On the 16bit expansion, I saw they use the SDxx lanes, some IRQs and the /IOCS16. They don't use /MEMCS16, /MEMWR /MEMR. I need to figure out how the /IOCS16 lane works, and if I could disregard it completely or not. Besides that, it think the interface should be straightforward to the 80c188.

ghaerr commented 2 years ago

I don't see ANYTHING if I do ^C from the serial console, but I do see some output on the serial console if I ^C on the telnet console:

Yep. Notice that the process group is 0 on the login shell, but is 9 on the telnet shell. We need a setsid() call in /bin/sh or /bin/sash to fix this. Since the process group is 0, the kill_pg isn't called in the tty driver, and even if it was, there's no processes attached to the process group.

cocus commented 2 years ago

Right, I see! I'd love to flash the rootfs onto my sd card so this system behaves more like the PC port and I don't get all these issues, but for the time I'll still resort to the ROMFS :) Nice catch on this "bug", I don't have enough knowledge of the system to have found this myself, so thanks!

ghaerr commented 2 years ago

# ^C Not supported by standalone shell: '' (Note: I hit enter after the ^C, and that was printed by the serial code when 0x03 is received). Now, from the telnet console, I do get a line feed when I ^C, and I also get some verbose output on the serial console:

I can now see an additional problem - when ttyp->pgrp (process group) is 0, then not only is the signal not generated, but the TTY VINTR character (^C=03) isn't processed, causing the shell to say "^C" not supported by standalone shell. That message is complicated, and is the response to an unprocessed ^C not being able to be processed by /bin/sash, which would normally exec the real /bin/sh to handle it (normally only for characters like |, >, <, etc, but also printed on control characters, apparently).

I'll figure out a fix for this in the morning.

ghaerr commented 2 years ago

@cocus,

Add the following to elks/init/main.c, this should solve your signal problem. It will work well when /bin/init is not installed (and /bin/sh or /bin/sash is used), but should not be used if running /bin/init. Let me know how it works, and I'll post a PR that will take care of it with a bit more detail.

diff --git a/elks/init/main.c b/elks/init/main.c
index 5a9094c3..c1e39308 100644
--- a/elks/init/main.c
+++ b/elks/init/main.c
@@ -133,6 +133,10 @@ static void init_task(void)

     mount_root();

+#ifdef CONFIG_ROMCODE
+    current->session = current->pgrp = 1;      /* force initial process group on console*/
+#endif
+
     /* Don't open /dev/console for /bin/init, 0-2 closed immediately and fragments heap*/
     //if (strcmp(init_command, bininit) != 0) {
        /* Set stdin/stdout/stderr to /dev/console if not running /bin/init*/
cocus commented 2 years ago

Add the following to elks/init/main.c, this should solve your signal problem. It will work well when /bin/init is not installed (and /bin/sh or /bin/sash is used), but should not be used if running /bin/init. Let me know how it works, and I'll post a PR that will take care of it with a bit more detail.

That works! Excellent!!!

ghaerr commented 2 years ago

Hello @cocus,

I ended up porting this version of BASIC to ELKS, and it seems to work OK; although it does support string variables, there are no string functions, and you kind of have to know whether the variable is string or integer before being able to print it. Also, integers are maxed out at 65535. It supports a FORMAT statement for string and integer output, but I ended up adding an old-fashioned PRINT statement.

I found this version of BASIC, created for the Arduino board, which runs some of the code on Arduino and the rest on a host. All math is done internally in floats, and it supports strings, string functions and both structured and line numbered versions of BASIC. I have been playing around with it and just ported it to macOS, and think I could get it working well on ELKS. There are a few problems still, since the ELKS libc doesn't (yet) support float display, etc. It could probably also be enhanced with float trig functions.

https://github.com/robinhedwards/ArduinoBASIC

The language it implements is shown on the first page. Both BASIC interpreters compile the language before running, and the Arduino BASIC allows for an explicitly-set size of memory buffer to use, without having to use malloc or expanding the interpreter memory size.

It has another advantage in that it has some statements that allow for turning on and off GPIO pins, which would be great for an embedded language. Let me know what you think, and whether this might be worth a porting effort. It seems that our ELKS compilers supports doubles (better than floats) and does not require an 8087/FP chip, so everything would be done soft-float.

Thank you!

cocus commented 2 years ago

I think the ArduinoBASIC seems like a better choice. Let's split this issue up into another ticket (like "Porting BASIC to ELKS"), since the networking and IRQ-related changes for the 8018x are already merged.