mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
Moved graphics.c into console.h, with boot message framework
This commit is contained in:
11
Makefile
11
Makefile
@@ -47,10 +47,14 @@ ASFLAGS ?=
|
||||
|
||||
CFLAGS ?=
|
||||
CFLAGS += $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS)
|
||||
CFLAGS += -DGIT_VERSION="\"$(VERSION)\""
|
||||
CFLAGS += -DGIT_VERSION="L\"$(VERSION)\""
|
||||
CFLAGS += -std=c11 -fno-stack-protector -fpic -fshort-wchar -mno-red-zone
|
||||
CFLAGS += -DEFI_DEBUG=0 -DEFI_DEBUG_CLEAR_MEMORY=0 -DGNU_EFI_USE_MS_ABI -DHAVE_USE_MS_ABI #-DEFI_FUNCTION_WRAPPER
|
||||
|
||||
ifdef MAX_HRES
|
||||
CFLAGS += -DMAX_HRES=$(MAX_HRES)
|
||||
endif
|
||||
|
||||
LDFLAGS ?=
|
||||
LDFLAGS += -L $(BUILD_D) -ggdb
|
||||
LDFLAGS += -nostdlib -znocombreloc -shared -Bsymbolic -fPIC -nostartfiles
|
||||
@@ -76,7 +80,7 @@ QEMU ?= qemu-system-x86_64
|
||||
GDBPORT ?= 27006
|
||||
CPUS ?= 2
|
||||
OVMF ?= assets/ovmf/x64/OVMF.fd
|
||||
QEMUOPTS := -bios $(OVMF) -hda $(BUILD_D)/fs.img -smp $(CPUS) -m 512 -nographic $(QEMUEXTRA)
|
||||
QEMUOPTS := -bios $(OVMF) -hda $(BUILD_D)/fs.img -smp $(CPUS) -m 512 $(QEMUEXTRA)
|
||||
|
||||
|
||||
all: $(BUILD_D)/fs.img
|
||||
@@ -150,6 +154,9 @@ $(BUILD_D)/fs.iso: $(BUILD_D)/fs.img
|
||||
xorriso -as mkisofs -R -f -e fs.img -no-emul-boot -o $@ $(BUILD_D)/iso
|
||||
|
||||
qemu: $(BUILD_D)/fs.img
|
||||
"$(QEMU)" $(QEMUOPTS) -nographic
|
||||
|
||||
qemu-window: $(BUILD_D)/fs.img
|
||||
"$(QEMU)" $(QEMUOPTS)
|
||||
|
||||
qemu-gdb: $(BUILD_D)/fs.img $(BUILD_D)/kernel.debug.efi
|
||||
|
||||
116
src/arch/x86_64/console.c
Normal file
116
src/arch/x86_64/console.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "utility.h"
|
||||
|
||||
UINTN ROWS = 0;
|
||||
UINTN COLS = 0;
|
||||
|
||||
EFI_STATUS
|
||||
con_initialize (const CHAR16 *version)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
|
||||
Print(L"Setting console display mode...\n");
|
||||
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *gfx_out_proto;
|
||||
EFI_GUID gfx_out_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||
|
||||
status = ST->BootServices->LocateProtocol(
|
||||
&gfx_out_guid, NULL, (void**)&gfx_out_proto);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "LocateProtocol gfx");
|
||||
|
||||
const uint32_t modes = gfx_out_proto->Mode->MaxMode;
|
||||
uint32_t res =
|
||||
gfx_out_proto->Mode->Info->HorizontalResolution *
|
||||
gfx_out_proto->Mode->Info->VerticalResolution;
|
||||
uint32_t best = gfx_out_proto->Mode->Mode;
|
||||
|
||||
for (uint32_t i = 0; i < modes; ++i) {
|
||||
UINTN size = 0;
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info = NULL;
|
||||
status = gfx_out_proto->QueryMode(gfx_out_proto, i, &size, &info);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode");
|
||||
|
||||
#ifdef MAX_HRES
|
||||
if (info->HorizontalResolution > MAX_HRES)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
const uint32_t new_res =
|
||||
info->HorizontalResolution *
|
||||
info->VerticalResolution;
|
||||
|
||||
if (new_res > res) {
|
||||
best = i;
|
||||
res = new_res;
|
||||
}
|
||||
}
|
||||
|
||||
status = gfx_out_proto->SetMode(gfx_out_proto, best);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "SetMode %d/%d", best, modes);
|
||||
|
||||
status = ST->ConOut->QueryMode(
|
||||
ST->ConOut,
|
||||
ST->ConOut->Mode->Mode,
|
||||
&COLS, &ROWS);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode");
|
||||
|
||||
status = ST->ConOut->ClearScreen(ST->ConOut);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "ClearScreen");
|
||||
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTCYAN);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"Popcorn OS ");
|
||||
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTMAGENTA);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)version);
|
||||
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L" booting...\r\n");
|
||||
|
||||
con_status_begin(L"Setting console display mode: ");
|
||||
Print(L"%ux%u (%ux%u chars)\n",
|
||||
gfx_out_proto->Mode->Info->HorizontalResolution,
|
||||
gfx_out_proto->Mode->Info->VerticalResolution,
|
||||
ROWS, COLS);
|
||||
con_status_ok();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
con_status_begin (const CHAR16 *message)
|
||||
{
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)message);
|
||||
}
|
||||
|
||||
void
|
||||
con_status_ok ()
|
||||
{
|
||||
UINTN row = ST->ConOut->Mode->CursorRow;
|
||||
ST->ConOut->SetCursorPosition(ST->ConOut, COLS - 8, row - 1);
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"[");
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_GREEN);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L" ok ");
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"]\r");
|
||||
}
|
||||
|
||||
void
|
||||
con_status_fail (const CHAR16 *error)
|
||||
{
|
||||
UINTN row = ST->ConOut->Mode->CursorRow;
|
||||
ST->ConOut->SetCursorPosition(ST->ConOut, COLS - 8, row - 1);
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"[");
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTRED);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"failed");
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"]\r\n");
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_RED);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)error);
|
||||
}
|
||||
7
src/arch/x86_64/console.h
Normal file
7
src/arch/x86_64/console.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include <efi.h>
|
||||
|
||||
EFI_STATUS con_initialize (const CHAR16 *version);
|
||||
void con_status_begin (const CHAR16 *message);
|
||||
void con_status_ok ();
|
||||
void con_status_fail (const CHAR16 *error);
|
||||
@@ -1,53 +0,0 @@
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
EFI_STATUS
|
||||
set_graphics_mode (EFI_SYSTEM_TABLE *SystemTable)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
|
||||
Print(L"Setting console display mode... ");
|
||||
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *gfx_out_proto;
|
||||
EFI_GUID gfx_out_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||
|
||||
status = SystemTable->BootServices->LocateProtocol(
|
||||
&gfx_out_guid, NULL, (void**)&gfx_out_proto);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "LocateProtocol gfx");
|
||||
|
||||
const uint32_t modes = gfx_out_proto->Mode->MaxMode;
|
||||
uint32_t res =
|
||||
gfx_out_proto->Mode->Info->HorizontalResolution *
|
||||
gfx_out_proto->Mode->Info->VerticalResolution;
|
||||
uint32_t best = (uint32_t)-1;
|
||||
|
||||
for (uint32_t i = 0; i < modes; ++i) {
|
||||
UINTN size = 0;
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info = NULL;
|
||||
status = gfx_out_proto->QueryMode(gfx_out_proto, i, &size, &info);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode");
|
||||
|
||||
const uint32_t new_res =
|
||||
info->HorizontalResolution *
|
||||
info->VerticalResolution;
|
||||
|
||||
if (new_res > res) {
|
||||
best = i;
|
||||
res = new_res;
|
||||
}
|
||||
}
|
||||
|
||||
if (best != (uint32_t)-1) {
|
||||
status = gfx_out_proto->SetMode(gfx_out_proto, best);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "SetMode");
|
||||
Print(L"*");
|
||||
}
|
||||
Print(L"%ux%u\n",
|
||||
gfx_out_proto->Mode->Info->HorizontalResolution,
|
||||
gfx_out_proto->Mode->Info->VerticalResolution);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#pragma once
|
||||
#include <efi.h>
|
||||
|
||||
EFI_STATUS set_graphics_mode (EFI_SYSTEM_TABLE *SystemTable);
|
||||
@@ -1,9 +1,13 @@
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include "graphics.h"
|
||||
#include "console.h"
|
||||
#include "utility.h"
|
||||
|
||||
#ifndef GIT_VERSION
|
||||
#define GIT_VERSION L"no version"
|
||||
#endif
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
{
|
||||
@@ -11,10 +15,14 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
|
||||
InitializeLib(ImageHandle, SystemTable);
|
||||
|
||||
Print(L"Popcorn OS " GIT_VERSION L" booting...\n");
|
||||
// When checking the console initialization error,
|
||||
// use CHECK_EFI_STATUS_OR_RETURN because we can't
|
||||
// be sure if the console was fully set up
|
||||
status = con_initialize(GIT_VERSION);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "con_initialize");
|
||||
|
||||
status = set_graphics_mode(SystemTable);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, "set_graphics_mode");
|
||||
// From here on out, use CHECK_EFI_STATUS_OR_FAIL instead
|
||||
// because the console is now set up
|
||||
|
||||
Print(L" SystemTable: %x\n", SystemTable);
|
||||
if (SystemTable)
|
||||
|
||||
18
src/arch/x86_64/utility.c
Normal file
18
src/arch/x86_64/utility.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <efi.h>
|
||||
|
||||
struct ErrorCode {
|
||||
EFI_STATUS code;
|
||||
const CHAR16 *desc;
|
||||
};
|
||||
|
||||
extern struct ErrorCode ErrorCodeTable[];
|
||||
|
||||
const CHAR16 *util_error_message(EFI_STATUS status) {
|
||||
int32_t i = -1;
|
||||
while (ErrorCodeTable[++i].desc != NULL) {
|
||||
if (ErrorCodeTable[i].code == status)
|
||||
return ErrorCodeTable[i].desc;
|
||||
}
|
||||
|
||||
return L"Unknown";
|
||||
}
|
||||
@@ -1,9 +1,19 @@
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include "console.h"
|
||||
|
||||
#define CHECK_EFI_STATUS_OR_RETURN(s, msg) \
|
||||
const CHAR16 *util_error_message(EFI_STATUS status);
|
||||
|
||||
#define CHECK_EFI_STATUS_OR_RETURN(s, msg, ...) \
|
||||
if (EFI_ERROR((s))) { \
|
||||
Print(L"EFI_ERROR: " msg L" %d\n", (s)); \
|
||||
Print(L"EFI_ERROR: " msg L": %s\n", ## __VA_ARGS__, util_error_message(s)); \
|
||||
return (s); \
|
||||
}
|
||||
|
||||
#define CHECK_EFI_STATUS_OR_FAIL(s, msg, ...) \
|
||||
if (EFI_ERROR((s))) { \
|
||||
con_status_fail(util_error_message(s)); \
|
||||
Print(L"\n" msg, ## __VA_ARGS__ ); \
|
||||
while (1) __asm__("hlt"); \
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user