Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 May 2014 11:32:12 -0400
From:      =?UTF-8?Q?Rafael_Esp=C3=ADndola?= <rafael.espindola@gmail.com>
To:        freebsd-current@freebsd.org, Ed Maste <emaste@freebsd.org>
Subject:   [patch] Switch to text mode during efi boot
Message-ID:  <CAG3jReLhdO7xdM8W8M65iokD9y5tFDTR7vRO0Tz8C6d0e5Q3Jw@mail.gmail.com>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
The attached patch causes both boot1 and loader.efi to switch to text
mode. This only
seems to make a difference on Macs where otherwise no information was being
displayed.

The ConsoleControl.h file is copied from
EdkCompatibilityPkg/Foundation/Protocol/ConsoleControl in
https://github.com/tianocore/edk2.

I tested that both programs are able to change to text mode by
enabling only one of them at a time.

With this patch I am able to see loaders output on all the macs I
tried. The kernel boots correctly on a MacPro, but unfortunately it
doesn't seem to be able to find the efi buffer in a MacBookPro.

Some design questions:

* Why do we have both boot1 and loader? It is just the issue with
building a usb image without root that requires having a boot1 that
has a predictable size?

* Even if we want to keep both boot1 and loader, could boot1 use libefi?

* Is it ok to always switch to text mode in libefi or should it
provide a switch_to_text_mode function?

Cheers,
Rafael

[-- Attachment #2 --]
Index: sys/boot/amd64/boot1.efi/boot1.c
===================================================================
--- sys/boot/amd64/boot1.efi/boot1.c	(revision 266159)
+++ sys/boot/amd64/boot1.efi/boot1.c	(working copy)
@@ -26,6 +26,7 @@
 #include <machine/stdarg.h>
 
 #include <efi.h>
+#include <ConsoleControl.h>
 
 #define _PATH_LOADER	"/boot/loader.efi"
 #define _PATH_KERNEL	"/boot/kernel/kernel"
@@ -97,6 +98,7 @@
 static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
 static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
 static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
+static EFI_GUID ConsoleControlGUID =  EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
 
 static EFI_BLOCK_IO *bootdev;
 static EFI_DEVICE_PATH *bootdevpath;
@@ -117,6 +119,16 @@
 	printf(" \n>> FreeBSD EFI boot block\n");
 	printf("   Loader path: %s\n", path);
 
+	EFI_BOOT_SERVICES *BS = systab->BootServices;
+	EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
+	status = BS->LocateProtocol(&ConsoleControlGUID, NULL, (VOID **)& ConsoleControl);
+	if (EFI_ERROR(status))
+		panic("No console control protocol located");
+
+	status = ConsoleControl->SetMode(ConsoleControl, EfiConsoleControlScreenText);
+	if (EFI_ERROR(status))
+		panic("Could not switch to text mode");
+
 	status = systab->BootServices->LocateHandle(ByProtocol,
 	    &BlockIoProtocolGUID, NULL, &nparts, handles);
 	nparts /= sizeof(handles[0]);
Index: sys/boot/efi/include/ConsoleControl.h
===================================================================
--- sys/boot/efi/include/ConsoleControl.h	(revision 0)
+++ sys/boot/efi/include/ConsoleControl.h	(working copy)
@@ -0,0 +1,122 @@
+/*++ 
+
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  ConsoleControl.h
+
+Abstract:
+
+  Abstraction of a Text mode or GOP/UGA screen
+
+--*/
+
+#ifndef __CONSOLE_CONTROL_H__
+#define __CONSOLE_CONTROL_H__
+
+#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \
+  { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} }
+
+typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL   EFI_CONSOLE_CONTROL_PROTOCOL;
+
+
+typedef enum {
+  EfiConsoleControlScreenText,
+  EfiConsoleControlScreenGraphics,
+  EfiConsoleControlScreenMaxValue
+} EFI_CONSOLE_CONTROL_SCREEN_MODE;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) (
+  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
+  OUT EFI_CONSOLE_CONTROL_SCREEN_MODE   *Mode,
+  OUT BOOLEAN                           *GopUgaExists,  OPTIONAL  
+  OUT BOOLEAN                           *StdInLocked    OPTIONAL
+  )
+/*++
+
+  Routine Description:
+    Return the current video mode information. Also returns info about existence
+    of Graphics Output devices or UGA Draw devices in system, and if the Std In
+    device is locked. All the arguments are optional and only returned if a non
+    NULL pointer is passed in.
+
+  Arguments:
+    This         - Protocol instance pointer.
+    Mode         - Are we in text of grahics mode.
+    GopUgaExists - TRUE if Console Spliter has found a GOP or UGA device
+    StdInLocked  - TRUE if StdIn device is keyboard locked
+
+  Returns:
+    EFI_SUCCESS     - Mode information returned.
+
+--*/
+;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) (
+  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
+  IN  EFI_CONSOLE_CONTROL_SCREEN_MODE   Mode
+  )
+/*++
+
+  Routine Description:
+    Set the current mode to either text or graphics. Graphics is
+    for Quiet Boot.
+
+  Arguments:
+    This  - Protocol instance pointer.
+    Mode  - Mode to set the 
+
+  Returns:
+    EFI_SUCCESS     - Mode information returned.
+
+--*/
+;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) (
+  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
+  IN CHAR16                             *Password
+  )
+/*++
+
+  Routine Description:
+    Lock Std In devices until Password is typed.
+
+  Arguments:
+    This     - Protocol instance pointer.
+    Password - Password needed to unlock screen. NULL means unlock keyboard
+
+  Returns:
+    EFI_SUCCESS      - Mode information returned.
+    EFI_DEVICE_ERROR - Std In not locked
+
+--*/
+;
+
+
+
+struct _EFI_CONSOLE_CONTROL_PROTOCOL {
+  EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE           GetMode;
+  EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE           SetMode;
+  EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN        LockStdIn;
+};
+
+extern EFI_GUID gEfiConsoleControlProtocolGuid;
+
+#endif

Property changes on: sys/boot/efi/include/ConsoleControl.h
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: sys/boot/efi/libefi/libefi.c
===================================================================
--- sys/boot/efi/libefi/libefi.c	(revision 266159)
+++ sys/boot/efi/libefi/libefi.c	(working copy)
@@ -30,6 +30,7 @@
 #include <efi.h>
 #include <efilib.h>
 #include <stand.h>
+#include <ConsoleControl.h>
 
 EFI_HANDLE		IH;
 EFI_SYSTEM_TABLE	*ST;
@@ -82,6 +83,8 @@
 efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
 {
 	static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL;
+	static EFI_GUID console_control_protocol =  EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+	EFI_CONSOLE_CONTROL_PROTOCOL *console_control = NULL;
 	EFI_LOADED_IMAGE *img;
 	CHAR16 *argp, *args, **argv;
 	EFI_STATUS status;
@@ -92,6 +95,14 @@
 	BS = ST->BootServices;
 	RS = ST->RuntimeServices;
 
+	status = BS->LocateProtocol(&console_control_protocol, NULL, (VOID **)& console_control);
+	if (EFI_ERROR(status))
+		BS->Exit(IH, status, 0, NULL);
+
+	status = console_control->SetMode(console_control, EfiConsoleControlScreenText);
+	if (EFI_ERROR(status))
+		BS->Exit(IH, status, 0, NULL);
+
 	heapsize = 2 * 1024 * 1024;
 	status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
 	    EFI_SIZE_TO_PAGES(heapsize), &heap);

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAG3jReLhdO7xdM8W8M65iokD9y5tFDTR7vRO0Tz8C6d0e5Q3Jw>