]> git.mdlowis.com Git - proto/uefi.git/commitdiff
fixed scrolling logic
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 23 Sep 2021 01:23:43 +0000 (21:23 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 23 Sep 2021 01:23:43 +0000 (21:23 -0400)
1  2 
Makefile
core/kernel.h
core/main.c
core/term.c
uefi/crt_x86_64.c
uefi/platform.h

diff --cc Makefile
index 7692f86ffef070d2083e13ecaff6d2332f8a1d77,c05f02e124c67fdeec045dae7cf90646d5a01acc..0c2734e8f77ab4786cbe81e28f3c3db9a7e4a68f
+++ b/Makefile
@@@ -1,12 -1,48 +1,50 @@@
- TARGET = kernel.efi
+ ARCH = x86_64
+ EFIARCH = efi-app-$(ARCH)
+ TARGET = BOOTX64.EFI
 +OVMF = /usr/share/qemu/OVMF.fd
- #OVMF = /usr/share/edk2-ovmf/OVMF_CODE.fd
 +
- include uefi/Makefile
+ CC = gcc
+ LD = ld
+ OBJCOPY = objcopy
+ AR = ar
+ CFLAGS = \
+     -fshort-wchar \
+     -fno-strict-aliasing \
+     -ffreestanding \
+     -fno-stack-protector \
+     -fno-stack-check \
+     -mno-red-zone \
+     -maccumulate-outgoing-args \
+     -Wno-builtin-declaration-mismatch \
+     -fpic \
+     -fPIC
+ CPPFLAGS = \
+     -I./core/ \
+     -I./uefi \
+     -I/usr/include \
+     -D__$(ARCH)__ \
+     -DHAVE_USE_MS_ABI
+ LDFLAGS = \
+     -nostdlib \
+     -shared \
+     -Bsymbolic \
+     -Luefi
+ LIBS = \
+     -o $(TARGET).so \
+     -T uefi/elf_$(ARCH)_efi.lds
  
- .PHONY: all run clean
+ # get source files, generate object names
+ SRCS = $(wildcard core/*.c uefi/*.c)
+ OBJS = $(SRCS:.c=.o)
  
- all: boot.img
+ .PHONY: all clean run
+ all: $(TARGET)
  
  clean:
        find -name '*.o' -delete
diff --cc core/kernel.h
index 8363ca7f685fbd157ef5b358d57d195ee4ea63a7,c390b6b5dd52cf7266aeafa36782efd01b3bce44..98f5c62d2bee53d4bbfa8c3f56663a5538b8f883
@@@ -2,21 -5,17 +5,15 @@@
  #define FONT_HEIGHT 16
  extern uint8_t Font[];
  
- struct Video {
-     uint32_t* buffer;
-     uint32_t stride;
- };
- extern struct Video Video;
- void Video_Init(void);
--void Video_PutGlyph(int x, int y, char c);
--
  static inline void Video_PutPixel(int x, int y, uint32_t pixel)
  {
 -    int offset = (sizeof(pixel) * Video.stride * y) + (sizeof(pixel) * x);
 -    *(Video.buffer + offset) = pixel;
 +    Video.buffer[Video.stride * y + x] = pixel;
  }
  
+ /*
+     Terminal/Console Driver
+ */
++void Term_Init(void);
  void Term_Clear(void);
  void Term_PutChar(int c);
  void Term_PutString(char* s);
diff --cc core/main.c
index 0000000000000000000000000000000000000000,39c0e664a6f5dc3c90b6156ed49fe0fb1d4f8417..6a792135b80c3a9c374214c716356960967c3cea
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,13 +1,20 @@@
 -//        BS->Stall(1000000);
+ #include <platform.h>
++#include <kernel.h>
+ int main (int argc, char** argv)
+ {
++    Term_Init();
+     /* loop forever */
+     for (;;)
+     {
++        Term_PutString("foo\n");
++        sleep(250);
++        Term_PutString("bar\n");
++        sleep(250);
++        Term_PutString("baz\n");
++        sleep(250);
+     }
+     return 0;
+ }
diff --cc core/term.c
index 4132341b5b32c98d08b49f558d5406ed7acff84a,e08ca70667bd6a7211caf5664be49e5bd788cb63..0619e240943a01c4821e89419560d56a02bff0dd
--- 1/term.c
@@@ -1,11 -1,29 +1,85 @@@
- #include <uefi.h>
+ #include <platform.h>
+ #include <kernel.h>
++#define MAX_COLS 240
++#define MAX_ROWS 75
 +
  static char* Digits = "0123456789abcdef";
  
 -                (x * FONT_WIDTH) + col,
 -                (y * FONT_HEIGHT) + row,
++struct {
++    int cols;
++    int rows;
++    int cursor;
++    char cells[MAX_ROWS * MAX_COLS];
++} Term = { 0 };
++
+ static void PutGlyph(int x, int y, char c)
+ {
+     char* glyph = &Font[c * FONT_HEIGHT];
+     for (int row = 0; row < 16; row++)
+     {
+         char piece = glyph[row];
+         for (int col = 0; col < 8; col++, piece <<= 1)
+         {
+             Video_PutPixel(
++                x + col,
++                y + row,
+                 (piece & 0x80) ? 0xFFFFFFFF : 0x00000000);
+         }
+     }
+ }
++static void PutCell(int c)
++{
++    int max = Term.rows * Term.cols;
++    /* check if we need to scroll and do it */
++    if (Term.cursor >= max)
++    {
++        int dst = 0;
++        int src = Term.cols;
++        Term.cursor = (Term.rows - 1) * Term.cols;
++        while (src < max)
++        {
++            PutGlyph((dst % Term.cols) * 8, (dst / Term.rows) * 16, Term.cells[src]);
++            Term.cells[dst++] = Term.cells[src++];
++        }
++        for (int i = Term.cursor; i < Term.cols; i++)
++        {
++            PutGlyph((i % Term.cols) * 8, (i / Term.rows) * 16, ' ');
++            Term.cells[i] = ' ';
++        }
++    }
++    /* now place the new glyph */
++    Term.cells[Term.cursor] = c;
++    int row = (Term.cursor / Term.cols);
++    int col = (Term.cursor % Term.cols);
++    PutGlyph(col * 8, row * 16, c);
++    Term.cursor++;
++}
++
++void Term_Init(void)
++{
++    Term.cols = min(Video.width / FONT_WIDTH, MAX_COLS);
++    Term.rows = min(Video.height / FONT_HEIGHT, MAX_ROWS);
++}
  void Term_PutChar(int c)
  {
-     wchar_t tmp[2] =  { (wchar_t)c, 0 };
-     ST->ConOut->OutputString(ST->ConOut, (c == '\n' ? (wchar_t*)L"\r\n" : tmp));
 -//    wchar_t tmp[2] =  { (wchar_t)c, 0 };
 -//    ST->ConOut->OutputString(ST->ConOut, (c == '\n' ? (wchar_t*)L"\r\n" : tmp));
++    switch (c)
++    {
++        case '\r':
++            Term.cursor = (Term.cursor / Term.cols) * Term.cols;
++            break;
++
++        case '\n':
++            Term.cursor = (Term.cursor / Term.cols) * Term.cols;
++            Term.cursor += Term.cols;
++            break;
++
++        default:
++            PutCell(c);
++            break;
++    }
  }
  
  void Term_PutString(char* s)
index f7832f52cdf47e80a4900488bd80ae325affe5c3,253fd93c5fce1a5c23a75e5c8784e72a85960ab7..b5481f664941ce54daf6288756276940535bdbf1
@@@ -1,5 -1,57 +1,64 @@@
+ #include <platform.h>
+ #include <uefi.h>
+ /* this is implemented by the application */
+ extern int main(void);
+ /* globals to store system table pointers */
+ static efi_handle_t IM = NULL;
+ static efi_system_table_t *ST = NULL;
+ static efi_boot_services_t *BS = NULL;
+ static efi_runtime_services_t *RT = NULL;
+ static efi_loaded_image_protocol_t *LIP = NULL;
+ /* platform specific globals */
+ VideoConfig Video = {0};
++void sleep(int ms)
++{
++    BS->Stall(ms * 1000);
++}
++
+ static void video_init(void)
+ {
+     /* get a handle to the graphics protocol */
+     efi_gop_t *gop = NULL;
+     efi_guid_t gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+     BS->LocateProtocol(&gopGuid, NULL, (void**)&gop);
+     /* query mode 0 to see if mode needs to be set first */
+     uintn_t info_size = 0;
+     efi_gop_mode_info_t *info = NULL;
+     uintn_t status = gop->QueryMode(gop, 0, &info_size, &info);
+     /* some machines need mode set explicitly first */
+     if (status == EFI_NOT_STARTED)
+     {
+         status = gop->SetMode(gop, 0);
+     }
+     /*
+         OK, now we have real info for possible modes, pick the max mode.
+         We assume this one is the best resolution.
+     */
+     if (status == EFI_SUCCESS)
+     {
+         status = gop->SetMode(gop, 17); /* pick a smaller resolution for QEMU */
+ //        status = gop->SetMode(gop, gop->Mode->MaxMode-1);
+     }
+     /*
+         Now let's save off the info we need to draw pixels and glyphs.
+         The code in this file assumes 32 bits per pixel.
+     */
+     Video.buffer = (uint32_t*)(gop->Mode->FrameBufferBase);
+     Video.stride = gop->Mode->Information->PixelsPerScanLine;
++    Video.width = gop->Mode->Information->HorizontalResolution;
++    Video.height = gop->Mode->Information->VerticalResolution;
+ }
  /*
-  * crt_x86_64.c
+  * crt_x86_64.c : bootstrap() and uefi_init()
   *
   * Copyright (C) 2021 bzt (bztsrc@gitlab)
   *
diff --cc uefi/platform.h
index 0000000000000000000000000000000000000000,538b27627cea75de307cc6c69dd05d3a082fb999..d282b0d52a9b2b2478cac3625ac0fb7130ae7cbe
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,32 +1,34 @@@
 -extern VideoConfig Video;
+ /* define standard type definitions */
+ typedef char                int8_t;
+ typedef unsigned char       uint8_t;
+ typedef short               int16_t;
+ typedef unsigned short      uint16_t;
+ typedef int                 int32_t;
+ typedef unsigned int        uint32_t;
+ typedef long long           int64_t;
+ typedef unsigned long long  uint64_t;
+ typedef long long           intptr_t;
+ typedef unsigned long long  uintptr_t;
+ /* sanity check type definitions */
+ extern char check_u16[sizeof(uint16_t) == 2  ? 1 : -1];
+ extern char check_u32[sizeof(uint32_t) == 4  ? 1 : -1];
+ extern char check_u64[sizeof(uint64_t) == 8  ? 1 : -1];
+ extern char check_uptr[sizeof(uintptr_t) == 8 ? 1 : -1];
+ #define NULL     ((void*)0)
+ #define abs(x)   ((x)<0?-(x):(x))
+ #define min(x,y) ((x)<(y)?(x):(y))
+ #define max(x,y) ((x)>(y)?(x):(y))
+ /* video memory configuration info */
+ typedef struct {
+     uint32_t* buffer;
+     uint32_t stride;
+     uint32_t width;
+     uint32_t height;
+ } VideoConfig;
++extern VideoConfig Video;
++
++void sleep(int ms);