Download raw body.
sys/amd64: fallback to VGA text mode on headless systems
> Date: Fri, 30 Jan 2026 20:39:34 +0100
> From: Kirill A. Korinsky <kirill@korins.ky>
>
> On Tue, 27 Jan 2026 15:23:55 +0100,
> Kirill A. Korinsky <kirill@korins.ky> wrote:
> >
> > On Tue, 27 Jan 2026 13:18:50 +0100,
> > Crystal Kolipe <kolipe.c@exoticsilicon.com> wrote:
> > >
> > > On Tue, Jan 27, 2026 at 11:31:50AM +0000, Stuart Henderson wrote:
> > > > On 2026/01/27 12:05, Kirill A. Korinsky wrote:
> > > > > On Tue, 27 Jan 2026 10:21:02 +0100,
> > > > > Crystal Kolipe <kolipe.c@exoticsilicon.com> wrote:
> > > > > > Whilst it fixes your machine, how confident can we be that this is harmless on
> > > > > > others?
> > > > > >
> > > > > > It's perfectly valid to have no graphics hardware at all and run entirely from
> > > > > > a serial console, so this could plausibly break machines that are currently
> > > > > > working just fine.
> > > > > >
> > > > >
> > > > > Well, here my assumption that on amd64, both the VGA legacy memory region
> > > > > and I/O ports is still reserved and not used.
> > > >
> > > > if my reading is correct then I think that is ok in this case (but I'm
> > > > not 100%) ..
> > > >
> > > > boot> machine mem
> > > > Region 0: type 1 at 0x0 for 639KB
> > > > Region 1: type 2 at 0x9fc00 for 1KB
> > > > Region 2: type 2 at 0xf0000 for 64KB
> > > > Region 3: type 1 at 0x100000 for 2078296KB
> > > > Region 4: type 2 at 0x7ee96000 for 17832KB
> > > > Region 5: type 2 at 0xf8000000 for 65536KB
> > > > Region 6: type 2 at 0xfec10000 for 4KB
> > > > Region 7: type 2 at 0xfed40000 for 20KB
> > > > Low ram: 639KB High ram: 2078296KB
> > > > Total free memory: 2078935KB
> > >
> > > The VGA memory space is certainly marked as reserved.
> > >
> > > But 'reserved' doesn't mean that writing arbitrary values to those addresses
> > > is harmless.
> > >
> >
> > But for compatiblity it should stay reserved for VGA, and to reuse it for
> > something else BIOS should have two code paths: when VGA is avaialbel and
> > when it isn't.
> >
> > This is quite small region and introduce two code path seems strange.
> >
> > But, again, here many assumptions.
> >
>
> Here the second attempt. This time it is looks safer.
>
> Idea to scan PCI bus to find some VGA adapter and use it as primamary.
>
> More or less similar with Loongson's approach.
>
> It allows to boot this machine without serial and amdgpu and dmesg has:
>
> ~ $ grep vga /var/run/dmesg.boot
> vga1 at pci13 dev 0 function 0 "ATI Raphael" rev 0xc9
> wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
> ~ $
>
> which is expected.
>
> Thoughts? Tests? OKs?
What about my suggestion to have a dummy framebuffer?
> Index: sys/arch/amd64/amd64/wscons_machdep.c
> ===================================================================
> RCS file: /home/cvs/src/sys/arch/amd64/amd64/wscons_machdep.c,v
> diff -u -p -r1.14 wscons_machdep.c
> --- sys/arch/amd64/amd64/wscons_machdep.c 14 Oct 2017 04:44:43 -0000 1.14
> +++ sys/arch/amd64/amd64/wscons_machdep.c 30 Jan 2026 19:28:07 -0000
> @@ -35,6 +35,10 @@
> #include <dev/cons.h>
>
> #include "vga.h"
> +#if NVGA_PCI > 0
> +#include <dev/pci/pcivar.h>
> +#include <dev/pci/vga_pcivar.h>
> +#endif
> #include "pcdisplay.h"
> #if (NVGA > 0) || (NPCDISPLAY > 0)
> #include <dev/ic/mc6845reg.h>
> @@ -150,6 +154,11 @@ wscn_video_init(void)
> #endif
> #if (NPCDISPLAY > 0)
> if (pcdisplay_cnattach(X86_BUS_SPACE_IO, X86_BUS_SPACE_MEM) == 0)
> + return (0);
> +#endif
> +#if NVGA_PCI > 0
> + if (vga_pci_cnattach_scan(X86_BUS_SPACE_IO, X86_BUS_SPACE_MEM,
> + NULL) == 0)
> return (0);
> #endif
> return (-1);
> Index: sys/dev/pci/vga_pci.c
> ===================================================================
> RCS file: /home/cvs/src/sys/dev/pci/vga_pci.c,v
> diff -u -p -r1.92 vga_pci.c
> --- sys/dev/pci/vga_pci.c 12 Jun 2025 09:17:46 -0000 1.92
> +++ sys/dev/pci/vga_pci.c 30 Jan 2026 19:28:00 -0000
> @@ -287,6 +287,39 @@ vga_pci_cnattach(bus_space_tag_t iot, bu
> }
>
> int
> +vga_pci_cnattach_scan(bus_space_tag_t iot, bus_space_tag_t memt,
> + pci_chipset_tag_t pc)
> +{
> + pcitag_t tag;
> + pcireg_t id, class, cmd;
> + int bus, dev;
> +
> + for (bus = 0; bus < 256; bus++) {
> + for (dev = 0; dev < 32; dev++) {
> + tag = pci_make_tag(pc, bus, dev, 0);
> + id = pci_conf_read(pc, tag, PCI_ID_REG);
> + if (id == 0 || PCI_VENDOR(id) == PCI_VENDOR_INVALID)
> + continue;
> +
> + class = pci_conf_read(pc, tag, PCI_CLASS_REG);
> + if (!DEVICE_IS_VGA_PCI(class))
> + continue;
> +
> + cmd = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
> + if ((cmd & (PCI_COMMAND_IO_ENABLE |
> + PCI_COMMAND_MEM_ENABLE)) !=
> + (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE))
> + continue;
> +
> + if (vga_pci_cnattach(iot, memt, NULL, bus, dev, 0) == 0)
> + return (0);
> + }
> + }
> +
> + return (ENXIO);
> +}
> +
> +int
> vga_pci_ioctl(void *v, u_long cmd, caddr_t addr, int flag, struct proc *pb)
> {
> int error = 0;
> Index: sys/dev/pci/vga_pcivar.h
> ===================================================================
> RCS file: /home/cvs/src/sys/dev/pci/vga_pcivar.h,v
> diff -u -p -r1.20 vga_pcivar.h
> --- sys/dev/pci/vga_pcivar.h 29 Oct 2015 07:47:03 -0000 1.20
> +++ sys/dev/pci/vga_pcivar.h 30 Jan 2026 19:27:47 -0000
> @@ -82,6 +82,8 @@ struct vga_pci_softc {
> #endif
> };
>
> +int vga_pci_cnattach_scan(bus_space_tag_t, bus_space_tag_t,
> + pci_chipset_tag_t);
> int vga_pci_cnattach(bus_space_tag_t, bus_space_tag_t,
> pci_chipset_tag_t, int, int, int);
> int vga_aperture_needed(struct pci_attach_args *);
>
>
sys/amd64: fallback to VGA text mode on headless systems