setos

拙OS
Log | Files | Refs | LICENSE

commit 568231651d1ad8aecb0274157b4813ea7b445df1
parent 86dac8fe036182531cf5d7a26e618976c22f8d3e
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue,  2 Apr 2024 15:53:48 +0900

add cons_printf

Diffstat:
Msys/include/console.h | 5+++--
Dsys/include/utils.h | 71-----------------------------------------------------------------------
Msys/src/boot/boot.c | 2+-
Msys/src/boot/utils.c | 2+-
Msys/src/kernel/console.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msys/src/kernel/main.c | 6+++---
6 files changed, 86 insertions(+), 78 deletions(-)

diff --git a/sys/include/console.h b/sys/include/console.h @@ -17,4 +17,5 @@ extern AsciiFont asciifont; extern Console console; void cons_putchar(Console *cons, char c); -int cons_print(Console *cons, char *s); -\ No newline at end of file +int cons_print(Console *cons, char *s); +int cons_printf(Console *cons, char *fmt, ...); +\ No newline at end of file diff --git a/sys/include/utils.h b/sys/include/utils.h @@ -1,70 +0,0 @@ -// #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]); - -// Wstr2str converts UTF16-encoded string s16 to string. -// It ignores the high byte. -// caller must ensure that s has enough space. -// It returns s. -char *wstr2str(CHAR16 *s16, char *s8); - -// Efi_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 efi_printf(char *fmt, ...); - -// Open_gop opens the graphics output protocol. -EFI_STATUS open_gop(EFI_HANDLE, EFI_GRAPHICS_OUTPUT_PROTOCOL **); - -// Open_root opens the root directory of the efi image. -EFI_STATUS open_root(EFI_HANDLE, EFI_FILE_PROTOCOL **); - -// ELF header. -typedef struct { - unsigned char ident[16]; - UINT16 type; - UINT16 machine; - UINT32 version; - UINTN entry; - UINTN phoff; - UINTN shoff; - UINT32 flags; - UINT16 ehsize; // ELF header's size. - UINT16 phentsize; - UINT16 phnum; - UINT16 shentsize; - UINT16 shnum; - UINT16 shstrndx; -} ElfHdr; - -typedef struct { - UINT32 type; - UINT32 flags; - UINTN offset; - UINTN vaddr; - UINTN paddr; - UINT64 filesz; - UINT64 memsz; - UINT64 align; -} Phdr; - -#define PT_LOAD 1 - -// Read_ehdr reads elf header and populates ehdr. -// It modifies elf's offset. -EFI_STATUS read_ehdr(EFI_FILE_PROTOCOL *elf, ElfHdr *ehdr); - -// Read_phdr reads elf's program headers and populates phdr. -// It uses ehdr to read phdr. -// It modifies elf's offset. -// Caller should allocate enough space in phdr. -EFI_STATUS read_phdr(EFI_FILE_PROTOCOL *elf, ElfHdr *ehdr, Phdr phdr[]); - -// Load_elf copies loadable segments of elf to the memory specified by the -// vaddr field of each Phdr. -EFI_STATUS load_elf(EFI_FILE_PROTOCOL *elf, ElfHdr *ehdr, Phdr phdr[]); -\ No newline at end of file diff --git a/sys/src/boot/boot.c b/sys/src/boot/boot.c @@ -1,5 +1,5 @@ #include <uefi.h> -#include <utils.h> +#include <uefi_utils.h> EFI_SYSTEM_TABLE *SystemTable; EFI_STATUS EFIAPI diff --git a/sys/src/boot/utils.c b/sys/src/boot/utils.c @@ -1,7 +1,7 @@ #include <stdarg.h> // TODO: implement stdarg.h by my self #include <uefi.h> -#include <utils.h> +#include <uefi_utils.h> CHAR16 * sprinth(UINT64 n, CHAR16 s[19]) diff --git a/sys/src/kernel/console.c b/sys/src/kernel/console.c @@ -1,3 +1,5 @@ +#include <stdarg.h> // TODO: implement stdarg by myself. + #include <libc.h> #include <draw.h> #include <console.h> @@ -67,6 +69,82 @@ cons_print(Console *con, char *s) return n; } +int +cons_printf(Console *con, char *fmt, ...) +{ + va_list ap; + char _buf[1024], *buf = _buf; + + char *s; + long long d, e; + unsigned long long f, g, h; + + va_start(ap, fmt); + for (;*fmt;) { + if (*fmt != '%') { + *buf++ = *fmt++; + continue; + } + fmt++; + switch (*fmt++) { + case '%': + *buf++ = '%'; + break; + case 's': + s = va_arg(ap, char *); + for (;*s;) { + *buf++ = *s++; + } + break; + case 'd': + d = va_arg(ap, int); + if (d == 0) { + *buf++ = '0'; + break; + } else if (d < 0) { + *buf++ = '-'; + d = -d; + } + for (e = 1; e <= d; e *= 10) { + if (e > e * 10) { // integer too big; + return -1; + } + } + for (e /= 10; e >= 1; e /= 10) { + *buf++ = '0' + ((d / e) % 10); + } + break; + case 'x': + f = va_arg(ap, unsigned int); + if (f == 0) { + *buf++ = '0'; + break; + } + for (g = 1; g <= f; g *= 0x10) { + if (g > g * 0x10) { // integer too big. + return -1; + } + } + for (g /= 0x10; g >= 1; g /= 0x10) { + h = ((f / g) % 0x10); + if (h < 0xa) { + *buf++ = '0' + h; + } else { + *buf++ = 'a' + h - 0xa; + } + } + break; + } + } + va_end(ap); + *buf = '\0'; + + cons_print(con, _buf); + + return (int) (buf - _buf); + +} + Console console = { &root_window, &asciifont, diff --git a/sys/src/kernel/main.c b/sys/src/kernel/main.c @@ -12,6 +12,7 @@ kernel_main(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) gop->Mode->Info->VerticalResolution, gop->Mode->Info->PixelsPerScanLine ); - cons_print(&console, "Hello, World!\nNew Line.\tTab\tTab\rnEW\vVertical"); + cons_print(&console, "Hello, World!\nNew Line.\tTab\tTab\rnEW\vVertical\n"); + cons_printf(&console, "digit: %d, str: %s, hex: 0x%x\n", 124, "abc", 0xdeadbeef); for(;;); -} -\ No newline at end of file +}