commit 8dbccc7fa779d7c4f57ef9734d464708b4735040
parent b4ea08671081416e15e8acd9021f43b5cfff63ee
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 3 Apr 2024 15:01:27 +0900
modify makefile
Diffstat:
10 files changed, 139 insertions(+), 37 deletions(-)
diff --git a/sys/include/draw.h b/sys/include/draw.h
@@ -1,5 +1,9 @@
// #include <libc.h>
+// #include <uefi.h>
+// low 8 bits represent alpha, next low 8 bits represent blue,
+// the next 8bits green, and the last red.
+// red is 0xff000000, green: 0x00ff0000, blue: 0x0000ff00.
typedef unsigned int RGBA32;
typedef struct Window Window;
@@ -20,7 +24,7 @@ typedef struct Image {
} Image;
typedef struct Window {
- RGBA32 *fb;
+ uint32 *fb;
RGBA32 fg;
RGBA32 bg;
int hres;
@@ -30,6 +34,6 @@ typedef struct Window {
int nchildren;
} Window;
-error init_root_window(RGBA32 *fb_base, int hres, int vres, int ppsl);
-void pixel(Window *dst, Point p, RGBA32 col);
+int init_root_window(uint32 *fb_base, int hres, int vres, int ppsl, EFI_GRAPHICS_PIXEL_FORMAT pf);
+extern void (* pixel)(Window *dst, Point p, RGBA32 col);
void line(Window *dst, Point p0, Point p1, RGBA32 col);
\ No newline at end of file
diff --git a/sys/include/libc.h b/sys/include/libc.h
@@ -6,8 +6,14 @@ typedef unsigned long long int uint64;
typedef unsigned long long int uintptr;
typedef struct {
- char *ename;
-} *error;
+ char ename[1024];
+} error;
+
+extern error err;
+
+// Strcpy copies null terminated string s2 to s1 and returns s1.
+// Caller should allocate enough memory at s1.
+char *strcpy(char *s1, char *s2);
typedef struct Memblock {
void *start, *end;
diff --git a/sys/include/uefi.h b/sys/include/uefi.h
@@ -135,7 +135,7 @@ typedef struct {
UINT32 Version;
UINT32 HorizontalResolution;
UINT32 VerticalResolution;
- EFI_GRAPHICS_PIXEL_FORMAT PixelFromat; // This is not fixed in size.
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; // TODO: I think this is not fixed in size.
EFI_PIXEL_BITMASK PixelInformation;
UINT32 PixelsPerScanLine;
} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
diff --git a/sys/src/Makefile b/sys/src/Makefile
@@ -1,4 +1,4 @@
-TARGETS = boot kernel
+TARGETS = boot kernel libc
disk.img: targets
qemu-img create -f raw disk.img 200M
diff --git a/sys/src/kernel/Makefile b/sys/src/kernel/Makefile
@@ -4,14 +4,21 @@ CFLAGS = -I ../../include -nostdlib -fpic -mno-red-zone -Wall -g \
-ffreestanding -fno-builtin
LDFLAGS = -e kernel_main -static
OBJS = main.o draw.o alloc.o console.o
+LIBS = libc
+LIBOBJ = ../libc/libc.o
all: main.elf
-main.elf: $(OBJS) memmap.ld
- $(LD) $(LDFLAGS) -T memmap.ld -o $@ $(OBJS)
+main.elf: $(OBJS) libs memmap.ld
+ $(LD) $(LDFLAGS) -T memmap.ld -o $@ $(OBJS) $(LIBOBJ)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
+libs:
+ for lib in $(LIBS); do \
+ cd ../$$lib && make; \
+ done
+
clean:
rm -f $(OBJS) main.elf
\ No newline at end of file
diff --git a/sys/src/kernel/console.c b/sys/src/kernel/console.c
@@ -1,6 +1,7 @@
#include <stdarg.h> // TODO: implement stdarg by myself.
#include <libc.h>
+#include <uefi.h>
#include <draw.h>
#include <console.h>
diff --git a/sys/src/kernel/draw.c b/sys/src/kernel/draw.c
@@ -1,11 +1,25 @@
#include <libc.h>
+#include <uefi.h>
#include <draw.h>
+#include <console.h>
Window root_window;
-error
-init_root_window(RGBA32 *fb_base, int hres, int vres, int ppsl)
+void (* pixel)(Window *dst, Point p, RGBA32 col);
+static void pixelRedGreenBlueReserved(Window *dst, Point p, RGBA32 col);
+static void pixelBlueGreenRedReserved(Window *dst, Point p, RGBA32 col);
+
+int
+init_root_window(uint32 *fb_base, int hres, int vres, int ppsl, EFI_GRAPHICS_PIXEL_FORMAT pf)
{
+ if (pf == PixelRedGreenBlueReserved8BitPerColor) {
+ pixel = pixelRedGreenBlueReserved;
+ } else if (pf == PixelBlueGreenRedReserved8BitPerColor) {
+ pixel = pixelBlueGreenRedReserved;
+ } else {
+ strcpy(err.ename, "pixel format not supported.");
+ return -1;
+ }
root_window.fb = fb_base;
root_window.fg = 0x0;
root_window.bg = 0xffffea;
@@ -14,40 +28,75 @@ init_root_window(RGBA32 *fb_base, int hres, int vres, int ppsl)
root_window.ppsl = ppsl;
root_window.children = NULL;
root_window.nchildren = 0;
- return NULL;
+ return 0;
}
-void
-pixel(Window *dst, Point p, RGBA32 col)
+static void
+pixelRedGreenBlueReserved(Window *dst, Point p, RGBA32 col)
+{
+ // TODO: alpha
+ // TODO: this order is correct?
+ // UEFI-SPEC says that R is at the "byte zero".
+ uint32 _col =
+ (col & 0xff000000) >> 24 | // R
+ (col & 0x00ff0000) >> 8 | // G
+ (col & 0x0000ff00) << 8 | // B
+ (col & 0x000000ff) << 24; // A
+ if (0 <= p.x && p.x < dst->hres && 0 <= p.y && p.y < dst->vres) {
+ dst->fb[p.y * dst->ppsl + p.x] = _col;
+ }
+}
+
+static void
+pixelBlueGreenRedReserved(Window *dst, Point p, RGBA32 col)
{
+ // TODO: alpha
+ uint32 _col =
+ (col & 0xff000000) >> 8 | // R
+ (col & 0x00ff0000) >> 8 | // G
+ (col & 0x0000ff00) >> 8 | // B
+ (col & 0x000000ff) << 24; // A
if (0 <= p.x && p.x < dst->hres && 0 <= p.y && p.y < dst->vres) {
- dst->fb[p.y * dst->ppsl + p.x] = col;
+ dst->fb[p.y * dst->ppsl + p.x] = _col;
}
}
void
line(Window *dst, Point p0, Point p1, RGBA32 col)
{
- // TODO: wip. I need debug print.
- int x, y;
- int dx = p1.x - p0.x;
- int dy = p1.y - p0.y;
- float err = 0;
- float derr = (float)dy / (float)dx;
- if (derr < 0) {
- derr = -derr;
+ int x, y, sx, sy, dx, dy;
+ int err, e2;
+ if (p0.x < p1.x) {
+ dx = p1.x - p0.x;
+ sx = 1;
+ } else {
+ dx = p0.x - p1.x;
+ sx = -1;
}
+ if (p0.y < p1.y) {
+ dy = p1.y - p0.y;
+ sy = 1;
+ } else {
+ dy = p0.y - p1.y;
+ sy = -1;
+ }
+ err = dx - dy;
x = p0.x;
- y = (x - p0.x) * (p1.y - p0.y) / (p1.x - p0.x) + p0.y;
- for (; x < p1.x; x++) {
- err += derr;
- if (err > 0.5) {
- y++;
- err -= 1.0;
+ y = p0.y;
+ pixel(dst, (Point){x, y}, col);
+ for (;x != p1.x || y != p1.y;) {
+ e2 = 2 * err;
+ if (e2 > -dy) {
+ err -= dy;
+ x += sx;
+ }
+ if (e2 < dx) {
+ err +=dx;
+ y += sy;
}
- if (y < 0 || dst->vres <= y) {
- continue; // TODO: break if the rest is outside the window.
+ if (x <= 0 || dst->hres < x || y <= 0 || dst->vres < y) {
+ continue; // TODO: break
}
- dst->fb[y * dst->ppsl + x] = col; // TODO: alpha
+ pixel(dst, (Point){x, y}, col);
}
}
\ No newline at end of file
diff --git a/sys/src/kernel/main.c b/sys/src/kernel/main.c
@@ -3,16 +3,27 @@
#include <draw.h>
#include <console.h>
+error err;
+
void
kernel_main(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop)
{
- init_root_window(
- (RGBA32 *)gop->Mode->FrameBufferBase,
+ if (init_root_window(
+ (uint32 *)gop->Mode->FrameBufferBase,
gop->Mode->Info->HorizontalResolution,
gop->Mode->Info->VerticalResolution,
- gop->Mode->Info->PixelsPerScanLine
- );
+ gop->Mode->Info->PixelsPerScanLine,
+ gop->Mode->Info->PixelFormat
+ ) < 0) {
+ // can't print to console.
+ goto halt;
+ }
line(&root_window, (Point){1000, 100}, (Point){1050, 140}, 0x000000);
-
+ line(&root_window, (Point){1000, 300}, (Point){100000, 100000}, 0x000000);
+ line(&root_window, (Point){1000, 400}, (Point){1100, 400}, 0xff000000);
+ line(&root_window, (Point){1000, 500}, (Point){1100, 500}, 0x00ff0000);
+ line(&root_window, (Point){1000, 600}, (Point){1100, 600}, 0x0000ff00);
+ line(&root_window, (Point){1000, 700}, (Point){1100, 700}, 0x000000ff);
+halt:
for(;;);
}
diff --git a/sys/src/libc/Makefile b/sys/src/libc/Makefile
@@ -0,0 +1,12 @@
+CC = gcc
+CFLAGS = -I ../../include -nostdlib -fpic -mno-red-zone -Wall -g \
+ -ffreestanding -fno-builtin
+SRC = strcpy.c
+
+all: libc.o
+
+libc.o: $(SRC)
+ $(CC) $(CFLAGS) -c -o $@ $(SRC)
+
+clean:
+ rm -f libc.o
diff --git a/sys/src/libc/strcpy.c b/sys/src/libc/strcpy.c
@@ -0,0 +1,11 @@
+#include <libc.h>
+
+char *
+strcpy(char *s1, char *s2)
+{
+ char *s = s1;
+ for (;*s2;) {
+ *s1++ = *s2++;
+ }
+ return s;
+}
+\ No newline at end of file