commit 568231651d1ad8aecb0274157b4813ea7b445df1
parent 86dac8fe036182531cf5d7a26e618976c22f8d3e
Author: Matsuda Kenji <info@mtkn.jp>
Date: Tue, 2 Apr 2024 15:53:48 +0900
add cons_printf
Diffstat:
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
+}