Opened 3 years ago

Closed 2 years ago

#831 closed defect (fixed)

With -M isapc graphical kernel console is not visible

Reported by: Jiri Svoboda Owned by: Jiri Svoboda
Priority: major Milestone: 0.12.1
Component: helenos/unspecified Version: mainline
Keywords: Cc:
Blocker for: Depends on:
See also:

Description

If I compile ia32 version of the OS, then (disregarding the fact, that userspace does not work), VESA/graphical kernel console is not visible. I can see output on the serial line and I can type in commands via the keyboard, but only garbage is seen on the screen.

If Frame buffer support is disabled (i.e. EGA text mode is forced), then the kernel console displays correctly. Without -M isapc, graphical console works correctly (i.e. with a system build for CPU=486).

Change History (12)

comment:1 by Jiri Svoboda, 2 years ago

Milestone: 0.11.20.12.1

comment:2 by Jiri Svoboda, 2 years ago

Owner: set to Jiri Svoboda
Status: newaccepted

comment:3 by Jiri Svoboda, 2 years ago

I found out by experiment that for ia32 version 1 multiboot is used. For ia32/amd64 GRUB architecture is pc by default. For pc GRUB we boot the kernel using multiboot 1, as evidenced by this part of boot/grub/meson.build:

f GRUB_ARCH == 'pc'
        MULTIBOOT_CMD = 'multiboot'
        MODULE_CMD = 'module'
        INSMODS = [ 'insmod vbe', 'insmod vga' ]
elif GRUB_ARCH == 'efi'
        MULTIBOOT_CMD = 'multiboot2'
        MODULE_CMD = 'module2'
        INSMODS = [ 'insmod efi_gop', 'insmod efi_uga' ]
endif

Now kernel/arch/ia32/src/boot/multiboot.S includes kernel/arch/ia32/src/boot/vesa_*.inc and sets up the graphics mode and frame buffer by calling into real-mode VESA BIOS.

At this point, AFAIK, protected mode is enabled, paging disabled. The code switches back and forth between real-mode and protected mode to call the real-mode VESA functions.

I found a small bug where only AL was checked for status return from VBE functions. However, AL contains 0x4F if the function is supported and != 0x4F if it is not. However, the success or failure is stored in AH, 0x00 = success, != 0x00 .. failure. So, we need to check entire AX for being equal to 0x004f (supported, success). Fixing this did not have an effect on this bug.

comment:4 by Jiri Svoboda, 2 years ago

If any of the VESA functions fail (i.e. we cannot set up a graphics mode), the system correctly falls back to the EGA text mode. Now in case of -M isapc we can actually clearly see that the call to set the video mode succeeds (because the emulator window size changes and artifacts matching the selected video mode are seen as the video memory is not cleared per our request). However, the OS clearly never writes anything to the frame buffer.

comment:5 by Jiri Svoboda, 2 years ago

There don't seem to be many possibilities here. Either we somehow get the address of the framebuffer wrong or the mapping wrong in the isapc case, or there is a problem on the emulator/VBE side. I was even thinking whether it is possible to provide a linear framebuffer on a (real) ISA bus.

8-bit ISA bus has 20 address lines, so it can only address up to 1 MB of memory (so linear frame buffer would not be possible, since there is very little free space under 1 MB). 16-bit ISA has 24 address lines, so it can address up to 4 MB of memory. That's still a tight fit (especially with higher resolution and considering you need to put RAM somewhere, too?) Typical super VGAs were used VLB so not sure if they had more address lines available. Also not sure, if these real HW limitations would be emulated by Qemu.

In any case, it would be good to verify the linear framebuffer address returned by VBE and see if there is some problem accessing it.

It could well be the case that this is a problem in Qemu/VBE, either that it does not set up the buffer correctly in this case, or there is a good reason why it cannot be used in this case and just not reported correctly.

comment:6 by Jiri Svoboda, 2 years ago

I think I've found the root cause of the problem. Without -M isapc the VESA BIOS in Qemu will report an adapter with 16 MB of video RAM and supporting a number of modes, including 0x111 (our fallback mode). With -M isapc it will report only 2 MB VRAM and only supporting BIOS modes (⇐ 0x13).

Now our VESA code will look through the list of supported modes to find a match. If not found, it will query for information for mode 0x111. If successful, it will set it.

Here's what the VBE specification says:

Note that VBE modes may
only be set if the mode exists in the VideoModeList pointed to by the VideoModePTR returned in
Function 00h, while Standard VGA modes and OEM defined 7 bit modes may be initialized
without a corresponding entry in the VideoModeList and a mode info block.

So asking for mode 0x111 if it is not listed as supported is technically in violation of the specification. I've verified the VBE will return success when asked for this mode, even though it clearly is not supported by this display adapter.

While it would be nice for the VBE to return error for this unsupported mode, I'm not sure if this can even be considered a bug in the VBE since clearly we've done something which we're not supposed to do here.

comment:7 by Jiri Svoboda, 2 years ago

I added a check that verifies that 0x111 is in the mode list before trying to get information on it and setting it, but this did not help.

I've added code to print the list of modes we are getting and it's different than the list I am getting from my simple DOS utility that I created for the purpose of testing.

Mode list from VESATEST DOS utility without -M isapc:

  • 0x0000..0x0007, 0x000d..0x0013, 0x006a

Mode list from HelenOS without -M isapc:

  • 0x0100..0x0107, 0x010d, 0x010e, 0x0110..0x011f, 0x0140..0x014c, 0x0175..0x198, 0x0000..0x0007, 0x000d..0x0013, 0x006a

Mode list from VESATEST DOS utility with -M isapc:

  • 0x0000..0x0007, 0x000d..0x0013, 0x006a

Mode list from HelenOS with -M isapc:

  • 0x0101, 0x0111, 0x0110, 0x0112, 0x0103, 0x0114, 0x0113, 0x0105, 0x0117, 0x0116, 0x0118, 0x0107, 0x0119, 0x011a, 0x0000..0x0007, 0x000d..0x0013, 0x006a

I am not sure why there is a difference with -M isapc between HelenOS and the DOS utility.

comment:8 by Martin Decky, 2 years ago

Have you considered the following comment? https://github.com/HelenOS/helenos/blob/master/kernel/arch/ia32/src/boot/vesa_real.inc#L169

The VESA BIOS usually reports different modes when the client does not indicate that it is expecting VBE 2.0 compliance.

in reply to:  5 comment:9 by Martin Decky, 2 years ago

By the way …

16-bit ISA has 24 address lines, so it can address up to 4 MB of memory.

That's 16 MiB of memory (224 bytes), actually. I used to have an Intel 386SX PC some 32 years ago which only uses 24 address pins to connect to the address bus. It is fully compatible with the so called 16-bit (or AT) ISA bus and I clearly remember having 8 MiB of physical memory. I also used to have several ISA SVGA graphics cards (various brands) and they all supported the VESA VBE 2.0 BIOS with a linear framebuffer on the 386SX machine fine.

VESA mode 0x111 (which is 640x480 in 16 bpp, if I'm not mistaken) should require 600 KiB of framebuffer memory. Which is again nothing extreme even for a 386-era PC.

Of course, this is probably only tangentially relevant to what QEMU with -M isapc might be doing. I'm just saying that there is no principal issue here and we are indeed dealing with a bug somewhere (either on the HelenOS side or on the QEMU side).

If the QEMU is indeed emulating the 24-bit data bus limitation faithfully, then I would definitively check the amount of physical memory configured. Maybe that is preventing the framebuffer memory from being accessed properly.

comment:10 by Jiri Svoboda, 2 years ago

Yes, I have taken the two ways of inquiring (without VBE2 and with VBE2 signature) into account, I forgot to mention it. I implemented both options in my VESATEST utility and I can select which one to use with a command line switch.

The reported list of video modes is always the same in both VESA and VBE2 mode (regardless of -M isapc), so that's not the reason why we are getting different lists.

Also note the mode list reported in HelenOS with -M isapc is quite different (the mode numbers are not in order), which is a little bit suspicious. I am going to print out all the information from VbeInfoBlock to see if the other information we get is correct.

comment:11 by Jiri Svoboda, 2 years ago

Thanks for that comment about 16 MB of RAM, yeah I also used to have a 386 with Super 4 MB of RAM and Super VGA, so I was confused why this should be a problem (but I don't remember if it was a pure ISA card or if it used Vesa Local Bus).

Anyway givan that it really seems like there is nothing in principle preventing mode 0x111 with LFB from working with an ISA PC wit a SuperVGA having 2 MB of VRAM. So maybe I'm just doing something stupid in my utility to get the wrong mode list. At the same time there IS something preventing HelenOS from writing to the frame buffer.

One thing to try would be some DOS software running in 640x480x256 and run it in Qemu -M isapc.

comment:12 by Jiri Svoboda, 2 years ago

Resolution: fixed
Status: acceptedclosed

OK, so regardless of physical (im)possibility, the (different) video adapter presented by Qemu in isapc mode does not support linear frame buffer, as I was thinking from the start.

I printed mode attributes from HelenOS and this became obvious.

So what was the problem? When we decide to use the fallback mode we don't verify it at all, we just blindly try to set it. When we actually retrieve the mode's attributes, we find out it does not support linear frame buffer. Also, we should actually go through the list of supported modes and verify the mode is there. (And bit 0 in mode attributes must reaffirm that the mode is indeed currently supported).

Fixed in changeset 36aec61ed4ea92750995d2823370a5f19b89a6b3

Note: See TracTickets for help on using tickets.