Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix kexec framebuffer graphics for 5.10 kernel #1378

Merged

Conversation

JonathonHall-Purism
Copy link
Collaborator

@JonathonHall-Purism JonathonHall-Purism commented Apr 18, 2023

Fix setting up a framebuffer for the OS kernel to use following kexec.

If Heads is configured with kernel 4.20 or later, the OS kernel is not able to use framebuffer video output. The OS kernel must have the i915 module (or other appropriate driver) and there won't be any video output until it takes over the device. In particular, this prevents booting memtest86+ and the Debian netinstall image (as well as others).

This now works on i915 using kernel 5.10 in Heads. I've tested Librem 15v4 and Librem Mini v2.

It does not work on Aspeed graphics (ast), even when adding the astdrmfb identifier to kexec. It looks like ast uses a shadow buffer internally in the kernel (it sets mode_config.prefer_shadow = 1 in ast_mode.c), which means that the generic DRM FB helper doesn't know where the real framebuffer is (AFAICT from a cursory read-through). A hack would be to somehow get the real framebuffer address up to fix.smem_start, but this is pretty wrong from the kernel's perspective (nothing should write there, it's just what we need since we are going to kexec and the driver will be gone), would just be a hack for kexec. I took an initial look at this but it's going to need a deeper dive.

That's probably the reason for the ID checks in kexec, so I don't think we can remove that currently.


TODO:

  • Test more boards, particularly Aspeed graphics (server)
  • Bump kexec to 2.0.26
  • See if we can remove the driver name checks in kexec
  • Improve kexec tracing, in particular trace unknown driver names (if we have to keep that check) and warn if framebuffer address is not provided by kernel
  • Enable fixes for other boards

kexec(8) needs to get the framebuffer address in order to set up the
new kernel's boot parameters.  This is one of the reasons that using a
>4.20 kernel in Heads prevents framebuffer graphics from working in the
OS kernel.

Linux 4.20 started hiding this address from userspace, because
userspace is not supposed to need physical memory addresses.  A
workaround was added to keep leaking the address, apparently for some
proprietary userspace OpenGL drivers.  This requires both a Kconfig and
a kernel parameter.

This commit enables the Kconfig on the librem_common config, and the
kernel parameter on the librem_15v4 (where I'm testing this).  We will
need to enable it on other >4.20 configs/boards as well.

Signed-off-by: Jonathon Hall <[email protected]>
The i915 driver's ID changed again, now to i915drmfb.

It's unclear why kexec checks this, it seems it could populate the
target kernel's framebuffer info as long as it knows enough about the
host kernel's framebuffer, which it already checks.  Maybe we could
improve this, for now just add the new ID again.

Signed-off-by: Jonathon Hall <[email protected]>
@tlaurion
Copy link
Collaborator

tlaurion commented Apr 18, 2023

I suggest that we version bump kexec to latest.

I added the following patch on my debugging branch so that we know what is happening when calling kexec -d -l with debugging on top of kexec 2.0.26

diff --git a/Makefile.in b/Makefile.in
index fb01134..bf1973e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -157,12 +157,12 @@ include $(srcdir)/kexec/Makefile
 
 # vmcore-dmesg (read dmesg from a vmcore)
 #
-include $(srcdir)/vmcore-dmesg/Makefile
+#include $(srcdir)/vmcore-dmesg/Makefile
 
 #
 # kexec_test (test program)
 #
-include $(srcdir)/kexec_test/Makefile
+#include $(srcdir)/kexec_test/Makefile
 
 SPEC=$(PACKAGE_NAME).spec
 GENERATED_SRCS:= $(SPEC)
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
index 057ee14..43e017a 100644
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -137,7 +137,8 @@ static int setup_linux_vesafb(struct x86_linux_param_header *real_mode)
 		goto out;
 	if (-1 == ioctl(fd, FBIOGET_VSCREENINFO, &var))
 		goto out;
-	if (0 == strcmp(fix.id, "VESA VGA")) {
+	if (0 == strcmp(fix.id, "VESA VGA")
+            || 0 == strcmp(fix.id, "inteldrmfb") || 0 == strcmp(fix.id, "i915drmfb")) {
 		/* VIDEO_TYPE_VLFB */
 		real_mode->orig_video_isVGA = 0x23;
 	} else if (0 == strcmp(fix.id, "EFI VGA")) {
diff --git a/kexec/kexec.c b/kexec/kexec.c
index bc6ab3d..b82725b 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -805,6 +805,27 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
 	if (sort_segments(&info) < 0) {
 		return -1;
 	}
+
+#if 1
+	// force segment 0 to have memsz == bufsz
+	// so that it won't overwrite EBDA
+	if (info.segment[0].mem == 0)
+	{
+		if (kexec_debug)
+			printf("hack ebda into segment 0!\n");
+
+		uint8_t * ebda = calloc(1, info.segment[0].memsz);
+		memcpy(ebda, info.segment[0].buf, info.segment[0].bufsz);
+		info.segment[0].bufsz = info.segment[0].memsz;
+		info.segment[0].buf = ebda;
+
+		// install some default EBDA values that are off scale,
+		// which will force Xen to use the multiboot info
+		*(uint16_t*)(ebda + 0x40e) = 0xFFFF; // segment
+		*(uint16_t*)(ebda + 0x413) = 0xFFFF; // size
+	}
+#endif
+
 	/* if purgatory is loaded update it */
 	update_purgatory(&info);
 	if (entry)
diff --git a/purgatory/Makefile b/purgatory/Makefile
index 2dd6c47..2de8f07 100644
--- a/purgatory/Makefile
+++ b/purgatory/Makefile
@@ -44,7 +44,6 @@ purgatory/sha256.o: $(srcdir)/util_lib/sha256.c
 	mkdir -p $(@D)
 	$(COMPILE.c) -o $@ $^
 
-$(PURGATORY): CC=$(TARGET_CC)
 $(PURGATORY): CFLAGS=$(PURGATORY_EXTRA_CFLAGS) \
 		      $($(ARCH)_PURGATORY_EXTRA_CFLAGS) \
 		      -Os -fno-builtin -ffreestanding \
diff --git a/util/Makefile b/util/Makefile
index 948ee63..833a897 100644
--- a/util/Makefile
+++ b/util/Makefile
@@ -2,7 +2,7 @@ BIN_TO_HEX:= bin/bin-to-hex
 
 $(BIN_TO_HEX): $(srcdir)/util/bin-to-hex.c
 	@$(MKDIR) -p $(@D)
-	$(LINK.o) $(CFLAGS) -o $@ $^
+	$(BUILD_CC) $(BUILD_CFLAGS) -o $@ $^
 
 $(BIN_TO_HEX): CC=$(BUILD_CC)
 $(BIN_TO_HEX): CFLAGS=$(BUILD_CFLAGS)
--- a/kexec/arch/i386/x86-linux-setup.c.orig	2023-04-11 15:44:59.905000000 -0400
+++ b/kexec/arch/i386/x86-linux-setup.c	2023-04-11 15:45:03.830000000 -0400
@@ -146,9 +146,11 @@
             || 0 == strcmp(fix.id, "inteldrmfb") || 0 == strcmp(fix.id, "i915drmfb")) {
 		/* VIDEO_TYPE_VLFB */
 		real_mode->orig_video_isVGA = 0x23;
+		dbgprintf("%s: VIDEO_TYPE_VLFB setuped.\n", __func__);
 	} else if (0 == strcmp(fix.id, "EFI VGA")) {
 		/* VIDEO_TYPE_EFI */
 		real_mode->orig_video_isVGA = 0x70;
+		dbgprintf("%s: VIDEO_TYPE_EFI setuped.\n", __func__);
 	} else if (arch_options.reuse_video_type) {
 		int err;
 		off_t offset = offsetof(typeof(*real_mode), orig_video_isVGA);
@@ -159,6 +161,7 @@
 			goto out;
 	} else {
 		real_mode->orig_video_isVGA = 0;
+		dbgprintf("%s: VIDEO_TYPE not VGA.\n", __func__);
 		close(fd);
 		return 0;
 	}

Might be a good idea to output fix.id content when no match happens into kexec. Otherwise we are kinda in the dark right now

@JonathonHall-Purism
Copy link
Collaborator Author

The big picture of how boot works is somewhat complex. In particular, it depends on whether coreboot provides any graphics init and a framebuffer that the kernel can observe (such as VBE). My boards don't provide anything from coreboot, and we would prefer not to have to include libgfxinit since we are already shipping a driver in the Heads kernel.

qemu works differently and I have not investigated that yet, I'm focusing on hardware first.

The boot is supposed to proceed this way:

  • coreboot invokes the Heads kernel. No graphics are initialized yet.
  • Heads' kernel uses the i915 driver to select a mode and create a framebuffer.
  • When handing off to the OS kernel, kexec(8) fills in the OS kernel boot parameters (since it will not invoke the OS kernel's real mode stub).
  • kexec(8) uses the Heads kernel's framebuffer to fill in the video mode and framebuffer for the OS kernel. (This framebuffer was set up by i915, but the OS kernel doesn't know that and will hand it to the vesafb driver, which uses a flat framebuffer.)
  • The OS kernel uses that framebuffer for early console.
  • If the OS has i915, it'll eventually take over. Otherwise it uses the framebuffer forever.

The upshot of all this is that we can boot an OS needing a framebuffer without having to ship anything like a VBIOS, GOP driver, etc. We just use the Heads Linux kernel to set up a framebuffer.

There's been a lot of discussion on this in a lot of places, and just to capture a few more details:

  • kexec --reuse-video-type is not useful to us. This would copy whatever was in the Heads kernel's boot parameters to the OS. This is probably "nothing" because coreboot is not doing any graphics init, and even if it was something, i915 has changed modes by this point.
  • There's some confusion about what happens in real mode (16 bit), protected mode (32 bit), long mode (64 bit) in the OS kernel. VBE is probed in real mode, which doesn't happen here (we don't invoke the real mode stub, and there is no VBE to detect). The OS kernel says it is using "vesafb", but that's just the driver it uses to handle a flat framebuffer, it doesn't actually know where the framebuffer came from.

@JonathonHall-Purism
Copy link
Collaborator Author

I suggest that we version bump kexec to latest.

Agree, I'm working locally with 2.0.26, right now just want to get it functioning correctly and then we can expand with things like this.

Might be a good idea to output fix.id content when no match happens into kexec. Otherwise we are kinda in the dark right now

Agree here too, I had to do the same to get the new-new ID. But maybe we can improve it not to check ID this way, since it's a bit of a cat-and-mouse game keeping up with the ID changes. Anyway, like above, I want to get it to fully work on 5.10, try other boards, and see what we can improve at that point.

@tlaurion
Copy link
Collaborator

Here is my recent patch to also show output for newer board ports when fix.id doesn't match anything to proper into desired VIDEO_TYPE_VLFB mode

user@heads-tests:~/heads$ cat patches/kexec-2.0.26.patch 
diff --git a/Makefile.in b/Makefile.in
index fb01134..bf1973e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -157,12 +157,12 @@ include $(srcdir)/kexec/Makefile
 
 # vmcore-dmesg (read dmesg from a vmcore)
 #
-include $(srcdir)/vmcore-dmesg/Makefile
+#include $(srcdir)/vmcore-dmesg/Makefile
 
 #
 # kexec_test (test program)
 #
-include $(srcdir)/kexec_test/Makefile
+#include $(srcdir)/kexec_test/Makefile
 
 SPEC=$(PACKAGE_NAME).spec
 GENERATED_SRCS:= $(SPEC)
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
index 057ee14..43e017a 100644
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -142,12 +142,21 @@
 		goto out;
 	if (-1 == ioctl(fd, FBIOGET_VSCREENINFO, &var))
 		goto out;
-	if (0 == strcmp(fix.id, "VESA VGA")) {
+
+	dbgprintf("fix.id is: %s.\n", fix.id);
+
+	if (0 == strcmp(fix.id, "VESA VGA")
+           || 0 == strcmp(fix.id, "inteldrmfb")
+	    || 0 == strcmp(fix.id, "i915drmfb")
+	    || 0 == strcmp(fix.id, "virtio_gpudrmfb"))
+	{
 		/* VIDEO_TYPE_VLFB */
 		real_mode->orig_video_isVGA = 0x23;
+		dbgprintf("%s: VIDEO_TYPE_VLFB setuped.\n", __func__);
 	} else if (0 == strcmp(fix.id, "EFI VGA")) {
 		/* VIDEO_TYPE_EFI */
 		real_mode->orig_video_isVGA = 0x70;
+		dbgprintf("%s: VIDEO_TYPE_EFI setuped.\n", __func__);
 	} else if (arch_options.reuse_video_type) {
 		int err;
 		off_t offset = offsetof(typeof(*real_mode), orig_video_isVGA);
@@ -158,6 +167,7 @@
 			goto out;
 	} else {
 		real_mode->orig_video_isVGA = 0;
+		dbgprintf("%s: VIDEO_TYPE not VGA.\n", __func__);
 		close(fd);
 		return 0;
 	}
diff --git a/kexec/kexec.c b/kexec/kexec.c
index bc6ab3d..b82725b 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -805,6 +805,27 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
 	if (sort_segments(&info) < 0) {
 		return -1;
 	}
+
+#if 1
+	// force segment 0 to have memsz == bufsz
+	// so that it won't overwrite EBDA
+	if (info.segment[0].mem == 0)
+	{
+		if (kexec_debug)
+			printf("hack ebda into segment 0!\n");
+
+		uint8_t * ebda = calloc(1, info.segment[0].memsz);
+		memcpy(ebda, info.segment[0].buf, info.segment[0].bufsz);
+		info.segment[0].bufsz = info.segment[0].memsz;
+		info.segment[0].buf = ebda;
+
+		// install some default EBDA values that are off scale,
+		// which will force Xen to use the multiboot info
+		*(uint16_t*)(ebda + 0x40e) = 0xFFFF; // segment
+		*(uint16_t*)(ebda + 0x413) = 0xFFFF; // size
+	}
+#endif
+
 	/* if purgatory is loaded update it */
 	update_purgatory(&info);
 	if (entry)
diff --git a/purgatory/Makefile b/purgatory/Makefile
index 2dd6c47..2de8f07 100644
--- a/purgatory/Makefile
+++ b/purgatory/Makefile
@@ -44,7 +44,6 @@ purgatory/sha256.o: $(srcdir)/util_lib/sha256.c
 	mkdir -p $(@D)
 	$(COMPILE.c) -o $@ $^
 
-$(PURGATORY): CC=$(TARGET_CC)
 $(PURGATORY): CFLAGS=$(PURGATORY_EXTRA_CFLAGS) \
 		      $($(ARCH)_PURGATORY_EXTRA_CFLAGS) \
 		      -Os -fno-builtin -ffreestanding \
diff --git a/util/Makefile b/util/Makefile
index 948ee63..833a897 100644
--- a/util/Makefile
+++ b/util/Makefile
@@ -2,7 +2,7 @@ BIN_TO_HEX:= bin/bin-to-hex
 
 $(BIN_TO_HEX): $(srcdir)/util/bin-to-hex.c
 	@$(MKDIR) -p $(@D)
-	$(LINK.o) $(CFLAGS) -o $@ $^
+	$(BUILD_CC) $(BUILD_CFLAGS) -o $@ $^
 
 $(BIN_TO_HEX): CC=$(BUILD_CC)
 $(BIN_TO_HEX): CFLAGS=$(BUILD_CFLAGS)

Unfortunately it doesn't help as of now for qemu + tinycore which still hangs there without neither serial nor vga, but shows on kexec -d -l call:

fix.id is: virtio_gpudrmfb.
setup_linux_vesafb: VIDEO_TYPE_VLFB setuped.

But does't succeed kexec'ing into next kernel with vga...

│         13 Boot_Core_Plus_with_FLWM_Classic_Window_Manager.                  │
│                                                                              │
│                                                                              │
│                     <Ok>                         <Cancel>                    │
│                                                                              │
└──────────────────────────────────────────────────────────────────────────────┘

TRACE: Under /bin/kexec-boot
DEBUG: kexectype= elf
DEBUG: restval= 
DEBUG: filepath= /media/boot/vmlinuz
DEBUG: kexeccmd= kexec -d --noefi -l /media/boot/vmlinuz
Loading the new kernel:
kexec -d --noefi -l /media/boot/vmlinuz --initrd=/media/boot/core.gz --append="loglevel=3 cde showapps desktop=flwm console=ttyS0 console=tty systemd.
zram=0 drm_kms_helper.drm_leak_fbdev_smem=1 "
Try gzip decompression.
kernel: 0x7fc93d264020 kernel_size: 0x512ea0
MEMORY RANGES
0000000000000000-0000000000000fff (1)
0000000000001000-000000000009ffff (0)
00000000000a0000-00000000000fffff (1)
0000000000100000-000000003ff59fff (0)
000000003ff5a000-000000003fffffff (1)
00000000b0000000-00000000bfffffff (1)
00000000fed40000-00000000fed44fff (1)
bzImage is relocatable
sym: sha256_starts info: 12 other: 00 shndx: 1 value: 1120 size: 48
sym: sha256_starts value: 3ff52120 addr: 3ff51002
R_X86_64_64
sym: sha256_update info: 12 other: 00 shndx: 1 value: 3cb0 size: 19
sym: sha256_update value: 3ff54cb0 addr: 3ff5100f
R_X86_64_64
sym: sha256_regions info: 11 other: 00 shndx: 8 value: 40 size: 100
sym: sha256_regions value: 3ff56040 addr: 3ff5101a
R_X86_64_64
sym: sha256_regions info: 11 other: 00 shndx: 8 value: 40 size: 100
sym: sha256_regions value: 3ff56140 addr: 3ff51044
R_X86_64_64
sym: sha256_finish info: 12 other: 00 shndx: 1 value: 3cd0 size: 15e
sym: sha256_finish value: 3ff54cd0 addr: 3ff5105b
R_X86_64_64
sym: sha256_digest info: 11 other: 00 shndx: 8 value: 20 size: 20
sym: sha256_digest value: 3ff56020 addr: 3ff5106f
R_X86_64_64
sym:     memcmp info: 12 other: 00 shndx: 1 value: 599 size: 21
sym: memcmp value: 3ff51599 addr: 3ff51079
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54f40 addr: 3ff5108d
R_X86_64_64
sym:     printf info: 12 other: 00 shndx: 1 value: 4ba size: a0
sym: printf value: 3ff514ba addr: 3ff5109b
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54f70 addr: 3ff510a5
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54f60 addr: 3ff510b3
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54f76 addr: 3ff510d3
R_X86_64_64
sym: sha256_digest info: 11 other: 00 shndx: 8 value: 20 size: 20
sym: sha256_digest value: 3ff56020 addr: 3ff510e1
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54f78 addr: 3ff510ef
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54f70 addr: 3ff51105
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54f76 addr: 3ff51117
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54f88 addr: 3ff51136
R_X86_64_64
sym:     printf info: 12 other: 00 shndx: 1 value: 4ba size: a0
sym: printf value: 3ff514ba addr: 3ff51142
R_X86_64_64
sym: setup_arch info: 12 other: 00 shndx: 1 value: 762 size: 56
sym: setup_arch value: 3ff51762 addr: 3ff5114f
R_X86_64_64
sym: skip_checks info: 11 other: 00 shndx: 8 value: 0 size: 4
sym: skip_checks value: 3ff56000 addr: 3ff5115b
R_X86_64_64
sym: verify_sha256_digest info: 12 other: 00 shndx: 1 value: 0 size: 134
sym: verify_sha256_digest value: 3ff51000 addr: 3ff5116a
R_X86_64_64
sym: post_verification_setup_arch info: 12 other: 00 shndx: 1 value: 7f0 size: 58
sym: post_verification_setup_arch value: 3ff517f0 addr: 3ff5117c
R_X86_64_64
sym:    putchar info: 12 other: 00 shndx: 1 value: d8e size: 124
sym: putchar value: 3ff51d8e addr: 3ff5118f
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54f9a addr: 3ff512d1
R_X86_64_64
sym:   vsprintf info: 12 other: 00 shndx: 1 value: 187 size: 29d
sym: vsprintf value: 3ff51187 addr: 3ff514a0
R_X86_64_64
sym:   vsprintf info: 12 other: 00 shndx: 1 value: 187 size: 29d
sym: vsprintf value: 3ff51187 addr: 3ff51540
R_X86_64_64
sym:    entry32 info: 10 other: 00 shndx: 1 value: 5c0 size: 0
sym: entry32 value: 3ff515bc addr: 3ff515cd
R_X86_64_PC32
sym:    entry32 info: 10 other: 00 shndx: 1 value: 5c0 size: 0
sym: entry32 value: 3ff515bc addr: 3ff515e2
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff5615c addr: 3ff515fd
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff5613c addr: 3ff51604
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e54 addr: 3ff5160a
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff561ac addr: 3ff51610
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e2c addr: 3ff51616
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ec1 addr: 3ff51649
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ed0 addr: 3ff51650
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54edb addr: 3ff51657
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ee6 addr: 3ff5165e
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ef1 addr: 3ff51665
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54efc addr: 3ff5166c
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54f07 addr: 3ff51673
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ef6 addr: 3ff5167a
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff56271 addr: 3ff51681
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54eec addr: 3ff51693
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54f1c addr: 3ff516a9
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e5c addr: 3ff516bc
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e64 addr: 3ff516c3
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e6c addr: 3ff516ca
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e74 addr: 3ff516d1
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e7c addr: 3ff516d8
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e84 addr: 3ff516df
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e8c addr: 3ff516e6
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e94 addr: 3ff516ed
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54e9c addr: 3ff516f4
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ea4 addr: 3ff516fb
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54eac addr: 3ff51702
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54eb4 addr: 3ff51709
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ebc addr: 3ff51710
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ec4 addr: 3ff51717
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ecc addr: 3ff5171e
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ed4 addr: 3ff51725
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54edc addr: 3ff5172b
R_X86_64_PC32
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54f1c addr: 3ff51733
R_X86_64_PC32
sym: jump_back_entry info: 11 other: 00 shndx: 8 value: 2008 size: 8
sym: jump_back_entry value: 3ff58004 addr: 3ff5174d
R_X86_64_PC32
sym:       .bss info: 03 other: 00 shndx: a value: 0 size: 0
sym: .bss value: 3ff59ffc addr: 3ff51754
R_X86_64_PC32
sym:  purgatory info: 12 other: 00 shndx: 1 value: 134 size: 53
sym: purgatory value: 3ff51130 addr: 3ff51759
R_X86_64_PLT32
sym:    entry64 info: 10 other: 00 shndx: 1 value: 690 size: 0
sym: entry64 value: 3ff5168c addr: 3ff5175e
R_X86_64_PLT32
sym:  reset_vga info: 11 other: 00 shndx: 8 value: 2012 size: 1
sym: reset_vga value: 3ff58012 addr: 3ff51764
R_X86_64_64
sym: x86_reset_vga info: 12 other: 00 shndx: 1 value: eb2 size: 232
sym: x86_reset_vga value: 3ff51eb2 addr: 3ff51773
R_X86_64_64
sym: legacy_pic info: 11 other: 00 shndx: 8 value: 2011 size: 1
sym: legacy_pic value: 3ff58011 addr: 3ff51780
R_X86_64_64
sym: x86_setup_legacy_pic info: 12 other: 00 shndx: 1 value: 10e4 size: 35
sym: x86_setup_legacy_pic value: 3ff520e4 addr: 3ff5178f
R_X86_64_64
sym: legacy_pic info: 11 other: 00 shndx: 8 value: 2011 size: 1
sym: legacy_pic value: 3ff58011 addr: 3ff5179e
R_X86_64_64
sym: x86_setup_legacy_pic info: 12 other: 00 shndx: 1 value: 10e4 size: 35
sym: x86_setup_legacy_pic value: 3ff520e4 addr: 3ff517ad
R_X86_64_64
sym: cmdline_end info: 11 other: 00 shndx: 8 value: 2000 size: 8
sym: cmdline_end value: 3ff58000 addr: 3ff517ba
R_X86_64_64
sym: jump_back_entry info: 11 other: 00 shndx: 8 value: 2008 size: 8
sym: jump_back_entry value: 3ff58008 addr: 3ff517cc
R_X86_64_64
sym: .rodata.str1.1 info: 03 other: 00 shndx: 5 value: 0 size: 0
sym: .rodata.str1.1 value: 3ff54fab addr: 3ff517db
R_X86_64_64
sym:    sprintf info: 12 other: 00 shndx: 1 value: 424 size: 96
sym: sprintf value: 3ff51424 addr: 3ff517e5
R_X86_64_64
sym: panic_kernel info: 11 other: 00 shndx: 8 value: 2010 size: 1
sym: panic_kernel value: 3ff58010 addr: 3ff517f2
R_X86_64_64
sym: crashdump_backup_memory info: 12 other: 00 shndx: 1 value: cb3 size: 3e
sym: crashdump_backup_memory value: 3ff51cb3 addr: 3ff51801
R_X86_64_64
sym: jump_back_entry info: 11 other: 00 shndx: 8 value: 2008 size: 8
sym: jump_back_entry value: 3ff58008 addr: 3ff5180e
R_X86_64_64
sym: x86_setup_jump_back_entry info: 12 other: 00 shndx: 1 value: 7b8 size: 38
sym: x86_setup_jump_back_entry value: 3ff517b8 addr: 3ff5181e
R_X86_64_64
sym: jump_back_entry info: 11 other: 00 shndx: 8 value: 2008 size: 8
sym: jump_back_entry value: 3ff58008 addr: 3ff5182d
R_X86_64_64
sym: x86_setup_jump_back_entry info: 12 other: 00 shndx: 1 value: 7b8 size: 38
sym: x86_setup_jump_back_entry value: 3ff517b8 addr: 3ff5183d
R_X86_64_64
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58047 addr: 3ff51867
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff5804f addr: 3ff5186d
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58075 addr: 3ff5188d
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff5807f addr: 3ff51893
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58089 addr: 3ff51899
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58093 addr: 3ff5189f
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58076 addr: 3ff518a6
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff5808d addr: 3ff518ad
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff5806d addr: 3ff51977
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58075 addr: 3ff5197d
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff5809b addr: 3ff5199d
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff580a5 addr: 3ff519a3
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff580af addr: 3ff519a9
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff580b9 addr: 3ff519af
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff580e2 addr: 3ff519f2
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff5812b addr: 3ff51a35
R_X86_64_PC32
sym: backup_src_size info: 11 other: 00 shndx: 8 value: 2070 size: 8
sym: backup_src_size value: 3ff58070 addr: 3ff51cb5
R_X86_64_64
sym: backup_start info: 11 other: 00 shndx: 8 value: 2080 size: 8
sym: backup_start value: 3ff58080 addr: 3ff51cc7
R_X86_64_64
sym: backup_src_start info: 11 other: 00 shndx: 8 value: 2078 size: 8
sym: backup_src_start value: 3ff58078 addr: 3ff51cd9
R_X86_64_64
sym:     memcpy info: 12 other: 00 shndx: 1 value: 581 size: 18
sym: memcpy value: 3ff51581 addr: 3ff51ce6
R_X86_64_64
sym: serial_base info: 11 other: 00 shndx: 8 value: 2090 size: 2
sym: serial_base value: 3ff58090 addr: 3ff51cf3
R_X86_64_64
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58088 addr: 3ff51d00
R_X86_64_64
sym: serial_baud info: 11 other: 00 shndx: 8 value: 208c size: 4
sym: serial_baud value: 3ff5808c addr: 3ff51d3a
R_X86_64_64
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58088 addr: 3ff51d69
R_X86_64_64
sym: console_vga info: 11 other: 00 shndx: 8 value: 2093 size: 1
sym: console_vga value: 3ff58093 addr: 3ff51d90
R_X86_64_64
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58098 addr: 3ff51da4
R_X86_64_64
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58098 addr: 3ff51e09
R_X86_64_64
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58094 addr: 3ff51e1e
R_X86_64_64
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58094 addr: 3ff51e37
R_X86_64_64
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff58094 addr: 3ff51e6d
R_X86_64_64
sym: console_serial info: 11 other: 00 shndx: 8 value: 2092 size: 1
sym: console_serial value: 3ff58092 addr: 3ff51e81
R_X86_64_64
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51cf1 addr: 3ff51e90
R_X86_64_64
sym: sha256_process info: 12 other: 00 shndx: 1 value: 1170 size: 2a25
sym: sha256_process value: 3ff52170 addr: 3ff54bef
R_X86_64_64
sym:     memcpy info: 12 other: 00 shndx: 1 value: 581 size: 18
sym: memcpy value: 3ff51581 addr: 3ff54c53
R_X86_64_64
sym: sha256_process info: 12 other: 00 shndx: 1 value: 1170 size: 2a25
sym: sha256_process value: 3ff52170 addr: 3ff54c65
R_X86_64_64
sym:     memcpy info: 12 other: 00 shndx: 1 value: 581 size: 18
sym: memcpy value: 3ff51581 addr: 3ff54c93
R_X86_64_64
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff54ba0 addr: 3ff54cb7
R_X86_64_64
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff54ba0 addr: 3ff54d1a
R_X86_64_64
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff580a0 addr: 3ff54d27
R_X86_64_64
sym:    entry16 info: 10 other: 00 shndx: 1 value: 850 size: 0
sym: entry16 value: 3ff51850 addr: 3ff54e58
R_X86_64_64
sym:    entry32 info: 10 other: 00 shndx: 1 value: 5c0 size: 0
sym: entry32 value: 3ff515c0 addr: 3ff54ee0
R_X86_64_64
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54ef0 addr: 3ff54ef2
R_X86_64_64
sym:    .rodata info: 03 other: 00 shndx: 3 value: 0 size: 0
sym: .rodata value: 3ff54f20 addr: 3ff54f22
R_X86_64_64
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51000 addr: 3ff54fe8
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51134 addr: 3ff5501c
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51187 addr: 3ff55050
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51424 addr: 3ff5509c
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff514ba addr: 3ff550b8
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff5155a addr: 3ff550f0
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff5156d addr: 3ff55104
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51581 addr: 3ff55118
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51599 addr: 3ff5512c
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51762 addr: 3ff55158
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff517b8 addr: 3ff55178
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff517f0 addr: 3ff5518c
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51cb3 addr: 3ff551c8
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51cf1 addr: 3ff551f8
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51d8e addr: 3ff5520c
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff51eb2 addr: 3ff55248
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff520e4 addr: 3ff55278
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff52120 addr: 3ff552a8
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff52170 addr: 3ff552bc
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff54ba0 addr: 3ff55308
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff54cb0 addr: 3ff5536c
R_X86_64_PC32
sym:      .text info: 03 other: 00 shndx: 1 value: 0 size: 0
sym: .text value: 3ff54cd0 addr: 3ff55380
R_X86_64_PC32
sym:      .data info: 03 other: 00 shndx: 8 value: 0 size: 0
sym: .data value: 3ff56140 addr: 3ff56142
R_X86_64_64
Loaded purgatory at addr 0x3ff51000
Loaded real-mode code and command line at 0x3000
Loaded 32bit kernel at 0x100000
initrd_addr_max is 0x7fffffff
Loaded initrd at 0x3f3bf000 size 0xb91b8e
fix.id is: virtio_gpudrmfb.
setup_linux_vesafb: VIDEO_TYPE_VLFB setuped.
E820 memmap:
0000000000000000-0000000000000fff (2)
0000000000001000-000000000009ffff (1)
00000000000a0000-00000000000fffff (2)
0000000000100000-000000003ff59fff (1)
000000003ff5a000-000000003fffffff (2)
00000000b0000000-00000000bfffffff (2)
00000000fed40000-00000000fed44fff (2)
/sys/firmware/edd does not exist.
kexec_load: entry = 0x3ff51730 flags = 0x3e0000
nr_segments = 4
segment[0].buf   = 0x1501120
segment[0].bufsz = 0x40b4
segment[0].mem   = 0x3000
segment[0].memsz = 0x5000
segment[1].buf   = 0x7fc93d268020
segment[1].bufsz = 0x50eea0
segment[1].mem   = 0x100000
segment[1].memsz = 0x50f000
segment[2].buf   = 0x7fc93c6d2020
segment[2].bufsz = 0xb91b8e
segment[2].mem   = 0x3f3bf000
segment[2].memsz = 0xb92000
segment[3].buf   = 0x14fa020
segment[3].bufsz = 0x70e0
segment[3].mem   = 0x3ff51000
segment[3].memsz = 0x9000
TRACE: Under /bin/tpmr
Starting the new kernel

Compressed framebuffer requires the driver to track updates to the
framebuffer from the CPU and update the compressed framebuffer.  This
doesn't work if we kexec into an OS that will use the linear
framebuffer, so disable it.  (The OS kernel can still use compressed
framebuffer if it has i915.)

Linux 5.8 enabled compressed framebuffer on more chipsets using i915,
which is why this stopped working.

memtest86+ and Debian (manually blacklisted i915, comparable to
netinst) now boot correctly on Librem 15v4.  This will need to be
enabled for other boards too.

Signed-off-by: Jonathon Hall <[email protected]>
tlaurion added a commit to tlaurion/heads that referenced this pull request Apr 18, 2023
daringer added a commit to daringer/heads that referenced this pull request Apr 19, 2023
@daringer
Copy link
Collaborator

daringer commented Apr 19, 2023

As to be seen by the reference, this solution works for me on a novacustom nv4xpz (12th gen intel) together with some more twirks to get into heads initially (simplefb). Here's my current state: master...daringer:heads:nitropad-x

Notable changes/differences: GOP init for gfx + simplefb + 6.1 kernel

awesome work folks, thanks!

@tlaurion
Copy link
Collaborator

tlaurion commented Apr 19, 2023

b7adbb6 x230-maximized rom (https://output.circle-artifacts.com/output/job/fccd3747-19de-454c-ab0e-2341d1308ad4/artifacts/0/build/x86/x230-maximized/heads-x230-maximized-v0.2.0-1527-gb7adbb6.rom) was able to boot directly into Tinycore 64 bit (http://tinycorelinux.net/14.x/x86_64/release/TinyCorePure64-14.0.iso) dd'ed onto usb thumb drive. (@saber might be interested. Other isolinux fix are needed to boot detached signed iso, which is #1374 )

Will fix all other configs and push into seperate PR for cherry-picking.

@paulmenzel
Copy link
Contributor

paulmenzel commented Apr 19, 2023

If Heads is configured with kernel 4.20 or later, the OS kernel is not able to use framebuffer video output.

Was some configuration changed? If not, it’d be great, if you bisected this Linux kernel regression.

@paulmenzel
Copy link
Contributor

Was Linux’ framebuffer configuration changed? Does building with simplefb fix it as it’s done in @daringer’s changes?

CONFIG_SYSFB_SIMPLEFB=y
CONFIG_FB=y

@JonathonHall-Purism
Copy link
Collaborator Author

@paulmenzel I did bisect this (twice 😁 )

The first problem was this commit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6be8f3bd2c78915a9f3a058a346ae93068d35c01

Linux now hides the framebuffer address from userspace. That makes sense, but kexec uses it to populate the boot parameters for the new kernel. There were a Kconfig and module parameter added later to keep the old behavior for compatibility, which I enabled here.

The second problem (specific to i915 apparently) was this: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=691f7ba58d5220bbb06392054a6e50abdd393516

More devices started using a compressed framebuffer in more situations. We can only provide a flat framebuffer to the new OS, so I set the module parameter to disable this.

I'm not really sure what the long term "perfect solution" is here, it seems like having kexec do this is making a lot of assumptions about how the kernel has set this framebuffer up, and it still doesn't work on ast (and probably others), looks like they are using a shadow framebuffer in the kernel and we need the real framebuffer address somehow. This works for i915 for now, but maybe a more ideal solution would be to have the host kernel provide its framebuffer address to the new kernel instead of doing it in userspace?

CONFIG_SYSFB_SIMPLEFB=y

Don't think so, because coreboot isn't initializing graphics. The first graphics initialization is done by the Heads kernel's i915 driver (or other driver), then we use that as the "firmware" framebuffer for the new kernel.

CONFIG_FB=y

This one is already enabled.

Allow leaking the DRM framebuffer pointer to userspace, and disable
framebuffer compression, like librem_15v4.

Tested booting memtest86+ and Debian netinstaller on Mini v2.

Do not enable this for L1UM, it uses Aspeed graphics which still don't
work.  qemu uses virtio graphics, which also are not working.

Signed-off-by: Jonathon Hall <[email protected]>
Add CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM and related kernel parameters to
t440p.  This board is already on kernel 5.10 and uses i915 graphics.

Signed-off-by: Jonathon Hall <[email protected]>
@daringer
Copy link
Collaborator

CONFIG_SYSFB_SIMPLEFB=y

Don't think so, because coreboot isn't initializing graphics. The first graphics initialization is done by the Heads kernel's i915 driver (or other driver), then we use that as the "firmware" framebuffer for the new kernel.

For my hardware setup this was the only thing that helped for HEADS to display anything at all. But I did not try to leave it out and use your kernel commandline instead:

CONFIG_LINUX_COMMAND_LINE="iommu=pt quiet loglevel=2 video=eDP-1:1920x1080 drm_kms_helper.drm_leak_fbdev_smem=1 i915.enable_fbc=0"

@JonathonHall-Purism do you think using this command line instead of CONFIG_SYSFB_SIMPLEFB should work? and if so, does it make any difference ?

@daringer
Copy link
Collaborator

daringer commented Apr 19, 2023

As a side note, I am using GOP init for the gfx and coreboot logs showed me this:

PCI: 00:02.0 init
GMA: Found VBT in CBFS
GMA: Found valid VBT in CBFS
framebuffer_info: bytes_per_line: 7680, bits_per_pixel: 32
                   x_res x y_res: 1920 x 1080, size: 8294400 at 0x90000000
PCI: 00:02.0 init finished in 0 msecs

which left me with the impression I need to activate FB somehow in the kernel, thus I activated CONFIG_SYSFB_SIMPLEFB

@JonathonHall-Purism
Copy link
Collaborator Author

@tlaurion I enabled the fixes for the other 5.10/i915 boards - other Librems except L1UM, and t440p. I tested mini v2 (I'll test the others in my next PB release). Could you test t440p?

Aspeed graphics still do not work per the edited OP, I don't think I will be able to dive into this right away, I think this is worth finishing for i915 boards and merging. That won't be as simple (hah) of a fix since the real framebuffer address isn't plumbed near anywhere kexec could get it right now, as far as I can tell.

I don't think we can drop the ID checks right now as a result. Maybe we could check if the smem_start is nonzero instead, not sure if ast is populating the shadow framebuffer here or nothing.

I will still bump kexec to 2.0.26, this should be easy, and grab your improvements to tracing, particularly the driver name.

@JonathonHall-Purism
Copy link
Collaborator Author

@JonathonHall-Purism do you think using this command line instead of CONFIG_SYSFB_SIMPLEFB should work? and if so, does it make any difference ?

It depends a bit on how graphics are initialized on your board. If it's like mine (nothing from coreboot, initialized by i915 in Heads kernel), then you need the kernel command line and config changes in this PR. CONFIG_SYSFB_SIMPLEFB will not help because there is no framebuffer provided by coreboot.

If, on the other hand, you do have graphics initialized by coreboot, then you could try using simplefb and having kexec blindly reuse the video mode with --reuse-video-type. You'd also need to remove the graphics driver from the Heads kernel (i915 or other driver) so it doesn't change modes, which would invalidate the firmware-provided mode I believe.

I don't really want to go that route on my boards though - I don't think libgfxinit supports them all so I would have to use VBIOS or a GOP driver (more blobs), and I'm not sure that would work on the servers (don't know if Aspeed's blobs would work without the full BIOS/UEFI environment).

Update kexec to 2.0.26.  Add tracing to framebuffer initialization.  In
particular, the driver name is traced if not recognized, and messages
about kernel config are shown if the kernel doesn't provide the
framebuffer pointer.

Signed-off-by: Jonathon Hall <[email protected]>
@JonathonHall-Purism JonathonHall-Purism changed the title WIP: Kexec framebuffer graphics Fix kexec framebuffer graphics for 5.10 kernel Apr 19, 2023
@JonathonHall-Purism
Copy link
Collaborator Author

@tlaurion Updated to kexec 2.0.26 and added tracing. I think I captured everything you had, and added a few things too.

If there is anything that I missed that you think should be in here, let me know.

Aspeed and qemu still aren't working but I don't really have bandwidth for another deep dive on this at the moment. There's no regression here, so I think the i915 work can be merged, no reason to hold it.

@tlaurion
Copy link
Collaborator

@ThePlexus @srgrint @akunterkontrolle : I would need one of you confirming that:

  • t440p works with current fix (it should!)

@srgrint
Copy link
Contributor

srgrint commented Apr 21, 2023

I can confirm that I have flashed 353e836 on my t440p. The debian netinst from USB (I have tried bookworm test image) now boots fine. My installed debian distribution on the hard drive still works as well!

@JonathonHall-Purism
Copy link
Collaborator Author

This comment sounds like a blocker (thank you @lankredotp41 for mentioning it!): #1351 (comment)

Per the comment, newer kexec now prefers multiboot2 by default, defeating the segment 0 / EBDA patch.

We should check this out - @tlaurion the patch mentions Xen but I'm not sure if that whole chunk relates to Xen or just those few lines. Do you know offhand what this patch was for?

@tlaurion
Copy link
Collaborator

tlaurion commented Apr 21, 2023

@JonathonHall-Purism :

My boards don't provide anything from coreboot, and we would prefer not to have to include libgfxinit since we are already shipping a driver in the Heads kernel.

We discussed it off github : coreboot savedefconfig format hides the facts, but mostly all librem boards currently enable libgfxinit and can now be more easily seen with helpers I added under 29c4b5c.


user@heads-tests:~/heads$ find boards/ -type d | awk -F "/" {'print $2'}| while read board; do make BOARD=$board coreboot.save_in_oldconfig_format_in_place; done; grep -Rn "CONFIG_MAINBOARD_USE_LIBGFXINIT=y" config/coreboot-*
config/coreboot-librem_13v2.config:449:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-librem_13v4.config:449:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-librem_14.config:449:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-librem_15v3.config:449:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-librem_15v4.config:449:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-librem_mini.config:445:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-librem_mini_v2.config:445:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-t420.config:449:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-t420-maximized.config:450:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-t430-legacy.config:442:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-t430-maximized.config:449:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-t440p.config:388:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-t520-maximized.config:446:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-t530-maximized.config:452:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-w530-maximized.config:452:CONFIG_MAINBOARD_USE_LIBGFXINIT=y
config/coreboot-x230-maximized-fhd_edp.config:448:CONFIG_MAINBOARD_USE_LIBGFXINIT=y

The results above do not reflect the reality since my PR already attempts to fix some, but is not complete as of now.
(I do not have all boards coreboot version locally extracted either... so results are really imperfect)
Just needed to let things here so I do not forget.

Ideal would really be to have CONFIG_NO_GFX_INIT=y so that even if FSP setups GOP, we do not rely on libgfxinit at all if possible (to get away of gnat as soon as possible even though #1269 is pushing for gnat6 inclusion, best would be to not depend on it and have reproducible build env in the long run, even more if libgfxinit is not needed at all).

user@heads-tests:~/heads$ grep -Rn "CONFIG_NO_GFX_INIT=y" config/coreboot-*
config/coreboot-librem_l1um.config:426:CONFIG_NO_GFX_INIT=y
config/coreboot-p8z77-m_pro-tpm1.config:382:CONFIG_NO_GFX_INIT=y
config/coreboot-t420-maximized.config.old:16:CONFIG_NO_GFX_INIT=y
config/coreboot-t430-legacy-flash.config:443:CONFIG_NO_GFX_INIT=y
config/coreboot-talos-2.config:292:CONFIG_NO_GFX_INIT=y
config/coreboot-x220.config:448:CONFIG_NO_GFX_INIT=y
config/coreboot-x220-maximized.config:448:CONFIG_NO_GFX_INIT=y
config/coreboot-x230-legacy.config:441:CONFIG_NO_GFX_INIT=y
config/coreboot-x230-legacy-flash.config:443:CONFIG_NO_GFX_INIT=y
config/coreboot-x230-maximized.config:448:CONFIG_NO_GFX_INIT=y

Also note that boards relying on VGA_BIOS are out of the list:

user@heads-tests:~/heads$ grep -Rn "CONFIG_VGA_BIOS=y" config/coreboot-*
config/coreboot-t530-dgpu-hotp-maximized.config:12:CONFIG_VGA_BIOS=y
config/coreboot-t530-dgpu-maximized.config:111:CONFIG_VGA_BIOS=y
config/coreboot-w530-dgpu-K1000m-maximized.config:111:CONFIG_VGA_BIOS=y
config/coreboot-w530-dgpu-K2000m-maximized.config:111:CONFIG_VGA_BIOS=y
config/coreboot-w530-dgpu-K2000m-maximized.config.old:12:CONFIG_VGA_BIOS=y

But that is no reason to not enable CONFIG_NO_GFX_INIT=y even to them:
user@heads-tests:~/heads$ grep -Rn "CONFIG_VGA_BIOS=y" config/coreboot-* | awk -F ":" {'print $1'}| while read config; do grep "CONFIG_NO_GFX_INIT=y" $config; done

My only current doubt is around edp board including coreboot.review patch, which provides a new vbt and seems to rely on libgfxinit to do what otherwise seems to be done per FSP, but I would have to dive deeper into this, the simplest would be probably to also activate NO_GFX for that board as well and see how tings go gor board owners.

@daringer
Copy link
Collaborator

Did someone test this with QubesOS, the same config which properly boots a recent Ubuntu is not working for me for QubesOS. It looks like the same issue we had with the linux kernel before. Using this https://github.com/daringer/heads/tree/nitropad-x setup...

@marmarek are you maybe aware of issues with kexec with recent kernels + QubesOS/XEN ?

@daringer
Copy link
Collaborator

Using this https://github.com/daringer/heads/tree/nitropad-x setup...

rebased on top of this PR, pulled in missing patches - I can confirm that using the updated kexec leads to no issues. So booting an Ubuntu LTS looks good, QubesOS still doesn't work but I suspect a too old kernel version here

@tlaurion
Copy link
Collaborator

tlaurion commented Apr 26, 2023

@daringer as discussed off gihub:

https://www.qubes-os.org/news/2023/03/14/qubes-4-1-2/#whats-new-in-qubes-412

kernel-latest available as a boot option when starting the installer

You have tried this option on Q4.1.2 installer?
I would have expected February 2023 packed 6.x kernel to contain latest i915 driver, but I will let you verify this.

@tlaurion
Copy link
Collaborator

tlaurion commented Apr 26, 2023

@daringer:

rebased on top of this PR, pulled in missing patches - I can confirm that using the updated kexec leads to no issues. So booting an Ubuntu LTS looks good, QubesOS still doesn't work but I suspect a too old kernel version here

Also discussed off github and above, kexec'ing into other kernel is not using the same codepath as multiboot (kexec 2.0.22) or multiboot2 (kexec 2.0.26).

no-real-mode and vga=current are passed as additional arguments to Xen and kexec has a patch under heads tree that works for multiboot but not multiboot2 used to boot into xen.

I have tested booting Qubes q4.1 and q4.2 from this PR on x230. But graphics only appears after OS loads i915 driver, so the kexec call seems "frozen" until Plymouth loads graphics (DRM+i915) just before the LUKS unlock passphrase prompt.

Short version: i915drmfb additional I'd added into kexec patch affects non-multiboot kexec only: I have seen no improvement nor regression as compared to master when booting q4.1/q4.2(xen) whenever multiboot (master) or multiboot2 (this PR with kexec 2.0.26).

@JonathonHall-Purism
Copy link
Collaborator Author

I did some more testing on Mini v2 to clarify the behavior around coreboot libgfxinit.

Bottom line, yes we can CONFIG_NO_GFX_INIT, and I'll set it on these boards once I test a few more devices.

@tlaurion You're right that Librem boards actually did get libgfxinit by default, but the default is to initialize in text mode, so there was no framebuffer provided to the kernel like I had found earlier. Disabling i915 booted in text mode. CONFIG_X86_SYSFB (predecessor to CONFIG_SYSFB_SIMPLEFB) doesn't help either, which is not surprising since the output is in text mode.

I tried configuring coreboot to initialize in framebuffer mode instead (CONFIG_GENERIC_LINEAR_FRAMEBUFFER) but this seems to just fail on this board, the video output was not enabled at all. There was no obvious tracing in coreboot indicating any error. I didn't look into it further since this is not the direction we want to go anyway.

I'll test Qubes too.

daringer added a commit to daringer/heads that referenced this pull request Apr 27, 2023
@JonathonHall-Purism
Copy link
Collaborator Author

Tested 13v2, 14, and Mini v2, memtest86+ and PureOS work. I can reproduce the issue with Qubes though; installed 4.1.2 on my L14 again and get no video on boot. I'll need to investigate what is going on there.

We don't need coreboot to initialize graphics on this boards, this
eliminates some unneeded code and the gnat dependency for them.

Coreboot was using libgfxinit, but it was initializing in text mode.
Heads' kernel will then switch to graphics mode, and we hand that
framebuffer from i915 to the target kernel during kexec.

Signed-off-by: Jonathon Hall <[email protected]>
@JonathonHall-Purism
Copy link
Collaborator Author

Well, I no longer have the issue with Qubes, not sure what was causing it. I set it up on Mini v2 to get serial logs. First boot after set up appeared to have no video output, but after about 5 minutes it actually did bring up video with i915. After that every boot has been fine, and I tried installing again to see if it was a first-boot issue, that was fine too. The install that was on my L14 is fine now too. (Still only have graphics after i915 init, but that's the same as master.)

Unfortunately I didn't get a chance to collect any diagnostics since I wasn't expecting it to disappear on its own. Given the circumstances, this may not be introduced by this PR.

@daringer Are you still having issues booting Qubes?

@daringer
Copy link
Collaborator

daringer commented Apr 27, 2023

@daringer Are you still having issues booting Qubes?

Yes, I still do. Are you using exactly this PR? I am afraid my problem might be a too old kernel version. But you say you installed QubesOS, already this is not working for me, once I kexec into the usb-device with the QubesOS image my display doesn't show anything. From a discussion with @tlaurion I found out I actually didn't boot with the most recent kernel yet, have to redo this!

I will clean up my working state and PR it here, this will then be easier to (and a better place to) discuss this.

@marmarek
Copy link
Contributor

marmarek commented Apr 27, 2023 via email

@daringer
Copy link
Collaborator

Are you doing kexec with -latest kernel as dom0, or the default one?

Nope, I didn't - or to be more precise: I thought I did. Anyways it now works, the issue was self-inflicted as we removed the 6.1-kernel option from our QubesOS OEM images. Shot my own feet, both at once 🤓

@JonathonHall-Purism so I can confirm that there are no issues with QubesOS for this PR

@tlaurion
Copy link
Collaborator

Tested 13v2, 14, and Mini v2, memtest86+ and PureOS work. I can reproduce the issue with Qubes though; installed 4.1.2 on my L14 again and get no video on boot. I'll need to investigate what is going on there.

@marmarek do you recall tests where qubesos would give early kernel console output prior if DRM driver kicking in?

@marmarek
Copy link
Contributor

@marmarek do you recall tests where qubesos would give early kernel console output prior if DRM driver kicking in?

Not really. That might have been the case before (Qubes 4.0?), but nor my memory nor test logs span that long to confirm/deny.

@JonathonHall-Purism
Copy link
Collaborator Author

Thanks @daringer and @marmarek 💯

In that case @tlaurion I think this is ready to merge - fixes i915 framebuffer graphics for Linux distros and memtest. Future work will be getting that to work on Aspeed as well, and possibly Qubes/Xen, but there's no regression, they're the same as before.

@tlaurion
Copy link
Collaborator

Haven't finished pushing 5.x config changes to xx20/xx30 yet but since they aren't impacted as of today, not a real problem

@tlaurion tlaurion merged commit ab1faf5 into linuxboot:master Apr 28, 2023
@akunterkontrolle
Copy link

Can confirm as well for the t440p that this pull request fixes the issues with no framebuffer graphical output. More detailed comment: #1323 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants