Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Aug 2009 23:40:07 -0400
From:      "remodeler" <remodeler@alentogroup.org>
To:        freebsd-i386@freebsd.org
Subject:   MBR hack for serial console
Message-ID:  <20090826032224.M60545@alentogroup.org>

next in thread | raw e-mail | index | archive | help
I am hoping for input on a patch I want to apply to the MBR of a FreeBSD
8-BETA3 server. The FreeBSD build is AMD64, however I posted here because the
MBR source is in /usr/src/sys/boot/i386/mbr, and my understanding is that the
default boot loader components are all i386 architecture.

I want a serial console on this server as it will be remotely deployed. The
ASUS motherboard (amibios) has PCI and PCI-e expansion slots, and a Moschip
MCS9820 UART (serial board) is installed at pci0:3:5:0. The serial board
doesn't have firmware, so is not configured before the BIOS executes. The
serial board has a single Base Address Register at 10h. The BIOS can be
configured to enumerate the PCI bus (plug and play), or this function
disabled. Whether the PCI bus is probed by the BIOS or FreeBSD by loader, the
UART BAR is assigned the i386 I/O port address of 0xe800. To function as a
serial console, it must be assigned an i/o port address of COM1-COM4 (i.e.
0x3F8), as boot0, boot2, and loader all use the PC BIOS system calls.

I do not expect the hardware configuration to change. My plan is to patch the
MBR to override the serial card's BAR with 0x3F8. My reasoning is that the CPU
is still in Real mode (allowing direct hardware access) until loader executes;
I considered trying to script this in Forth and use the loader's FICL rc.d
scheme, but the CPU is in protected mode at that time; there is no PC BIOS
call to do this that would work in protected mode; and I do not understand the
ACPI driver that I believe I would need to access to do this in Forth. I have
experimented with using pciconf to change the BAR from a command line;
curiously the command:

pciconf -w pci0:3:5:0 16 1016

loads 0x3F9 into the serial card's PCI configuration space. I've worked up
this patch and hope someone can tell me why this would or wouldn't work:

/usr/src/sys/boot/i386/mbr/mbr.s

41,57d40
< # Patch to reconfigure PCI UART's Base Address to COM1
< # I count 40 bytes in opcode                          
< #                                                     
< startcon:     .set PCIADD_PORT,0xcf8          # Load pci config port addy
<               .set PCIDATA_PORT,0xcfc         # Load pci data port addy  
<               .set PCIADD,0x8003e810          # Load pci register identifier
<               .set PCIDATA,0x3f8              # Load pci register data      
<
<               pushad                          # save double registers
<               mov %ax,$PCIADD                 # put pci reg to access in ax
<               mov %dx,$PCIADD_PORT            # put pci config port in dx
<               out %dx,%ax                     # send to cpu i/o space
<               mov %ax,$PCIDATA                # put pci data in ax
<               move %dx,$PCIDATA_PORT          # put pci data port in dx
<               out %dx,%ax                     # send data to cpu i/o space
<               popad                           # pop saved registers
< #
166,171c149,151
< #
< # Instruction messages reduced to numbers, saves 60 bytes
< #
< msg_pt:       .asciz "1"                      # "Invalid partition table"
< msg_rd:       .asciz "2"                      # "Error loading operating system"
< msg_os:       .asciz "3"                      # "Missing operating system"
---
> msg_pt:       .asciz "Invalid partition table"
> msg_rd:       .asciz "Error loading operating system"
> msg_os:       .asciz "Missing operating system"

Thank you for any help. I am very out of my league on this, but the serial
console is very important for this server.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090826032224.M60545>