Skip to content
This repository has been archived by the owner on Jul 11, 2023. It is now read-only.

Commit

Permalink
Fix the graphics mess
Browse files Browse the repository at this point in the history
We've had a problem since last august. If graphics worked on qemu, they did not work
on hardware. If they worked on hardware, they did not work on qemu.

The problem comes down to the nature of VESA setup and how it works.

Quick tutorial.
Kernels on hardware start in 16-bit mode, go to 32-bit mode, then
64-bit mode. The 16-bit code, and much 32-bit code, is not considered
part of the kernel; it's setup stuff, tacked on once the kernel is built
by scripts from the kernel Makefile. It's discarded once the real kernel
starts. Think of the kernel as the spaceship, and this 16- and 32- bit
stuff as the first and second stage.

While in the 32-bit code, if VESA is enabled, the 32-bit code calls and
sets it up. The whole pile of code is pretty nasty.

That VESA interaction you see sometimes? Looks like this?
Press <ENTER> to see video modes available, <SPACE> to continue, or wait 30 sec
Mode: Resolution:  Type: Mode: Resolution:  Type: Mode: Resolution:  Type:
0 F00   80x25      VGA   1 F01   80x50      VGA   2 F02   80x43      VGA
3 F03   80x28      VGA   4 F05   80x30      VGA   5 F06   80x34      VGA
6 F07   80x60      VGA   7 300  640x400x8   VESA  8 301  640x480x8   VESA

That's being done BEFORE the 64-bit kernel boots, in 32-bit code.
One reason to do this is it's pretty easy to call VESA BIOS setup calls
from that 32-bit code, but a mess to do it from 64-bit. And BIOS calls
are a security exposure anyway.

So, the boot sequence:
16 bit -> 32 bit -> ask about VESA if it's enabled -> 64 bit

What happens in kexec, i.e. when the webboot kernel boots
the tinycore kernel?
we did this: 16 bit -> 32 bit -> ask about VESA -> 64 bit
now we do this: -> kexec new kernel -> new kernel 64 bit

See the sequence? Second kernel's 32-bit code never runs.
And there's a problem. The second kernel never gets to ask you
about VESA mode. It has to be done in the first kernel. So we enable
all the VESA framebuffer stuff.

But what about hardware? Can't we just enable all the hardware?
Well, ... that's a problem, because then the flow changes. Kexec starts
the second kernel at the 64-bit entry point.

16 bit -> 32 bit -> 64 bit -> set up hardware

And, when you kexec:
we did this before: 16 bit -> 32 bit -> 64 bit -> set up hardware
now we do this: -> kexec -> 64 bit -> set up hardware

oh, oops.

You can see the problem: we enter the new kernel at the 64-bit entry point,
but it still wants to set up hardware, and that explains the hardware wedges
we were having.

So, this change enables all the VESA setup a kernel does in 32-bit, but nothing
more. It certainly fixes the problems we've had on qemu.

Will it work on hardware? We'll see. It should. But ... we'll see.

The trick will be not getting in trouble by enabling graphics HARDWARE
in the first kernel; let the kernel you kexec do that stuff.

N.B. This works ok with
qemu -kernel command.

it does not work with booting a usb stick in qemu via syslinux,
but it does work just fine on a thinkpad T510.

I also include a syslinux.cfg.example to show what I did that worked.

NOTE: you really need to pick a VESA type; if you don't, tinycore graphics
won't work.

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
  • Loading branch information
rminnich committed Feb 1, 2020
1 parent 1abd3d8 commit ac6873c
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 10 deletions.
16 changes: 16 additions & 0 deletions RR
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export PMEM_SIZE=4G
export RAM_SIZE=8G
export KERNEL=linux/arch/x86/boot/bzImage
export INITRD=/tmp/initramfs.linux_amd64.cpio

/usr/bin/qemu-system-x86_64 \
-machine q35 \
-m $RAM_SIZE \
-object rng-random,filename=/dev/urandom,id=rng0 \
-device virtio-rng-pci,rng=rng0 \
-netdev user,id=u1 -device rtl8139,netdev=u1 \
-kernel $KERNEL \
-initrd $INITRD \
-vga std \
-append "earlyprintk=ttyS0,115200,keep console=tty0 console=ttyS0 vga=ask memmap=1G!1G" \
-serial stdio
89 changes: 85 additions & 4 deletions config-4.12.7
Original file line number Diff line number Diff line change
Expand Up @@ -1550,7 +1550,9 @@ CONFIG_NET_VENDOR_INTEL=y
# CONFIG_E100 is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
# CONFIG_IGB is not set
CONFIG_IGB=y
CONFIG_IGB_HWMON=y
CONFIG_IGB_DCA=y
# CONFIG_IGBVF is not set
# CONFIG_IXGB is not set
# CONFIG_IXGBE is not set
Expand Down Expand Up @@ -2122,11 +2124,11 @@ CONFIG_GAMEPORT=y
#
CONFIG_TTY=y
CONFIG_VT=y
# CONFIG_CONSOLE_TRANSLATIONS is not set
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=0
Expand Down Expand Up @@ -2270,6 +2272,7 @@ CONFIG_I2C_MUX_PINCTRL=y
# CONFIG_I2C_MUX_MLXCPLD is not set
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_SMBUS=y
CONFIG_I2C_ALGOBIT=y

#
# I2C Hardware Bus support
Expand Down Expand Up @@ -2849,7 +2852,74 @@ CONFIG_MFD_VX855=y
#
# Frame buffer Devices
#
# CONFIG_FB is not set
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
CONFIG_FB_CMDLINE=y
CONFIG_FB_NOTIFY=y
# CONFIG_FB_DDC is not set
CONFIG_FB_BOOT_VESA_SUPPORT=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
# CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA is not set
# CONFIG_FB_FOREIGN_ENDIAN is not set
# CONFIG_FB_SYS_FOPS is not set
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set

#
# Frame buffer hardware drivers
#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ARC is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
# CONFIG_FB_VGA16 is not set
CONFIG_FB_VESA=y
# CONFIG_FB_N411 is not set
# CONFIG_FB_HGA is not set
# CONFIG_FB_OPENCORES is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_I740 is not set
# CONFIG_FB_LE80578 is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_VIA is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_CARMINE is not set
# CONFIG_FB_SMSCUFX is not set
# CONFIG_FB_UDL is not set
# CONFIG_FB_IBM_GXT4500 is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
# CONFIG_FB_AUO_K190X is not set
# CONFIG_FB_SIMPLE is not set
# CONFIG_FB_SM712 is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_VGASTATE is not set

Expand All @@ -2861,6 +2931,13 @@ CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=80
CONFIG_DUMMY_CONSOLE_ROWS=25
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_SOUND is not set

#
Expand Down Expand Up @@ -4322,6 +4399,10 @@ CONFIG_DDR=y
# CONFIG_IRQ_POLL is not set
CONFIG_MPILIB=y
CONFIG_OID_REGISTRY=y
CONFIG_FONT_SUPPORT=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
# CONFIG_SG_SPLIT is not set
CONFIG_SG_POOL=y
CONFIG_ARCH_HAS_SG_CHAIN=y
Expand Down
11 changes: 11 additions & 0 deletions syslinux.cfg.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
DEFAULT webboot
SAY Now booting webboot
PROMPT 1
TIMEOUT 1

LABEL webboot
KERNEL /boot/webboot
INITRD /boot/webboot.cpio.gz
APPEND earlyprintk=tty0 earlyprintk=ttyS0,115200,keep console=ttyS0 console=tty0 memmap=1G!1G vga=ask


19 changes: 13 additions & 6 deletions webboot/webboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const (
coreURL = "http://tinycorelinux.net/10.x/x86/release/CorePlus-current.iso"
ubuURL = "http://releases.ubuntu.com/18.04/ubuntu-18.04.3-desktop-amd64.iso"
archURL = "http://mirror.rackspace.com/archlinux/iso/2020.01.01/archlinux-2020.01.01-x86_64.iso"
tcCmdLine = "memmap=%dG!%dG earlyprintk=ttyS0,115200 console=ttyS0 console=tty0 root=/dev/pmem0 loglevel=3 cde waitusb=5 vga=791"
)

var (
Expand All @@ -52,30 +53,32 @@ var (
ipv6 = flag.Bool("ipv6", true, "use IPV6")
dryrun = flag.Bool("dryrun", false, "Do not do the kexec")
wifi = flag.String("wifi", "", "[essid [WPA [password]]]")
pmbase = flag.Int("pmbase", 1, "PM base in GiB")
pmsize = flag.Int("pmsize", 1, "PM size in GiB")
bookmark = map[string]*webboot.Distro{
// TODO: Fix webboot to process the tinycore's kernel and initrd to boot from instead of using our customized kernel
"webboot-tinycorepure": &webboot.Distro{
"boot/vmlinuz64",
"/boot/corepure64.gz",
"memmap=1G!1G earlyprintk=ttyS0,115200 console=ttyS0 console=tty0 root=/dev/pmem0 loglevel=3 cde waitusb=5 vga=791",
tinyCoreCmdLine(),
wbtcpURL,
},
"webboot-corepure": &webboot.Distro{
"boot/vmlinuz64",
"/boot/corepure64.gz",
"memmap=4G!4G earlyprintk=ttyS0,115200 console=ttyS0 console=tty0 root=/dev/pmem0 loglevel=3 cde waitusb=5 vga=791",
tinyCoreCmdLine(),
wbcpURL,
},
"tinycore": &webboot.Distro{
"boot/vmlinuz64",
"/boot/corepure64.gz",
"earlyprintk=ttyS0,115200 console=ttyS0 console=tty0",
tinyCoreCmdLine(),
tcURL,
},
"Tinycore": &webboot.Distro{
"/bzImage", // our own custom kernel, which has to be in the initramfs
"/boot/corepure64.gz",
"memmap=1G!1G earlyprintk=ttyS0,115200 console=ttyS0 console=tty0 root=/dev/pmem0 loglevel=3 cde waitusb=5 vga=791",
tinyCoreCmdLine(),
tcURL,
},
"arch": &webboot.Distro{
Expand Down Expand Up @@ -105,18 +108,22 @@ var (
"local": &webboot.Distro{
"/bzImage",
"/boot/corepure64.gz",
"memmap=256M!1G earlyprintk=ttyS0,115200 console=ttyS0 console=tty0 console=tty1 root=/dev/pmem0 loglevel=3 cde waitusb=5 vga=791",
tinyCoreCmdLine(),
"file:///iso", // NOTE: three / is REQUIRED
},
"core": &webboot.Distro{
"boot/vmlinuz",
"/boot/core.gz",
"console=tty0",
tinyCoreCmdLine(),
coreURL,
},
}
)

func tinyCoreCmdLine() string {
return fmt.Sprintf(tcCmdLine, *pmsize, *pmbase)
}

// parseArg takes a name of bookmark and produces a download link
// The download link can be used to download data to a persistent memory device '/dev/pmem0'
func parseArg(arg string) (string, string, error) {
Expand Down

0 comments on commit ac6873c

Please sign in to comment.