public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/boot: This program cannot be run in DOS mode.$
@ 2019-04-01 10:24 Pali Rohár
  2019-04-08 18:04 ` Pavel Machek
  0 siblings, 1 reply; 5+ messages in thread
From: Pali Rohár @ 2019-04-01 10:24 UTC (permalink / raw)
  To: x86, linux-kernel

Every EFI binary is in PE format. And we know that PE format needs to have
MZ MS-DOS header as there is written offset to PE header.

Therefore generated bzImage binary with CONFIG_EFI_STUB option is MS-DOS
executable binary.

We already know the "requirement" that Windows PE executable started in
MS-DOS must print legendary and famous message to computer screen:
"This program cannot be run in DOS mode."

But trying to run that bzImage of Linux kernel with MZ header just cause
freezing whole MS-DOS instead of writing "the correct message" to user.
This is not the compliant behavior of PE executables!

This patch fixes this problem. When Linux kernel compiled with
CONFIG_EFI_STUB is started in MS-DOS then it prints message:

  This program cannot be run in DOS mode.
  To load Linux kernel from DOS mode use LOADLIN.EXE.

So it also helps MS-DOS users how to "correctly" start this bzImage binary
by mentioning LOADLIN.EXE. Note that MS-DOS strings are not null-terminated
but rather dollar-terminated.

To have error message unified bugger_off_msg for BIOS boot block code was
changed to:

  This program cannot be run in BIOS mode.

So if you copy generated bzImage directly to boot sector and try to boot it
by BIOS you get this new updated message.

Due to fixed offset of setup header (0x1f1), PE header was moved after
entrytext section. bstext and bsdata sections where is full MZ header and
MS-DOS code is now bigger.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
---
 arch/x86/boot/header.S | 55 +++++++++++++++++++++++++++++++++++++++++++-------
 arch/x86/boot/setup.ld |  1 +
 2 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 850b8762e889..58fcab7d00c8 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -45,6 +45,46 @@ bootsect_start:
 	# "MZ", MS-DOS header
 	.byte 0x4d
 	.byte 0x5a
+
+	# Explicitly enter this as bytes, or the assembler
+	# tries to generate a 3-byte jump here, which causes
+	# everything else to push off to the wrong offset.
+	.byte	0xeb    # short (2-byte) jump
+	.byte	bios_start-1f
+1:
+
+	.org	0x04
+	.short	3       # e_cp - Pages in file
+	.short	0       # e_crlc - Relocations
+	.short	4       # e_cparhdr - Size of header in paragraphs
+	.short	0       # e_minalloc - Minimum extra paragraphs needed
+	.short	0xffff  # e_maxalloc - Maximum extra paragraphs needed
+	.short	0       # e_ss - Initial (relative) SS value
+	.short	0       # e_sp - Initial SP value
+	.short	0       # e_csum - Checksum
+	.short	0       # e_ip - Initial IP value
+	.short	-4      # e_cs - Initial (relative) CS value
+	.short	0x40    # e_lfarlc - File address of relocation table
+
+	.org	0x3c
+	.long	pe_header  # Offset to the PE header
+
+	#
+	# MS-DOS start code
+	#
+	push	%cs
+	pop	%ds
+
+	# Write msdos_msg string
+	mov	$msdos_msg, %dx
+	mov	$0x09, %ah
+	int	$0x21
+
+	# Terminate program
+	mov	$0x4c01, %ax
+	int	$0x21
+
+bios_start:
 #endif
 
 	# Normalize the start address
@@ -80,22 +120,23 @@ bs_die:
 	# invoke the BIOS reset code...
 	ljmp	$0xf000,$0xfff0
 
+	.section ".bsdata", "a"
 #ifdef CONFIG_EFI_STUB
-	.org	0x3c
-	#
-	# Offset to the PE header.
-	#
-	.long	pe_header
+msdos_msg:
+	.ascii	"This program cannot be run in DOS mode.\r\n"
+	.ascii	"To load Linux kernel from DOS mode use LOADLIN.EXE.\r\r\n"
+	.ascii	"$"
 #endif /* CONFIG_EFI_STUB */
 
-	.section ".bsdata", "a"
 bugger_off_msg:
-	.ascii	"Use a boot loader.\r\n"
+	.ascii	"This program cannot be run in BIOS mode.\r\n"
+	.ascii	"To load Linux kernel from BIOS mode use a boot loader.\r\n"
 	.ascii	"\n"
 	.ascii	"Remove disk and press any key to reboot...\r\n"
 	.byte	0
 
 #ifdef CONFIG_EFI_STUB
+	.section ".pedata", "a"
 pe_header:
 	.ascii	"PE"
 	.word 	0
diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld
index 0149e41d42c2..c0ec2fe09d2d 100644
--- a/arch/x86/boot/setup.ld
+++ b/arch/x86/boot/setup.ld
@@ -16,6 +16,7 @@ SECTIONS
 	. = 495;
 	.header		: { *(.header) }
 	.entrytext	: { *(.entrytext) }
+	.pedata		: { *(.pedata) }
 	.inittext	: { *(.inittext) }
 	.initdata	: { *(.initdata) }
 	__end_init = .;
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-04-18 11:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-04-01 10:24 [PATCH] x86/boot: This program cannot be run in DOS mode.$ Pali Rohár
2019-04-08 18:04 ` Pavel Machek
2019-04-08 18:08   ` Pali Rohár
2019-04-08 21:25     ` Pavel Machek
2019-04-18 11:27       ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox