MBR hack for serial console

John Baldwin jhb at freebsd.org
Fri Aug 28 13:44:29 UTC 2009


On Thursday 27 August 2009 11:36:09 pm remodeler wrote:
> This is in response to John Baldwin's response to my question about using a
> non-legacy IO port for an i386 serial console.
> 
> I notice that src/sys/boot/i386/boot0/boot0.S uses a call to the PC BIOS int
> 14h routine to access the serial console, if SIO is defined. I believe SIO is
> defined if make.conf specifies a port for BOOT_COMCONSOLE_PORT (though I'm
> probably wrong), in which case the boot0 executable would be made from
> src/sys/boot/i386/boot0/boot0sio when recompiling the boot blocks with:
> 
> # cd /sys/boot
> # make clean
> # make
> # make install
> 
> The 14h pc bios routine is definitely limited to 0x3F8, 0x2F8, 0x3E8, or 0x2E8
> because it is called with the DX register set to specify COM1-COM4 (dx set to
> 0, 1, 2, or 3).

That's probably true that the BIOS routines likely do not handle a serial port
in an add-on card.  However, just setting the I/O address to 03xf8 may not make
the BIOS routines work either since the BIOS may know that there isn't a COM1
on the motherboard so it may just fail I/O w/o trying.

> boot2 looks like I might be able to specify the 0xe800 address for the serial
> console. src/sys/boot/i386/boot2/sio.S has this definition: .set
> SIO_PRT,SIOPRT but I am not sure where SIOPRT is set. I don't see if in any
> makefile. I would guess it is being set by BOOT_COMCONSOLE_PORT also?

Correct.  It's set via 'CFLAGS' in boot2's Makefile.

> > if the device is behind a PCI-PCI bridge (which it probably is 
> > if it is on bus 3) you have the problem that 0x3f8 is probably not
> > in the IO range decoded by the parent bridge
> 
> The device is behind a bridge: pcib0 --> pci0 --> pcib3 --> pci3, but AMD
> doesn't have a data sheet available on the 'net to tell me what IO range is
> decoded by the parent bridge (750SB southbridge chip).

A verbose dmesg will tell you as it isn't a fixed range but it assigned by the
BIOS just like a BAR.

> I also notice in the PCI specification this ("I/O Space Address Decoding for
> Legacy Devices"):
> 
> A function that supports a PC legacy function (IDE, VGA, etc.) is allowed to
> claim those addresses associated with the specific function when the I/O Space
> (see Figure 6-2) [the configuration space's Command Register layout, bit 0]
> enable bit is set.
> 
> These addresses are not requested using a Base Address register but are
> assigned by initialization software. If a device identifies itself as a legacy
> function (class code), the initialization software grants the device
> permission to claim the I/O legacy addresses by setting the device’s I/O Space
> enable bit.

Note the 'not requested using a BAR' part of the quote.  :-/  The way these
transactions are handled by PCI-PCI bridges is there is a bit that effectively
instructs the bridge to claim legacy I/O or VGA ranges.  However, the PCI-ISA/LPC
bridge device probably is already setup that way so that I/O accesses to the RTC,
keyboard controller, etc. all work.

> >  read the current value of the BAR instead and use that address?
> 
> If I can set the serial console to a non-legacy port in boot2, that would be
> ideal. I don't think the boot0 routine would cause problems; it is just
> looking for keystrokes AFAIK. In this approach, I would guess it would make
> sense to read the value and set SIOPRT to it in boot2? I think from this point
> on, the serial console calls use sio.S, and these functions (sio_init, etc.)
> access the hardware directly with assembler out commands rather than using the
> PC BIOS routines like boot0. Would something as simple as:
> 
> .set SIO_PRT,0xe800
> 
> in src/sys/boot/i386/boot2/sio.S work? If it does, I can develop code to read
> and set it to the current port instead of hard-coding it.

Yes, I would try that.  You can also just do 'BOOT_COMCONSOLE_PORT=0xe800' to
see if that will work as a test w/o having to modify any of the boot2 code
directly.

-- 
John Baldwin


More information about the freebsd-hackers mailing list