ref: 377da78d28bcd0dcc90d963719eb6297ceeed13f
parent: bb4b8654acda0d7ec184206cf0ed186d6625ba6e
author: mkf <mkf@cloud9p.org>
date: Wed Nov 22 05:52:49 EST 2023
a few (gazillions) of changes cons, pccons, bitcons: disable at compile time, too buggy to be of any use, Makefile: make ld quiet about executable stack, Makefile: add cmd/, Makefile: add strcntok, strccnt, cmd/echo: import a basic echo, cmd/echo: add a bitmapped font option, cmd/rc: add a basic shell, include/u.h: add prog_t, used by rc.h, include/libc.h, include/u.h: add some stdarg macros and va_list, libc/lldel.c: free(!) deleted values, libc/lladd: fixed a memory leak, libc/strccnt.c: import (returns how many times a character have been found on a string), libc/strcntok.c: import (returns nth time of token happening in src, kinda like strtok, but without states), libc/strlen.c: small changes, pc/com.c: delete com_getl(), pc/boot.s: bump stack size to 32kb, pc/kern.c get rid of (s)hell(-ish) codes, it now lives in cmd/rc, pc/mem.c: fix a small mistake, pc/vga.c: style updates, include/cons.h: tidy up, that's all.
--- a/Makefile
+++ b/Makefile
@@ -7,19 +7,25 @@
CFLAGS +=-O0 -g -nostdinc -I./include/ -ffreestanding -fcommon -fno-pie
ASFLAGS += -g
-LDFLAGS += -T linker.ld
+LDFLAGS += -T linker.ld -z noexecstack
QEMU ?= qemu-system-i386
QFLAGS +=-machine accel=kvm:tcg -m 2M -serial stdio -kernel teppich.elf
+C = \
+ cmd/rc.o\
+ cmd/echo.o\
+
L = \
libc/strlen.o\
libc/strcmp.o\
+ libc/strcntok.o\
+ libc/strccnt.o\
libc/memcpy.o\
libc/memset.o\
- libc/lladd.o \
+ libc/lladd.o\
libc/lldel.o\
-
+
K = \
pc/boot.o\
pc/x86.o\
@@ -28,9 +34,9 @@
pc/ps2.o\
pc/com.o\
pc/mem.o\
- pc/cons.o\
pc/bitmap.o\
- ${L}
+ ${L}\
+ ${C}\
all: teppich.elf
--- /dev/null
+++ b/cmd/echo.c
@@ -1,0 +1,29 @@
+#include <u.h>
+#include <libc.h>
+
+#include <vga.h>
+#include <bitmap.h>
+
+void
+echo_main(int argc, char **argv)
+{
+ int i;
+ void (*puts)(char*);
+
+ puts = vga_puts;
+ i = 1;
+ if(argc >= 1 && !strcmp(argv[1], "-b"))
+ {
+ puts = bitputs;
+ i = 2;
+ }
+
+ while(i < argc)
+ {
+ puts(argv[i]);
+ puts(" ");
+ i++;
+ }
+
+ vga_putc('\n');
+}
--- /dev/null
+++ b/cmd/rc.c
@@ -1,0 +1,86 @@
+#include <u.h>
+#include <libc.h>
+
+#include <ps2.h>
+#include <vga.h>
+
+#include <mem.h>
+#include <err.h>
+#include "rc.h"
+
+int
+run(char *cmd)
+{
+ int argc;
+ char *arg0, **argv;
+
+ /* always always always
+ check for nil pointers */
+
+ arg0 = strcntok(cmd, ' ', 0);
+
+ if(!arg0)
+ {
+ arg0 = cmd;
+ argc = 0;
+ }
+ else
+ {
+ for(argc = 0 ; argc < (strccnt(cmd, ' ') + 1) ; argc++)
+ {
+ argv[argc] = strcntok(cmd, ' ', argc);
+ }
+ }
+ for(int i = 0 ; i < sizeof(cmdtbl) ; i++)
+ {
+ if(!strcmp(arg0, cmdtbl[i].name))
+ return cmdtbl[i].main(argc, argv);
+ }
+ vga_puts("No such command\n");
+
+ return NO_SUCH_CMD;
+}
+
+void
+rc_main(void)
+{
+ char c;
+ char *cmd;
+
+ int i = 0;
+ memset(cmd, 0, 25);
+
+ vga_puts("> ");
+ while(1)
+ {
+ c = ps2_getc();
+ vga_putc(c);
+
+ if(c == '\r' || c == '\n')
+ {
+ cmd[i] = '\0';
+ run(cmd);
+
+ /* clear the mess */
+ cmd = malloc(25);
+ i = 0;
+
+ vga_puts("> ");
+ }
+ /* ignore spaces as first character and ignore more than one space */
+ else if((c == ' ') && (i == 0 || cmd[i - 1] == ' '))
+ continue;
+ else if(c != '\b')
+ {
+ cmd[i] = c;
+ i++;
+ }
+ else
+ {
+ /* we don't want a negative i */
+ if(i)
+ i--;
+ cmd[i] = 0;
+ }
+ }
+}
--- /dev/null
+++ b/cmd/rc.h
@@ -1,0 +1,9 @@
+#pragma once
+
+int echo_main(int argc, char **argv);
+void rc_main(void);
+
+static prog_t cmdtbl[] =
+{
+ {"echo", echo_main},
+};
--- a/include/cons.h
+++ b/include/cons.h
@@ -11,9 +11,9 @@
void (*scroll)(int lines);
}consdev_t;
-void consinit(consdev_t);
-void consclear(consdev_t, char);
-void conswrite(consdev_t cons, char* s);
-void consputc(consdev_t, char c);
+void consinit(consdev_t cons);
+void consclear(consdev_t cons, char c);
+void conswrite(consdev_t cons, char *s);
+void consputc(consdev_t cons, char c);
char consread(consdev_t cons);
-void consscroll(consdev_t, int lines);
+void consscroll(consdev_t cons, int lines);
--- a/include/libc.h
+++ b/include/libc.h
@@ -1,8 +1,18 @@
#pragma once
+#define va_start(ap, param) __builtin_va_start(ap, param)
+#define va_end(ap) __builtin_va_end(ap)
+#define va_arg(ap, type) __builtin_va_arg(ap, type)
+
int strlen(char *s);
int strcmp(char *s1, char *s2);
+char* strtok(char *s, char *b);
+char* strcntok(char *src, char token, int n);
+int strccnt(char *s, char c);
+
void* memset(void* src, char c, unsigned int len);
void* memcpy(void *a1, void *a2, unsigned int len);
+
int lladd(ll_t*, void*);
int lldel(ll_t*);
+
--- a/include/u.h
+++ b/include/u.h
@@ -12,8 +12,15 @@
typedef unsigned long uint32;
typedef long int32;
+typedef char* va_list;
typedef struct
{
void *val;
void *next;
}ll_t;
+
+typedef struct
+{
+ char *name;
+ int (*main)(int argc, char **argv);
+}prog_t;
--- a/libc/lladd.c
+++ b/libc/lladd.c
@@ -5,7 +5,7 @@
int
lladd(ll_t *last, void *data)
{
- ll_t *temp = malloc(sizeof(ll_t*));
+ ll_t *temp;
temp->val = data;
temp->next = nil;
@@ -13,6 +13,8 @@
if(last->next != nil)
return LL_ERR;
+ temp = malloc(sizeof(ll_t*));
+
last->next = temp;
return OK;
}
--- a/libc/lldel.c
+++ b/libc/lldel.c
@@ -1,12 +1,16 @@
+#include <u.h>
+#include <err.h>
+#include <mem.h>
+
/* deletes the next entry in the list */
int
lldel(ll_t *ll)
{
ll_t *temp = ll->next;
- if(ll->next != nil)
- return LL_ERR;
- ll->next = ll->next->next;
+ ll->next = temp->next;
+
+ free(temp->val);
free(temp);
return OK;
}
--- /dev/null
+++ b/libc/strccnt.c
@@ -1,0 +1,18 @@
+#include <u.h>
+#include <libc.h>
+
+int
+strccnt(char *s, char c)
+{
+ int i, t;
+
+ i = 0;
+ t = 0;
+ while(i < strlen(s))
+ {
+ if(s[i] == c)
+ t++;
+ i++;
+ }
+ return t;
+}
--- /dev/null
+++ b/libc/strcntok.c
@@ -1,0 +1,42 @@
+#include <u.h>
+#include <libc.h>
+
+#include <mem.h>
+
+char*
+strcntok(char *src, char token, int n)
+{
+ int i, b, match, lastmatch, lastnotmatch;
+ char *res;
+
+ match = -1; /* n = 0, match++ = 0 */
+ lastmatch = 0;
+ i = 0;
+ while(i < strlen(src))
+ {
+ if(src[i] == token)
+ {
+ match++;
+ if(match == n)
+ {
+ res = malloc(i + 1 - lastmatch); /* i - lastmatch + '\0' */
+ /* TODO: use strncpy */
+ memcpy(res, src + lastmatch, i - lastmatch);
+ res[i - lastmatch] = '\0';
+ return res;
+ }
+
+ lastmatch = i+1;
+ }
+ i++;
+ }
+
+ /* last instance would return anything left */
+ if(n == match + 1)
+ {
+ res = malloc(i - lastmatch);
+ memcpy(res, src + lastmatch, i - lastmatch);
+ return res;
+ }
+ return nil;
+}
--- a/libc/strlen.c
+++ b/libc/strlen.c
@@ -1,8 +1,8 @@
-int
+unsigned int
strlen(char *s)
{
int i = 0;
- while(s[i])
+ while(s[i] != '\0')
i++;
return i;
-}
\ No newline at end of file
+}
--- a/pc/boot.s
+++ b/pc/boot.s
@@ -33,7 +33,7 @@
.section .bss
.align 16
stack_bottom:
-.skip 16384 # 16 KiB
+.skip 32768 # 32 KiB
stack_top:
.section .text
--- a/pc/com.c
+++ b/pc/com.c
@@ -77,17 +77,4 @@
com_getc(void)
{
return com_getchar(COM1);
-}
-
-char*
-com_getl(void)
-{
- char *cmd, c;
- int i = 0;
- /* might c be '\n'? unlikely */
- while(c != '\n')
- {
- cmd[i] = c;
- }
- return cmd;
}
\ No newline at end of file
--- a/pc/kern.c
+++ b/pc/kern.c
@@ -3,88 +3,27 @@
#include <mem.h>
#include <cons.h>
#include <pccons.h>
-#include <bitcons.h>
+#include "../cmd/rc.h"
+#include <vga.h>
+#include <ps2.h>
+
+
/* abandon hope, all ye who enter here */
void
panic(void)
{
- conswrite(pccons, "panic: give up. it's over.\n");
+ vga_puts("panic: give up. it's over.\n");
}
-int
-run(char* cmd)
-{
- /* replace it with a proper table */
- if(!strcmp(cmd, "clear"))
- {
- consclear(pccons, ' ');
- }
- else if(!strcmp(cmd, "hello"))
- {
- conswrite(pccons, "hi");
- }
- else if(!strcmp(cmd, "reboot"))
- return 0;
- else
- {
- conswrite(pccons, "no such command");
- }
-
- conswrite(pccons, "\n");
- conswrite(pccons, "> ");
- return 1;
-
-}
-
void
-repl(void)
-{
- char c;
- char *cmd;
-
- int i = 0;
- memset(cmd, 0, 16);
- conswrite(pccons, "> ");
- while(1)
- {
-
- c = consread(pccons);
-
- consputc(pccons, c);
-
- if(c == '\r' || c == '\n')
- {
- if(!run(cmd))
- return;
-
- /* clear the mess */
- cmd = malloc(16);
- i = 0;
- }
- else if(c != '\b')
- {
- *(cmd+i) = c;
- i++;
- }
- else
- {
- /* we don't want a negative i */
- if(i)
- i--;
- *(cmd+i) = 0;
-
- }
- }
-}
-
-void
kernel_main(void)
{
+ /* set up memory map */
memset(memap, FREE, MEM_MAX * (1024 / BLOCKSIZE));
- consinit(pccons);
- conswrite(bitcons, "Teppich");
+ vga_init();
+ vga_puts("Teppich\n");
- repl();
+ rc_main();
}
--- a/pc/mem.c
+++ b/pc/mem.c
@@ -5,7 +5,6 @@
/* does first fit, returns index of that part of memory in memap */
int
-
_malloc(uint16 size)
{
int i, j;
@@ -25,7 +24,7 @@
{
/* we are done here, give address */
- for(int j = i ; j > i - size; j--)
+ for(j = i ; j > i - size; j--)
memap[j] = TAKEN;
return i - size;
}
--- a/pc/vga.c
+++ b/pc/vga.c
@@ -128,7 +128,9 @@
void
vga_puts(char *s)
{
- int len = strlen(s);
+ int len;
+
+ len = strlen(s);
for(int i = 0 ; i < len ; i++)
vga_putc(s[i]);
}