For use only on NTSC Genesis Systems.
Avatar image by CyanSorcery!


Tumblr (inactive)
tumblokami.tumblr.com/
Twitter (inactive)
twitter.com/Techokami

jckarter
@jckarter

It doesn't look like support for FM TOWNS hardware was ever upstreamed into the official Linux kernel source, but Osamu Kurachi has been maintaining patches against Linux kernel versions up to the present-day Linux 6.7.0:

It took me a bit of hunting to find this page, so here's hoping Cohost's SEO juice makes it easier for the next person.


jckarter
@jckarter

Just for fun, I built a kernel using the Linux 6.9 (nice) source and Kurachi's FM TOWNS patches, and booted it on my FM TOWNS SN. Something is wrong with the console driver though...


jckarter
@jckarter

After trying a few different variants of kernel settings to no avail, I went to the source code. Unlike IBM-compatible PCs, the FM TOWNS doesn't have anything like a VGA adapter, and its custom graphics processor doesn't have a true text mode. But since the TOWNS port far predates the standard framebuffer console in modern Linux, the patch set instead heavily alters the vgacon text-mode console driver into an ad-hoc framebuffer console of sorts. The altered driver supports user-provided console fonts, like the standard VGA console driver does, and it initializes itself using the font in the FM TOWNS ROM. It does so using this loop:

static void ank_user_font_init(void)
{
    unsigned long flags;
    unsigned long code,i;
    unsigned long ankbase, src_addr, dest_addr;

    ankbase=((unsigned long) towns_vram_base) +(1024*512)+0x3d800;
    for(code=1; code<0x100-2; code++) {
       src_addr = ankbase + (code<<4);
       dest_addr = ((unsigned long) ank_user_font8x16) + (code<<4);
       if (code < 3) { // ank transfer wait
           pr_info("ank xfer:code=%ld src=0x%lx dst=0x%lx: ",code, src_addr, dest_addr);
       }
       raw_spin_lock_irqsave(&vga_lock, flags);
       __asm__("cld\n\t"
               "movsl\n\t"
               "movsl\n\t"
               "movsl\n\t"
               "movsl\n\t"
               :
               :"D" (dest_addr),
               "S" (src_addr));
       raw_spin_unlock_irqrestore(&vga_lock, flags);
       for(i = 0; i < ANK_XFER_WAIT ; i++) outb(0, 0x6c); /* wait */
    }
}

The asm immediately stood out to me. It copies the font information from ROM to the driver's user font buffer using four movsd (movsl in AT&T syntax) instructions, each of which loads four bytes from the address in the register ESI, stores a copy of them to the address in register EDI, then increments both ESI and EDI by four to point to the next value. The "D" (dest_addr), "S" (src_addr) constraints on the asm tell the compiler to assign the dest_addr variable to the EDI register and the src_addr to ESI. However, these are read-only constraints, and the movsl instruction modifies the registers. The compiler doesn't look into the contents of asm instructions, though, and continues to generate code assuming that it can still use the values in ESI and EDI that it put there before the assembly executed. The asm instruction also fails to indicate that it clobbers memory, so the compiler might move it around assuming it has no side effects.

Anyway, I replaced the above code with a memcpy, and now I can clearly see the kernel panic message. Time to figure out what's causing the panic… The 0F A2 instruction it's trapping on is a CPUID instruction, which came with the Pentium. It looks like it's trying to load microcode, which definitely isn't a thing for a 486 processor like this, so hopefully I just need to compile that part of the kernel out.


jckarter
@jckarter

I splatted a Gentoo stage3 tarball into a fresh ext4 filesystem (since of course Gentoo still provides i486 builds), and after several minutes of very slow initialization, got the SN to successfully boot to the login prompt! The kernel panicked when I pressed the CTRL key though…

To get this far, I haven't had to make any further source hacks, just mess with kernel config flags:

  • I had to disable CONFIG_SUP_AMD to leave out the AMD microcode loader, which is extremely not a thing for 90s CPUs and contained instructions too new for the 486 to execute
  • The FM TOWNS framebuffer driver changes the display mode on initialization, messing up the vgacon console rendering code. I disabled the framebuffer driver for now.
  • The FM TOWNS partition format driver looks like it only picks up partitions created with the MS-DOS partition type. I had tried to be cute and set up the ext4 partition as XENIX type, but the kernel pretended it didn't exist after that.

Something is clearly amiss in the keyboard driver, since even before panicking when I touched the keyboard, the dumpkeys tool was OOPSing and getting killed when the init scripts tried to save the keymap.


You must log in to comment.

in reply to @jckarter's post:

in reply to @jckarter's post:

Yeah, I've been stumped trying to think through exactly how this glitch is occuring. Why do the [] brackets get reliably printed? How does it print the "kernel panic" message with only dropped letters while the other messages have a mix of dropped and corrupted characters?