Open HunterBoy344 opened 4 months ago
How do other kernels treat the display? Like linux-lts in the place of Linux virt?
I've taken a log of V86's VGA debug messages when booting this image.
The switch from 1024x768 -> 1280x960 begins at timestamp 11:40:35, I've inserted 3 lines breaks in the log. I think this stands out:
11:40:36.158 11:40:36+158 [VGA ] 1CF / dispi write 0x6: 0x500
11:40:36.158 11:40:36+158 [VGA ] Unimplemented dispi write index: 0x6
11:40:36.158 11:40:36+158 [VGA ] SVGA: enabled=false, 1280x960x32
11:40:36.158 11:40:36+158 [VGA ] 1CF / dispi write 0x7: 0x6666
11:40:36.158 11:40:36+158 [VGA ] Unimplemented dispi write index: 0x7
11:40:36.158 11:40:36+158 [VGA ] SVGA: enabled=false, 1280x960x32
11:40:36.158 11:40:36+158 [VGA ] 1CF / dispi write 0x8: 0x0
11:40:36.158 11:40:36+158 [VGA ] Unimplemented dispi write index: 0x8
11:40:36.158 11:40:36+158 [VGA ] SVGA: enabled=false, 1280x960x32
11:40:36.158 11:40:36+158 [VGA ] 1CF / dispi write 0x9: 0x0
11:40:36.158 11:40:36+158 [VGA ] SVGA offset: 0x0 y=0x0
11:40:36.158 11:40:36+158 [VGA ] complete redraw
For context, 0x1CF is Bochs' VBE port as documented in the OSDev Wiki. The log states that three functions (0x6 - 0x8) are not implemented in V86, their meaning:
Note that the Y-offset 0x1CF:0x9 (VBE_DISPI_INDEX_Y_OFFSET) is already implemented in V86.
Even though an attempt to write "0" to 0x1CF:0x08 fails at this particular log entry, later down we find this:
11:40:36.167 11:40:36+167 [VGA ] 1CF / dispi write 0x8: 0x400
11:40:36.167 11:40:36+167 [VGA ] Unimplemented dispi write index: 0x8
So later an attempt is made to write 0x400 (dec. 1024) into 0x1CF:0x08 which looks promising.
My guess would be that including support for 0x1CF:0x08 (VBE_DISPI_INDEX_X_OFFSET) could fix this. Not sure about virtual width and height (0x6 and 0x7) though.
EDIT: That indeed fixed it:
I tested changing resolution on Windows 2000 (with VBE NT driver) and it doesn't use virtual width/height:
[VGA ] planar mode: 0x10
[VGA ] 3CC read
[VGA ] 1CF / dispi write 0x4: 0x0 <- VBE_DISPI_INDEX_ENABLE
[VGA ] SVGA: enabled=false, 1024x768x32
[VGA ] 1CF / dispi write 0x3: 0x20 <- VBE_DISPI_INDEX_BPP
[VGA ] SVGA: enabled=false, 1024x768x32
[VGA ] 1CF / dispi write 0x1: 0x640 <- VBE_DISPI_INDEX_XRES
[VGA ] SVGA: enabled=false, 1600x768x32
[VGA ] 1CF / dispi write 0x2: 0x384 <- VBE_DISPI_INDEX_YRES
[VGA ] SVGA: enabled=false, 1600x900x32
[VGA ] 1CF / dispi write 0x5: 0x0 <- VBE_DISPI_INDEX_BANK
[VGA ] SVGA bank offset: 0x0
[VGA ] SVGA: enabled=false, 1600x900x32
[VGA ] 1CF / dispi write 0x4: 0x41 <- VBE_DISPI_INDEX_ENABLE
[VGA ] SVGA: enabled=true, 1600x900x32
[VGA ] 3D4 / crtc index: 17
I tested changing resolution on Windows 2000 (with VBE NT driver) and it doesn't use virtual width/height:
As always, thanks a lot!
Seeing that I cannot find any bug reports from the past it looks to me that virtual width and height are not being used in the wild (that's assuming that it would completely trash the screen), though I do not believe that myself.
Maybe others, who've been around here longer than I, can chip in.
You're welcome, thank you too!
it looks to me that virtual width and height are not being used in the wild
Probably (in Linux vesafb) this virtual display is changed itself as main display when you need to switch between VESA videomodes. Modern Linux distros enables framebuffer on boot. I guess if Alpine Linux were booted with vgacon and gdm (login screen) was set to 1600x900, the screen wouldn't loop.
How do other kernels treat the display? Like linux-lts in the place of Linux virt?
IIRC Alpine Linux Standard and Virtual use same module for framebuffer.
During boot, my 32-bit Debian 12 image does what seems to be the norm (I googled around a bit today but couldn't find much substantial): It sets the virtual width to the same value as the real width, and the virtual height to fill all of the available video RAM.
The real screen size is 1024x768x4 (32bpp), with 8M video RAM the virtual size is 1024x2048x4 and with 16M it's 1024x4096x4 (I spare you the logs).
vga.js already supports virtual width and height (see members screen_width/screen_height vs. virtual_width/virtual_height), I have yet to look into that but shouldn't it be possible to reuse these mechanics in order to add full support for the Bochs-specific registers VBE_DISPI_INDEX_VIRT_WIDTH and VBE_DISPI_INDEX_VIRT_HEIGHT?
By "Bochs-specific" I mean to say that port 0x1CF exists only in Bochs VGA Bios, this is not the common VESA interface, the application (or OS) needs to know specifically about Bochs when making use of it (like Debian or Alpine obviously do).
From what I know, virtual screens are in general used for panning, scrolling and double-buffering, so unless it turns out that nobody uses the Bochs-specific registers to do that, I think proper support for it should be added. Bochs is 30 years old, and according to the API history, virtual width and height were added in 2002, so it's been around for a while.
By "Bochs-specific" I mean to say that port 0x1CF exists only in Bochs VGA Bios, this is not the common VESA interface, the application (or OS) needs to know specifically about Bochs when making use of it (like Debian or Alpine obviously do).
SerenityOS sources said that Bochs VGA doesn't support MMIO registers, so you need communicate via default IO-ports (QEMU stdvga has it: https://www.qemu.org/docs/master/specs/standard-vga.html#mmio-area-spec).
Browser: Chromium version 126.0.6478.182 VM memory: 256MB VM video memory: 128MB
Screenshot 1 (before resolution change, login screen, 1024x768):
Screenshot 2 (after resolution change, desktop, 1280x960):
The start button is supposed to be on the far left, and the sliver of my mouse you can see is where the right edge of the screen is supposed to be. Everything appears to be offset, and moving my mouse off the left edge of the screen causes it to loop over to the right.
I can avoid this issue by not raising the video memory of the VM above 8MB, preventing it from resizing above 1024x768. However, I want a higher resolution than that, and I also want more video memory, so this is a bit of a problem. This bug doesn't seem to happen when I use my disk image on QEMU, nor does it happen when changing resolutions in the official Windows 2000 VM on V86.
Disk image is here. It's 3GB and it contains a copy of Alpine Linux with linux-virt and the Xfce desktop environment. Default password is alp1neNSO.