-
DRAM Controller and Verilog Simulation
09/19/2024 at 23:36 • 0 commentsMackerel-10 now has a functioning DRAM controller and a serious boost to its total RAM in the form of two 4MB 30-pin SIMMs. With the 1MB of onboard SRAM, this brings the total usable memory to 9MB. Adding DRAM to any homebrew project always felt to me like a major milestone on the way to building a “real” computer. While it’s a long way from the complexity of modern DDR, it’s a significant step up in both complexity and capability compared to stacking a bunch of SRAM together (e.g. Mackerel-08).
Mackerel-10 prototype with attached DRAM controller board I’m hardly the first person to add DRAM to a 68k system and I want to call out and thank a few projects I found to be terrific references while I was putting this together:
- Lawrence Manning's MINI020 (and the rest of his 68k projects)
- Tobias Rathje's T030
- Stephen Moody's Y DdraigAll three projects implement some form of DRAM with a 68k CPU and I borrowed liberally from their implementations and write-ups. Thanks for sharing!
The best decision I made while working on this was definitely taking the time to setup a Verilog testbench to simulate my implementation before trying to debug it on real hardware. In fact, I wrote the controller and simulator before I had any design for the hardware. Seeing the Verilog behave as I expected gave me a lot more confidence in my PCB design and saved a ton of time during board bringup.
There are plenty of testbench tutorials out there and this is not one of them, but I used iverilog and GTKWave to simulate my design. Although I’m building and flashing the CPLD with Quartus (which includes ModelSim), I’d rather not spend a second longer than I have to in that program.
There are two areas that make dynamic RAM more complicated to deal with than static RAM. The first issue is that the address pins on the SIMMs are not all exposed as they are on SRAM. Instead, they are multiplexed into rows and columns. This means that reading and writing data is no longer as simple as putting the full address on the bus. The basic read cycle for DRAM looks like this:
1. Split the 24 bit address bus of the 68000 into row and column addresses (11 bits each in the case of 4 MB SIMMs)
2. Write the row address to the SIMM’s address pins and assert the RAS (row address strobe) line
3. Write the column address to the SIMM’s address pins and assert the CAS (column address strobe) line
4. Read or write the resulting dataConceptually not too difficult to comprehend, but care has to be taken to meet the timing requirements at each one of these stages. My implementation handles this with a finite state machine. Each step in the DRAM cycle corresponds to one or more states in the FSM. Here’s what this read cycle looks like in simulation:
Simulation of a 16-bit DRAM read cycle Once the DRAM responds with valid data, the controller will bring DTACK LOW and hold the data on the bus until the CPU brings the AS line HIGH, ending the memory cycle. This hold time is exaggerated in the simulation. A write cycle is almost identical except the WE pin on one or both SIMMs is asserted.
The other challenge involved in using DRAM is the need to constantly refresh the memory cells. Every cell in the array has a maximum amount of time it can hold a value before decaying (DRAM is just a giant grid of capacitors). Refreshing a cell means reading it and immediately writing it back to restore the charge in the capacitors. Fortunately the DRAM chips provide a few ways to deal with this. The method I chose is CAS-before-RAS refresh. In a normal memory access cycle, RAS is asserted and then CAS is asserted. If the reverse is done, the DRAM will run a refresh instead. The DRAM chips are also kind enough to maintain internal addresses for the next refresh target, so all we have do is run a refresh cycle frequently enough to keep all of the cells topped off.
Simulation of a single CAS-before-RAS refresh cycle Here you can see the relatively simple process of asserting CAS and then RAS. Each address has to be refreshed roughly every 16ms, so the frequency of the refresh cycle will depend on the total size of the DRAM. The state machine ensures that a refresh cycle takes precedence over a normal memory access cycle, so occasionally memory access by the CPU will be delayed slightly until the refresh is finished. This is not noticeable in normal operation, but it does technically slow down the system ever so slightly. That’s the trade-off for massively higher memory density compared to SRAM.
With all of this extra RAM, Mackerel-10 was ready to boot uClinux for the first time. Some minor updates to the bootloader and the kernel’s memory map were required, but Mackerel-10 now runs Linux. It’s great to see the kernel with all of that free memory - so much room for activities.
-
Mackerel-10 is up and running!
09/02/2024 at 01:01 • 1 commentAlthough the CPU, ROM, and RAM were simple enough to get running, I struggled quite a bit more with the DUART. I assumed it would be simple enough to port my glue logic and software from Mackerel-08, but there are a lot of moving parts in the 8-to-16-bit transition that all need to change at once. Testing just the hardware or just the software in isolation isn't really possible.
The first hurdle was proving that the DUART was connected correctly and that it could be addressed at the appropriate memory addresses. I thought I was making my life easier when I set up some memory-mapped LEDs in the CPLD. Eventually this was extremely useful, but only after I remembered to add the RW pin to the decoding logic for it. This issue and my general inexperience with Verilog cost a few hours of debugging time, but eventually the serial port was screaming `AAA...`.
Mackerel-10 first prototype fully assembled With a working serial port, my attention turned to software. I've already got a bootloader/monitor tool for Mackerel-08 that works well, so I started porting that to the new board. The two big changes going from the 68008 to the 68010 are a new memory map and the 16-bit wide ROM. The memory map is simple enough - just copy the .scr files from Mackerel-08 and modify the ROM and RAM locations to match up with the address decoding in the CPLD.
Since each ROM chip is only 8-bits wide, but they are both addressed simultaneously by the CPU, the resulting binary code needs to be split in half. The simple way to do this is using `objcopy`. I updated the Makefile to do this:
%-upper.bin: %.bin $(OBJCOPY) --interleave=2 --byte=0 -I binary -O binary $< $@ %-lower.bin: %.bin $(OBJCOPY) --interleave=2 --byte=1 -I binary -O binary $< $@
I found an example of this on Lawrence Manning's blog. He's built a few different 68k machines and I've learned a lot reading through his posts about them.
While I was making changes to the Makefile, I added support to build all of the existing code for either Mackerel-08 or Mackerel-10. There are a few #ifdefs in the C code to handle the differences in hardware, but most of the heavy lifting is done by the Makefile itself.
A working serial port and a working bootloader meant I no longer had to pull and flash two ROM chips for every code change. I could use the serial bootloader and load code directly into RAM. Note to self: ZIF sockets would have been worth the extra board size and cost on a first prototype. My fingers are sore from pulling the ROMs so many times.
The final subsystem left to debug was interrupt handling. I ported the GAL logic from Mackerel-08 into Verilog for the CPLD and I set up all the pin mappings. Annoyingly, as soon as I enabled interrupts at all, the system would immediately receive one and jump to the unhandled user interrupt exception handler. After carefully checking the Verilog and C code, I realized that the DUART's IRQ output was always low (i.e. active). It turns out that I forgot to put a pullup on that line in Mackerel-10. Mackerel-08 has one and the datasheet specifies one as well. With the pullup in place, the vectored interrupts from the DUART were working just as they do on Mackerel-08.
Bodged pullup on the DUART's IRQ output (connected on the CPLD side of the trace) With that small bodge in place, Mackerel-10 is fully tested. It functions just as well as Mackerel-08 minus some RAM and storage. The next step is to start implementing a DRAM controller!
Once I was happy that the 68010 was working, I had to push my luck and try this adapter for the MC68SEC000 that I made. It's designed to be a drop-in replacement for the DIP-64 processor. I assembled this adapter using the drag soldering method and plenty of liquid flux. I manually cleaned up a handful of bridges and scrubbed the excess flux away with alcohol then soap and water. I'm quite happy with the end results. I am even happier that it functions just fine slotted into Mackerel-10.
Drop-in adapter board converts a MC68SEC000 CPU to a DIP-64 68000/68010 slot The icing on the cake is the insane clock speed. I was running the 68010 at its full 10 MHz rating, but this 20MHz-rated SEC CPU actually ran perfectly for me at 40 MHz! I didn't do exhaustive testing at this speed, but the monitor ran just fine and the memory and DUART seemed to have no issues keeping up. This definitely warrants some stress testing and I still plan to design around the 68010 primarily, but I am really looking forward to seeing how uClinux runs at 40 MHz and how far I can push the speed (40 MHz is the fastest oscillator I currently have on hand).
This adapter PCB is available on Github: https://github.com/crmaykish/adapters-and-breakout-boards/tree/main/MC68SEC000-to-DIP-64
-
Mackerel-10 Beginning Board Bringup
08/30/2024 at 03:29 • 0 commentsThe next batch of PCBs have arrived. I spent an evening soldering and debugging the first prototype of Mackerel-10. I have only gotten as far as connecting the CPU, ROM, and RAM to the CPLD. The DUART is not working yet, but the 68010 is running C code that controls a memory-mapped LED register on the CPLD. No catastrophic design issues so far. Next step is to get the serial port working and modify some of the Mackerel-8 code to run on the new system. Without DRAM, I won't be able to run uClinux 4.4, but 2.0 should fit in the 1MB of onboard SRAM. I'd like to see that running on this hardware before I move ahead with a DRAM controller.
Mackerel-10 in the middle of board bring-up In other news, Revision 1.1 of Mackerel-08 has also been assembled and mostly tested. It boots to a monitor prompt and passed my RAM test for all 3.5MB. I need to make a few small modifications to the code to support the new SPI layout, but things are looking good. Once SPI is working and I can stress test uClinux, I think Mackerel-08 is approaching hardware completion. I can continue to work on the software/Linux side, but it will be nice having a solid baseline going forward.
Mackerel-08 Rev 1.1 assembled -
Prototyping a 68010 Upgrade
08/22/2024 at 19:30 • 0 commentsThe goal of the Mackerel project has always been to slowly work my way through the Motorola 68k CPU family, building new computers with each iteration. With Mackerel-08 fully operational, it's time to start thinking about its bigger brother, the 68000. Since building the same computer again with a faster CPU is not that interesting or enough of a challenge on its own, I'd like to add enough additional complexity with each new CPU to justify calling this a new computer.
For Mackerel-10 that means three things:
1. 68000/68010 CPU - either CPU should work in this system, but I will likely be using the 68010 for the relocatable vector table and the potentially higher clock speeds.
2. DRAM - this is the big one. uClinux will definitely take advantage of more RAM and I plan to fill almost the entire 16MB address space of the 68010 with DRAM. I have a 4x4MB kit of 30-pin SIMMs and the appropriate sockets. I will be building a DRAM controller in an Altera EPM7128 CPLD to utilize it.
3. IDE - Mackerel-08 has persistent storage in the form of a bit-banged SD card, but it is quite slow (somewhere around 3-5 kbps at best). I would like Mackerel-10 to have a full IDE interface for use with a real hard drive or a CF-to-IDE adapter.
Although I just said building the same computer again is not the goal, that's basically what I've done here:
Mackerel-10 mainboard first prototype design There are enough changes going from the 68008's 8 bit data bus to the 68010's full 16-bit bus and I've switched from using 22V10C GALs to a EPM7128 CPLD for glue logic, so I'd like to build this core system before adding DRAM and IDE hardware. This is also the first computer design I've done without building a hand-wired prototype or breadboard proof-of-concept first. Fingers crossed.
This first PCB includes the 68010 CPU, 1MB each of ROM and SRAM, and the same XR68C681 DUART as Mackerel-8. If all of this works as expected, I will build a second board for the IDE and DRAM. This can connect back to the main system via the two 40 pin box headers. Once that second board is proven, I'll combine the designs back into one SBC, probably using the ITX form factor.
As an additional little diversion, I've purchased some MC68SEC000 CPUs. They are rated to 20MHz, but I have read that many of them are stable at 50 MHz or higher. Sounds exciting! The SEC variant is basically a static version of the 68EC000 CPU, which is itself, a CMOS version of the 68000. I think it should be drop-in compatible with the original 68000 footprint provided there's an appropriate adapter. I was inspired by the Minimig project, but I couldn't find a source for their adapter, so I made my own:
MC68SEC000 QFP-64 to DIP-64 adapter PCB I don't know if this will actually work, but it should be an interesting experiment. KiCAD project and Gerbers are available for this adapter on Github, but use at your own risk. This is still untested.
https://github.com/crmaykish/adapters-and-breakout-boards/tree/main/MC68SEC000-to-DIP-64
-
Fixing Some PCB Issues On Mackerel-08
08/22/2024 at 17:38 • 0 commentsThe Mackerel-08 PCBs have been working great for a few weeks, but that doesn't stop me wanting to tinker with the design. There were a few minor issues with the PCB (mostly cosmetic) and a few design decisions I wanted to change. Consider this patch notes for Mackerel-08 v1.1.
1. Corrected a few typos and errors in the silkscreen labels, including the expansion header pins
2. Changed the SD header to fit an Adafruit microSD breakout, also connected card detect pin to a DUART input pin.
3. SPI headers are condensed into a dual row pin header instead of box connectors
4. Expansion headers now expose all address lines and CPU control signals
5. Changed the footprint for the two oscillators to accept either DIP-8 or DIP-14 size cans
6. Added/removed some pullup resistors
7. Add a 5v switching regulator to the board. DC input is now 7-15VDC
8. Changed all resistors to 1206 SMD and placed them on the back of the board
Not exactly a huge overhaul, but the on-board regulator and full expansion header will prove useful in developing additional hardware for the board.
The updated schematic PDF and Gerbers are on Github: https://github.com/crmaykish/mackerel-68k/tree/master/releases/mackerel-08/v1.1
Mackerel-08 v1.1 render -
Mackerel-08: First PCBs Are In
08/03/2024 at 15:12 • 0 commentsThe first PCBs for Mackerel-08 v1 are in and I'm happy to say they're not dead-on-arrival. I had to update some of the PLD logic and I spent an embarassingly long time debugging the DUART only to realize that I was plugged into the wrong serial port, but Mackerel is alive and well.
Just enough hardware to get up and running I'm still waiting on a few of the components (DC barrel jack connectors, for example) and as always, there are a few minor issues with the design I need to correct, but they are mostly cosmetic or mechanical, at least so far. The labels on the 5V and USR LEDs are swapped and I think I will change the layout of the serial port and SPI headers in the next revision, but these are small issues.
Another thing I realized only after I ordered the boards is that I did not expose the /VPA pin on the expansion header. This will prevent any additional hardware from using autovectored interrupts This is annoying, but I don't have any immediate plans to use it so I'll have to live with it for now.
I've only got 512KB of RAM and 512KB of ROM installed, but that's enough to test the bootloader and uClinux 2.0, both of which are working as expected, fully stable at 16 MHz even. Once I order more RAM or scavenge some from the hand-wired prototype, I'll fill out the empty sockets and get 4.4 booting, but I'm confident that will be smooth sailing.
The main features left to test besides the full RAM config are SPI and DTACK generation. Until now I've always had DTACK grounded. This has worked fine with the fairly modern and fast memory and DUART I'm using, but I'd like to have a real DTACK generator for flexibility. The unpopulated third PLD slot on the top right is responsible for this. There's a jumper near the CPU to select DTACK grounded or to use the DTACK generation PLD.
Glue logic PLDs - DTACK is grounded at the moment SPI testing is just a matter of wiring up the SD card and updating the bitbang code with the new pinouts.
It always feels good when a design works as expected. I'm looking forward to spending some time playing around with this board and polishing up some of the software and documentation.
-
Mackerel-08 SBC v1: Ready For Manufacturing!
07/26/2024 at 23:19 • 2 commentsAfter tearing everything up and restarting at least three times, I've finally got a PCB design I like. I don't think it's possible to be completely satisfied with a PCB when you've spent hours staring at it, but the important thing is that it’s done and ready for a prototype.
The hardware is largely the same as the backplane system I’ve been hacking together since the start of the project, but it’s all on one board. Here’s a quick overview:
- 68008 CPU: Mackerel uses the 52-pin variant for 4MB of address space
- 512 KB Flash ROM: Only 492 KB are usable as the rest of the address space is used for memory-mapped I/O.
- 3.5MB of SRAM: This does look a bit silly on the board, but it’s simple to wire and use.
- XR68C681 DUART – The workhorse of the system, providing two serial ports, a timer interrupt, and now bit-banged SPI. The two serial ports are connected to “standard” FTDI USB adapter headers. These are pretty common and what I personally use. The pins are all labeled, so they could easily be adapted to another style of adapter with a few jumper wires.
- Expansion header – I crammed as much as I could into a single 2x20 pin header. Dropping the high address bits seemed like a reasonable compromise since all of that address space is already filled with RAM. There’s room for a single peripheral device (or more with additional off-board decoding) with interrupt and DTACK support.
- SPI headers – A new addition to the system, using the DUART’s I/O pins to bitbang SPI/SD card connections.
One of my major goals when I started Mackerel was to build the simplest SBC that could run "modern" uClinux with a m68k CPU (i.e. not kernel 2.0). I don’t know if this counts as simple anymore, but it is most definitely a single-board computer. I’ve also designed the board with 100% through-hole components. Technically the two PLCC parts are surface-mount, but their sockets are through-hole, so the soldering is easy.
There are a few by-design limitations of Mackerel-08 (some of which can be addressed in future revisions):
- As mentioned earlier, the expansion header is only exposing the lowest 16 bits of the address bus. As this board is intended to be used with lots of onboard RAM, this should not be a major issue, but it prevents some “off-label” uses. Time will tell if the compromise was a good one.
- I have not included any of the bus mastering or synchronous/8-bit peripheral pins. Personally, I don’t have a need for these. They’re both a bit out of scope for the goals of the Mackerel project.
- Only two interrupts are mapped. IRQ level 1 is connected to the DUART and IRQ level 2 goes to the expansion header. Again, this is mainly to keep hardware complexity to a minimum. Since it’s possible to map multiple interrupt sources onto the one interrupt input on the expansion header (with additional decoding hardware), this should also not be a huge limitation. The trade-off is that the interrupt handlers would have to do more work to determine the source of the interrupt.
This is not designed to be a do-everything system. I’ve mainly focused on the hardware required to get Linux running and deferred everything else for future iterations.
I’ll be submitting the PCB to the manufacturer in the next day or two once I’m convinced I haven’t missed anything obvious in the design (there’s always something, right?). IWhile I wait for delivery, I’ll be working on a Linux driver for my new SPI/SD card hardware and cleaning up some documentation.
I’ll post the v1 schematic in PDF form here and once I get the boards delivered and brought up, I’ll be able to share the Gerbers as well. All of the design files and code already exists on Github if you want to check it out.
https://github.com/crmaykish/mackerel-68k
https://github.com/crmaykish/mackerel-uclinux-20160919
For the curious, here's what the routing looks like (inner power and ground planes not shown):
-
uClinux 4.4 Fully Working On 68008!
07/21/2024 at 01:59 • 2 commentsIt never fails that as soon as you show someone (or in this case, post about it on Hackaday) the problem you’ve been having for days , you immediately see the solution, a perfect example of rubber-duck debugging. Most of my recent issues with Mackerel have a lot to do with me forgetting what in the world I was doing two years ago when I started this project. Since picking it back up recently, I often take for granted that decisions or code changes I made in 2022 were actually correct. They were not.
Mackerel’s memory issues are solved. For whatever reason, I had XIP (execute in place) disabled for my kernel build. If you’re not familiar, normally when Linux runs an executable, it has to copy it into RAM first (usually from a drive of some kind). XIP allows programs located in ROM to skip this step and, you guessed it, execute in place. You can probably see where this is going. With XIP disabled, every program I would run had to be copied into Mackerel’s extremely limited RAM. The issue is exacerbated by the fact that no MMU means no shared libraries, so all the binaries are statically linked and quite large. With XIP back in place, Mackerel runs uClinux 4.4 beautifully with 3MB RAM (technically 3.5MB, but 512KB is used for the ROM filesystem and not available to the kernel).
I’m currently using busybox as both init and most of the userspace programs with the exception of expand and nwsh. I also included busybox’s hush shell for running bash-like scripts, but I prefer nwsh as the actual user shell. This config has been working well. When busybox as init starts, it mounts the RAM filesystem, sets up /proc, and starts a root nwsh shell. At this point, it operates like any other Linux machine.
RAM is still very much constrained, but no longer a deal-breaking issue. While running some simple shell programs, free memory floats around 800KB. There’s obviously no swap space, so there’s still a risk of OOMing with a huge program or some bad scripting, but it’s functional and stable.
So exciting to finally see this working after more than two years – a “modern” kernel running on a CPU manufactured in the early 90s and designed in the early 80s!
Here’s a quick demo of the boot process and some basic shell commands:
-
Linux 4.4 On A 68008? Technically, Yes!
07/20/2024 at 04:34 • 0 commentsEdit: Oops! This issue has been fixed... see my next post: https://hackaday.io/project/183861-mackerel-68k-computer/log/231396-uclinux-44-fully-working-on-68008
---
I lied in my last update when I said my next post would be board bring-up for a Mackerel-08 SBC. That still is the plan, but I couldn't shake the feeling that I should give Linux 4.4 another chance. I didn’t want to finish a PCB design only to realize I missed some small thing needed to run the newer kernel. Long story short, Mackerel runs Linux 4.4, but only just barely.
# mount -t proc proc /proc # hostname mackerel-08 # uname -a uClinux mackerel-08 4.4.0-uc0 #2 Fri Jul 19 23:45:06 EDT 2024 m68k GNU/Linux # cat /proc/cpuinfo CPU: MC68000 MMU: none FPU: none Clocking: 13.4MHz BogoMips: 1.67 Calibration: 838400 loops
While Linux 2.0 boots and runs indefinitely with good stability, 4.4 is functional for a time, but very quickly runs into a number of memory-related issues. Typically after running a handful of commands from the shell, I will see a page allocation failure, or an OOM message from the kernel, or sometimes the system will just throw an address exception or stop responding entirely.
Although it seems obvious that the problem is just a lack of RAM, I wanted to be sure. I wrote some test applications in userspace to stress a few different areas of the system. I checked the newly-written serial driver. I looped malloc and free and looked for issues, but one-off programs ran for hours without any problems. Running new commands from the shell seemed to be the cause of the memory issues.
Mackerel-08 has 3.5MB of RAM installed in its maximum configuration. The kernel takes up about 1MB of that, the root filesystem is between 256KB and 512KB. Down to 2MB before init even starts…
Memory: 2040K/3072K available (723K kernel code, 35K rwdata, 96K rodata, 40K init, 42K bss, 1032K reserved, 0K cma-reserved) Virtual kernel memory layout: vector : 0x00000000 - 0x00000400 ( 1 KiB) kmap : 0x00000000 - 0xffffffff (4095 MiB) vmalloc : 0x00000000 - 0xffffffff (4095 MiB) lowmem : 0x00000000 - 0x00300000 ( 3 MiB) .init : 0x000d6000 - 0x000e0000 ( 40 KiB) .text : 0x00000400 - 0x000b5120 ( 724 KiB) .data : 0x000b5120 - 0x000d5d20 ( 131 KiB) .bss : 0x000e0000 - 0x000eab8c ( 43 KiB)
I stripped userspace to the absolute minimum – no init, just boot right to /bin/nwsh (a minimalist shell). Even with this setup, the kernel eats up some additional free RAM and Mackerel is left with barely 800KB of free RAM.
# free total used free shared buffers Mem: 2080 1264 816 0 0 -/+ buffers: 1264 816
Very simple programs run just fine, but anything even slightly complex (like cat or mount) can potentially request enough RAM or cause a page allocation to OOM the system. This is all a long-winded way to say that Mackerel just does not have enough RAM! The problem, of course, is that the 68008 can only address up to 4MB (slightly less with ROM and I/O mapped) by design. I think I’ve found the limits of the system. Just for my own sanity, I looked for any examples online of the 68000 series running Linux with less than 4MB of RAM. I couldn’t find any. 68 Katy runs 2.0 and Luis Alve’s Alcetronics M68k runs 3.x, but his board had 8 MB of RAM.
I’m still far from a Linux kernel expert. Maybe there are some tweaks I could do to the allocator or kernel config that would improve the memory situation, but to be honest, I don’t think it’s worth much more time. I proved that Linux 4.4 can run a 68008 and that’s enough for now. Even all of the old SBCs used as examples in the uClinux source code seems to have 8MB or more.
from https://linuxdevices.org/teeny-weeny-linux-sbcs/ For the record, I ran all of these same tests on 3.x and had the same issues. The difference in size and RAM usage between 3.x and 4.x is negligible.
Meanwhile, I have continued to improve the config for my Linux 2.0 build. I’m quite happy with how well it functions as a self contained little system. I’m able to fit the kernel, sash, some useful busybox tools, and vi into a single 512KB ROM. This includes a ramfs that gets mounted automatically on boot to provide some (temporary) writable storage. I even got the 68008 running at 16 MHz. I'd like to find some kind of BASIC or simple interpreted language that I could compile and run so that Mackerel-08 is fully programmable without the help of a build PC, possibly Lua or MicroPython.
Immediate plans are still the same then – design and build a Mackerel-08 SBC. The good news is that don’t have to stress about the board not supporting some hypothetical Linux build. I’ll target 2.0 and that’s enough. I’ll revisit more modern kernels when I upgrade the CPU and lift the 4MB memory limit.
-
Linux In A Half Meg Of ROM
07/14/2024 at 01:02 • 0 commentsMy port of the uClinux 2.0 kernel is now bootable from a single 512KB ROM. For active development, it's still easier to use the serial loader to get Linux into memory, but having the kernel and filesystem in ROM makes for a nice self-contained demo. It's also "instant"-on, or at least it's one command to boot Linux now instead of the back and forth of the bootloader and serial transfer program.
Although, the kernel fits in ROM, there's very little room to spare. There are 524288 total bytes in the EEPROM and the allocation looks like this:
Bootloader: 8192 Linux text: 256176 Linux data: 27696 ROM fs: 231424 Total: 523488
524288 - 523488 = 800 bytes to spare
To be fair, this does include Colossal Cave Adventure which feels like a necessary component to me.
Because I'm using the 52-pin variant of the 68008, I have 4 MB of address space to play with. There's nothing stopping me from adding more ROM, but that approach will only go so far. Linux at idle is only using about 200k of the 2MB of RAM currently installed, but that number is sure to go way up with more applications or a newer kernel. At some point I'll need to maximize the amount of RAM available and load Linux from external storage anyway, but I'm very happy that Mackerel is now self-contained. Connect power and serial and it's a Linux machine.
uClinux/MC68000 Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne KERNEL -> TEXT=0x302000-0x33b3b8 DATA=0x000400-0x007030 BSS=0x007030-0x01543b KERNEL -> ROMFS=0x3474e0-0x37f920 MEM=0x015440-0x1fc000 STACK=0x1fc000-0x200000 Mackerel 68k support (C) 2024, Colin Maykish Calibrating delay loop.. ok - 1.27 BogoMIPS Memory available: 1908k/2031k RAM, 0k/0k ROM (2804k kernel code, 124k data) Swansea University Computer Society NET3.035 for Linux 2.0 NET3: Unix domain sockets 0.13 for Linux NET3.035. uClinux version 2.0.39.uc2 (colin@crm-x1-g6) (gcc version 2.95.3 20010315 (release)(ColdFire patches - 20010318 from http://fiddes.net/coldfire/)(uClinux XIP and shared lib patches from http://www.snapgear.com/)) 15 Sat Jul 13 07:27:58 PM EDT 2024 XR68C681 driver version 0.1 by Colin Maykish ttyS0 at 0x00000000 (irq = 1) is a XR68C681 Ramdisk driver initialized : 16 ramdisks of 4096K size Blkmem copyright 1998,1999 D. Jeff Dionne Blkmem copyright 1998 Kenneth Albanowski Blkmem 1 disk images: 0: 3474E0-37FCDF (RO) VFS: Mounted root (romfs filesystem) readonly. Shell invoked to run file: /etc/rc Command: hostname mackerel-68k Command: /bin/expand /etc/ramfs.img /dev/ram0 Command: mount -t proc proc /proc Command: mount -t ext2 /dev/ram0 /var Command: mkdir /var/tmp Command: mkdir /var/log Command: mkdir /var/run Command: mkdir /var/lock Command: cat /etc/motd __ __ _ _ __ ___ _ | \/ | | | | | / / / _ \| | | \ / | __ _ ___| | _____ _ __ ___| | / /_ | (_) | | __ | |\/| |/ _` |/ __| |/ / _ \ '__/ _ \ | | '_ \ > _ <| |/ / | | | | (_| | (__| < __/ | | __/ | | (_) | (_) | < |_| |_|\__,_|\___|_|\_\___|_| \___|_| \___/ \___/|_|\_\ Execution Finished, Exiting Sash command shell (version 1.1.1) /> free total: used: free: shared: buffers: cached: Mem: 1953792 208896 1744896 0 77824 0 Swap: 0 0 0 />
I'm part way through a PCB design for this system and I've been debating how complicated I want to get with it. The feature-creep is real, but I think I will keep the SBC to a fairly modest configuration - 1MB of ROM, 2MB of RAM, and the 68C681 DUART. As cool as it is to run Linux in any form on this thing, the ancient 2.0 kernel and similarly-aged applications are fairly limited in what they can actually do.Once the PCB goes off to manufacturing, I'd like to pick up my work on uClinux 4.4. I'm hopeful that a much newer kernel and userspace will result in a Linux experience more similar to a modern PC, but I don't know that it will function within the 4 MB address space limits of the 68008. Maybe the 68EC000 or 68SEC000 in 8-bit mode would be close to a drop-in upgrade boosting the address space to 16 MB.
Either way, if all goes well, my next update will be bringing up the first PCBs for Mackerel-08 and closing the first major chapter of this project.
Github project links:
Mackerel-68k Main Project: https://github.com/crmaykish/mackerel-68k
uClinux port: https://github.com/crmaykish/mackerel-uclinux-20040218