setos

拙OS
Log | Files | Refs

commit 2e9c53fab2e2c0d0a28b608921af7993449d8aeb
parent 710525bc8aa30bc58163f35a7249ab1fa79b1358
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 16 Mar 2024 15:55:10 +0900

implement elementary printf

Diffstat:
MMakefile | 2+-
Mhello.c | 41++++++++++++++++++++++++++++++++++++-----
Muefi.h | 37+++++++++++++++++++++++++++++++++----
Mutils.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mutils.h | 7+++++++
5 files changed, 129 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ CC = x86_64-w64-mingw32-gcc -CFLAGS = -shared -nostdinc -nostdlib -mno-red-zone -fno-stack-protector \ +CFLAGS = -shared -nostdlib -mno-red-zone -fno-stack-protector \ -mno-stack-arg-probe -Wall -e EfiMain OBJCOPY = objcopy SRC = hello.c utils.c diff --git a/hello.c b/hello.c @@ -1,27 +1,57 @@ #include "uefi.h" #include "utils.h" +EFI_SYSTEM_TABLE *SystemTable; + EFI_STATUS -EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *systab) { + // init global variable. + SystemTable = systab; + EFI_STATUS stat; CHAR16 s[19]; // Output firmware bender. + SystemTable->ConOut->ClearScreen(SystemTable->ConOut); SystemTable->ConOut->OutputString(SystemTable->ConOut, SystemTable->FirmwareVendor); + printf("--%s--%d--\n\r", "char *", 1259320); // Output memory map information. - UINTN mmsize = sizeof(EFI_MEMORY_DESCRIPTOR) * 1024; - EFI_MEMORY_DESCRIPTOR mmap[1024]; + UINTN mmsize = 8196; + char mmbuf[8196]; + EFI_MEMORY_DESCRIPTOR *mmap; UINTN mkey; UINTN dsize; UINT32 dver; + mmap = (EFI_MEMORY_DESCRIPTOR *) mmbuf; stat = SystemTable->BootServices->GetMemoryMap(&mmsize, mmap, &mkey, &dsize, &dver); if (stat != EFI_SUCCESS) { return stat; } - SystemTable->ConOut->OutputString(SystemTable->ConOut, sprinth(mmap[0].Type, s)); + + for (; mmap < (EFI_MEMORY_DESCRIPTOR *)(mmbuf + mmsize); + mmap = (EFI_MEMORY_DESCRIPTOR *) (((char *)mmap) + dsize)) { + if (mmap->Type != EfiConventionalMemory) { + continue; + } + SystemTable->ConOut->OutputString(SystemTable->ConOut, sprinth(mmap->Type, s)); + s[0] = '\t'; s[1] = '\0'; + SystemTable->ConOut->OutputString(SystemTable->ConOut, s); + SystemTable->ConOut->OutputString(SystemTable->ConOut, sprinth(mmap->VirtualStart, s)); + s[0] = '\t'; s[1] = '\0'; + SystemTable->ConOut->OutputString(SystemTable->ConOut, s); + SystemTable->ConOut->OutputString(SystemTable->ConOut, sprinth(mmap->PhysicalStart, s)); + s[0] = '\t'; s[1] = '\0'; + SystemTable->ConOut->OutputString(SystemTable->ConOut, s); + SystemTable->ConOut->OutputString(SystemTable->ConOut, sprinth(mmap->NumberOfPages, s)); + s[0] = '\t'; s[1] = '\0'; + SystemTable->ConOut->OutputString(SystemTable->ConOut, s); + SystemTable->ConOut->OutputString(SystemTable->ConOut, sprinth(mmap->Attribute, s)); + s[0] = '\n'; s[1] = '\r'; s[2] = '\0'; + SystemTable->ConOut->OutputString(SystemTable->ConOut, s); + } // Echo back user input. EFI_INPUT_KEY Key; @@ -31,5 +61,6 @@ EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) str[0] = Key.UnicodeChar; SystemTable->ConOut->OutputString(SystemTable->ConOut, str); } - return 0; + + return EFI_SUCCESS; } diff --git a/uefi.h b/uefi.h @@ -36,17 +36,46 @@ typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL { EFI_INPUT_READ_KEY ReadKeyStroke; } EFI_SIMPLE_TEXT_INPUT_PROTOCOL; +typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; typedef EFI_STATUS (EFIAPI *EFI_TEXT_STRING)( - IN struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN CHAR16 *String + IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS (EFIAPI *EFI_TEXT_CLEAR_SCREEN)( + IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This ); -typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL { +struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL { void *dummy; EFI_TEXT_STRING OutputString; -} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; + void *dummy1[4]; + EFI_TEXT_CLEAR_SCREEN ClearScreen; +}; + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiPersistentMemory, + EfiUnacceptedMemoryType, + EfiMaxMemoryType, +} EFI_MEMORY_TYPE; typedef struct { UINT32 Type; diff --git a/utils.c b/utils.c @@ -1,3 +1,5 @@ +#include <stdarg.h> + #include "uefi.h" #include "utils.h" @@ -18,3 +20,53 @@ sprinth(UINT64 n, CHAR16 s[19]) s[19] = L'\0'; return s; } + +int +printf(char *fmt, ...) +{ + va_list ap; + CHAR16 _buf[1024], *buf = _buf; + EFI_STATUS stat; + + char *s; + int d, e; + + va_start(ap, fmt); + for (;*fmt;) { + if (*fmt != '%') { + *buf++ = (CHAR16) *fmt++; + continue; + } + fmt++; + switch (*fmt++) { + case '%': + *buf++ = L'%'; + break; + case 's': + s = va_arg(ap, char *); + for (;*s;) { + *buf++ = (CHAR16) *s++; + } + break; + case 'd': + d = va_arg(ap, int); + if (d < 0) { + *buf++ = '-'; + d = -d; + } + for (e = 1; e <= d; e *= 10) { + } + for (e /= 10; e >= 1; e /= 10) { + *buf++ = (CHAR16) ('0' + ((d / e) % 10)); + } + break; + } + } + va_end(ap); + *buf = L'\0'; + stat = SystemTable->ConOut->OutputString(SystemTable->ConOut, _buf); + if (stat != EFI_SUCCESS) { + return -1; + } + return (int) (buf - _buf); +} diff --git a/utils.h b/utils.h @@ -1,6 +1,13 @@ // #include "uefi.h" +extern EFI_SYSTEM_TABLE *SystemTable; + // Printh converts the integer into a string of hex representation. // It returns the second argument. // The second argument should have length of 19 ("0x" + "0123456789abcdef" + "\0"). CHAR16 *sprinth(UINT64, CHAR16[19]); + +// Printf prints formatted string to ConOut. +// Can't format a string longer than 1024 CHAR16s. +// It returns number of CHAR16s written excluding the final NULL. +int printf(char *fmt, ...);