[Add] laos base boot
This commit is contained in:
21
laos/src/dev/Makefile
Normal file
21
laos/src/dev/Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
CURNAME := dev
|
||||
BUILD_DIR := $(TOP_BUILD_DIR)/$(CURNAME)
|
||||
|
||||
CSRC := $(wildcard *.c)
|
||||
OBJS := $(patsubst %.c,%.o,$(CSRC))
|
||||
BUILD_OBJS := $(addprefix $(BUILD_DIR)/,$(OBJS))
|
||||
|
||||
.PHONY: build all message
|
||||
|
||||
all: message build
|
||||
|
||||
$(BUILD_DIR):
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(BUILD_OBJS): $(BUILD_DIR)/%.o:%.c $(BUILD_DIR)
|
||||
@$(CC) -c -o $@ $< $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
build: $(BUILD_OBJS)
|
||||
|
||||
message:
|
||||
@echo "building $(CURNAME)"
|
||||
31
laos/src/dev/serial.c
Normal file
31
laos/src/dev/serial.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "memlayout.h"
|
||||
#include "latype.h"
|
||||
#include "memio.h"
|
||||
#include "defs.h"
|
||||
|
||||
struct spinlock serial_tx_lock;
|
||||
char serial_tx_buf[SERIAL_TX_BUF_SIZE];
|
||||
|
||||
u32 serial_tx_w; // write next to serial_tx_buf[serial_tx_w % SERIAL_TX_BUF_SIZE]
|
||||
u32 serial_tx_r; // read next from serial_tx_buf[serial_tx_r % SERIAL_TX_BUF_SIZE]
|
||||
|
||||
|
||||
|
||||
void serial_putc(int c) {
|
||||
acquire(&serial_tx_lock);
|
||||
|
||||
// if(panicked){
|
||||
// for(;;)
|
||||
// ;
|
||||
// }
|
||||
|
||||
while(serial_tx_w == serial_tx_r + SERIAL_TX_BUF_SIZE){
|
||||
// buffer is full.
|
||||
// wait for serialstart() to open up space in the buffer.
|
||||
// sleep(&serial_tx_r, &serial_tx_lock);
|
||||
}
|
||||
serial_tx_buf[serial_tx_w % SERIAL_TX_BUF_SIZE] = c;
|
||||
serial_tx_w += 1;
|
||||
// serialstart();
|
||||
release(&serial_tx_lock);
|
||||
}
|
||||
28
laos/src/kernel/console.c
Normal file
28
laos/src/kernel/console.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "console.h"
|
||||
#include "memio.h"
|
||||
#include "memlayout.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
void consputc(int c) {
|
||||
if (c == '\b') {
|
||||
memb(SERIAL_ADDR) = '\b';
|
||||
memb(SERIAL_ADDR) = ' ';
|
||||
memb(SERIAL_ADDR) = '\b';
|
||||
return;
|
||||
}
|
||||
|
||||
memb(SERIAL_ADDR) = c;
|
||||
}
|
||||
|
||||
struct {
|
||||
struct spinlock lock;
|
||||
|
||||
// input
|
||||
#define INPUT_BUF_SIZE 128
|
||||
char buf[INPUT_BUF_SIZE];
|
||||
uint r; // Read index
|
||||
uint w; // Write index
|
||||
uint e; // Edit index
|
||||
} cons;
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ _entry:
|
||||
# with a 4096-byte stack per CPU.
|
||||
# sp = stack0 + (hartid * 4096)
|
||||
la.global $sp, stack0
|
||||
lu12i.w $a0, (1024*4 >> 12) & 0xfffff
|
||||
addi.w $a0, $a0, 1024*4 & 0xfff
|
||||
csrrd $a1, CPUID
|
||||
addi.w $a1, $a1, 1
|
||||
mul.w $a0, $a0, $a1
|
||||
add.w $sp, $sp, $a0
|
||||
lu12i.w $a0, (1024*4 >> 12) & 0xfffff
|
||||
addi.w $a0, $a0, 1024*4 & 0xfff
|
||||
csrrd $a1, CPUID
|
||||
addi.w $a1, $a1, 1
|
||||
mul.w $a0, $a0, $a1
|
||||
add.w $sp, $sp, $a0
|
||||
# jump to start() in start.c
|
||||
bl start
|
||||
bl start
|
||||
spin:
|
||||
b spin
|
||||
116
laos/src/kernel/kprintf.c
Normal file
116
laos/src/kernel/kprintf.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "latype.h"
|
||||
#include "console.h"
|
||||
#include "kprintf.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
volatile int panicked = 0;
|
||||
|
||||
// lock to avoid interleaving concurrent printf's.
|
||||
static struct {
|
||||
struct spinlock lock;
|
||||
int locking;
|
||||
} pr;
|
||||
|
||||
static char digits[] = "0123456789abcdef";
|
||||
|
||||
static void print_int(int xx, int base, int sign) {
|
||||
char buf[32];
|
||||
int i;
|
||||
uint x;
|
||||
if (sign && (sign = xx < 0)) {
|
||||
x = -xx;
|
||||
} else {
|
||||
x = xx;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
buf[i++] = digits[x % base];
|
||||
} while ((x /= base) != 0);
|
||||
|
||||
if(sign) {
|
||||
buf[i++] = '-';
|
||||
}
|
||||
|
||||
while(--i >= 0)
|
||||
consputc(buf[i]);
|
||||
}
|
||||
|
||||
static void print_ptr(intptr_t x) {
|
||||
consputc('0');
|
||||
consputc('x');
|
||||
for (int i = 0; i < (sizeof(intptr_t) * 2); i++, x <<= 4)
|
||||
consputc(digits[x >> (sizeof(intptr_t) * 8 - 4)]);
|
||||
}
|
||||
|
||||
void kprintf(char *fmt, ...) {
|
||||
va_list ap;
|
||||
int i, c, locking;
|
||||
char *s;
|
||||
|
||||
locking = pr.locking;
|
||||
if(locking)
|
||||
acquire(&pr.lock);
|
||||
|
||||
if (fmt == 0)
|
||||
panic("null fmt");
|
||||
|
||||
va_start(ap, fmt);
|
||||
for (i = 0; (c = fmt[i] & 0xff) != 0; i++) {
|
||||
if (c != '%') {
|
||||
consputc(c);
|
||||
continue;
|
||||
}
|
||||
c = fmt[++i] & 0xff;
|
||||
if (c == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'd':
|
||||
print_int(va_arg(ap, int), 10, 1);
|
||||
break;
|
||||
case 'x':
|
||||
print_int(va_arg(ap, int), 16, 1);
|
||||
break;
|
||||
case 'p':
|
||||
print_ptr(va_arg(ap, intptr_t));
|
||||
break;
|
||||
case 's':
|
||||
if((s = va_arg(ap, char*)) == 0)
|
||||
s = "(null)";
|
||||
for(; *s; s++)
|
||||
consputc(*s);
|
||||
break;
|
||||
case '%':
|
||||
consputc('%');
|
||||
break;
|
||||
default:
|
||||
// Print unknown % sequence to draw attention.
|
||||
consputc('%');
|
||||
consputc(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
if(locking)
|
||||
release(&pr.lock);
|
||||
}
|
||||
|
||||
void panic(char *s) {
|
||||
pr.locking = 0;
|
||||
kprintf("panic: ");
|
||||
kprintf(s);
|
||||
kprintf("\n");
|
||||
panicked = 1; // freeze serial output from other CPUs
|
||||
for(;;)
|
||||
;
|
||||
}
|
||||
|
||||
void kprintf_init(void) {
|
||||
initlock(&pr.lock, "pr");
|
||||
pr.locking = 1;
|
||||
}
|
||||
@@ -1,3 +1,25 @@
|
||||
#include "la32r.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
|
||||
volatile static int started = 0;
|
||||
|
||||
void main() {
|
||||
struct spinlock lck[1];
|
||||
initlock(lck, "main");
|
||||
acquire(lck);
|
||||
|
||||
if (r_cpuid() == 0) {
|
||||
|
||||
|
||||
synchronize();
|
||||
started = 1;
|
||||
} else {
|
||||
// 当前假定只有一个 hart
|
||||
while (started == 0)
|
||||
;
|
||||
synchronize();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
24
laos/src/kernel/proc.c
Normal file
24
laos/src/kernel/proc.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "proc.h"
|
||||
#include "la32r.h"
|
||||
#include "latype.h"
|
||||
|
||||
struct cpu cpus[NCPU];
|
||||
|
||||
struct proc proc[NPROC];
|
||||
|
||||
struct proc *initproc;
|
||||
|
||||
int nextpid = 1;
|
||||
struct spinlock pid_lock;
|
||||
|
||||
// helps ensure that wakeups of wait()ing
|
||||
// parents are not lost. helps obey the
|
||||
// memory model when using p->parent.
|
||||
// must be acquired before any p->lock.
|
||||
struct spinlock wait_lock;
|
||||
|
||||
struct cpu *mycpu() {
|
||||
int id = r_cpuid();
|
||||
struct cpu *c = &cpus[id];
|
||||
return c;
|
||||
}
|
||||
54
laos/src/kernel/spinlock.c
Normal file
54
laos/src/kernel/spinlock.c
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "spinlock.h"
|
||||
#include "la32r.h"
|
||||
#include "defs.h"
|
||||
#include "kprintf.h"
|
||||
#include "proc.h"
|
||||
|
||||
void initlock(struct spinlock *lck, char *name) {
|
||||
lck->name = name;
|
||||
lck->locked = 0;
|
||||
lck->cpu = 0;
|
||||
}
|
||||
|
||||
void acquire(struct spinlock *lck) {
|
||||
|
||||
if(holding(lck)) {
|
||||
panic("acquire");
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
// 如果已经上锁了,就等待
|
||||
while (llw((intptr_t)&lck->locked) == 1)
|
||||
;
|
||||
// 此时没有上锁,那就开始抢锁
|
||||
// 没有抢成功就进入新的循环
|
||||
} while (scw(1, (intptr_t)&lck->locked) != 1);
|
||||
|
||||
synchronize();
|
||||
lck->cpu = mycpu();
|
||||
}
|
||||
|
||||
void release(struct spinlock *lck) {
|
||||
if (holding(lck) != 1) {
|
||||
panic("release");
|
||||
}
|
||||
|
||||
lck->cpu = NULL;
|
||||
|
||||
synchronize();
|
||||
|
||||
do {
|
||||
// 标记上
|
||||
llw((intptr_t)&lck->locked);
|
||||
|
||||
// 此时没有 hart 动,那就安全的释放
|
||||
// 否则重新循环
|
||||
} while (scw(0, (intptr_t)&lck->locked) != 1);
|
||||
}
|
||||
|
||||
int holding(struct spinlock *lck) {
|
||||
int r;
|
||||
r = (lck->locked && lck->cpu == mycpu());
|
||||
return r;
|
||||
}
|
||||
@@ -1,7 +1,20 @@
|
||||
#include "common.h"
|
||||
#include "kernel.h"
|
||||
#include "la32r.h"
|
||||
|
||||
__attribute__ ((aligned (16))) char stack0[4096 * NCPU];
|
||||
|
||||
void start() {
|
||||
// 设置特权等级
|
||||
volatile u32 crmd_info = r_crmd();
|
||||
crmd_info = crmd_info & 0xfffffffc;
|
||||
w_crmd(crmd_info);
|
||||
|
||||
// ERTN 返回地址
|
||||
w_eentry((intptr_t)main);
|
||||
|
||||
// 设置 tp
|
||||
int id = r_cpuid();
|
||||
w_tp(id);
|
||||
|
||||
asm volatile("ertn");
|
||||
}
|
||||
21
laos/src/lib/Makefile
Normal file
21
laos/src/lib/Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
CURNAME := lib
|
||||
BUILD_DIR := $(TOP_BUILD_DIR)/$(CURNAME)
|
||||
|
||||
CSRC := $(wildcard *.c)
|
||||
OBJS := $(patsubst %.c,%.o,$(CSRC))
|
||||
BUILD_OBJS := $(addprefix $(BUILD_DIR)/,$(OBJS))
|
||||
|
||||
.PHONY: build all message
|
||||
|
||||
all: message build
|
||||
|
||||
$(BUILD_DIR):
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(BUILD_OBJS): $(BUILD_DIR)/%.o:%.c $(BUILD_DIR)
|
||||
@$(CC) -c -o $@ $< $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
build: $(BUILD_OBJS)
|
||||
|
||||
message:
|
||||
@echo "building $(CURNAME)"
|
||||
0
laos/src/lib/path.c
Normal file
0
laos/src/lib/path.c
Normal file
29
laos/src/user/Makefile
Normal file
29
laos/src/user/Makefile
Normal file
@@ -0,0 +1,29 @@
|
||||
CURNAME := user
|
||||
BUILD_DIR := $(TOP_BUILD_DIR)/$(CURNAME)
|
||||
|
||||
CSRC := $(wildcard *.c)
|
||||
OBJS := $(patsubst %.c,%.o,$(CSRC))
|
||||
BUILD_OBJS := $(addprefix $(BUILD_DIR)/,$(OBJS))
|
||||
BASENAMES := $(basename $(CSRC))
|
||||
BUILD_EXE := $(addprefix $(BUILD_DIR)/,$(BASENAMES))
|
||||
|
||||
.PHONY: build all message
|
||||
|
||||
all: message build
|
||||
|
||||
$(BUILD_DIR):
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(BUILD_OBJS): $(BUILD_DIR)/%.o:%.c $(BUILD_DIR)
|
||||
@$(CC) -c -o $@ $< $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
$(BUILD_EXE): %:%.o
|
||||
@$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
build: $(BUILD_EXE)
|
||||
|
||||
message:
|
||||
@echo "building $(CURNAME)"
|
||||
|
||||
native: $(BUILD_EXE)
|
||||
@echo $(BASENAMES)
|
||||
16
laos/src/user/echo.c
Normal file
16
laos/src/user/echo.c
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
write(STDOUT_FILENO, argv[i], strlen(argv[i]));
|
||||
if(i + 1 < argc){
|
||||
write(STDOUT_FILENO, " ", 1);
|
||||
} else {
|
||||
write(STDOUT_FILENO, "\n", 1);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
0
laos/src/user/shell.c
Normal file
0
laos/src/user/shell.c
Normal file
49
laos/src/user/xargs.c
Normal file
49
laos/src/user/xargs.c
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
void remove_tail_newline(char *str, int len) {
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
if (str[len - 1] == '\n') {
|
||||
str[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 1) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char **args = malloc(argc * sizeof(char *));
|
||||
memcpy(args, &argv[1], (argc - 1) * sizeof(char *));
|
||||
argc -= 1;
|
||||
|
||||
const char *filename = argv[1];
|
||||
char input[128];
|
||||
read(STDIN_FILENO, input, 128);
|
||||
remove_tail_newline(input, strlen(input));
|
||||
|
||||
char *tok = strtok(input, " ");
|
||||
while (tok) {
|
||||
if (*tok != '\n') {
|
||||
args = realloc(args, (argc + 1) * sizeof(char *));
|
||||
args[argc] = tok;
|
||||
argc += 1;
|
||||
}
|
||||
tok = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
if (fork() == 0) {
|
||||
execvp(filename, args);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
wait(NULL);
|
||||
free(args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
#include <assert.h>
|
||||
93
laos/src/util/string.c
Normal file
93
laos/src/util/string.c
Normal file
@@ -0,0 +1,93 @@
|
||||
#include "string.h"
|
||||
#include "latype.h"
|
||||
|
||||
// mem ops could be more better
|
||||
// use loop unrolling
|
||||
|
||||
void *memset(void *dst, int c, uint n) {
|
||||
char *cdst = (char *) dst;
|
||||
for (uint i = 0; i < n; ++i) {
|
||||
cdst[i] = c;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
int memcmp(const void *m1, const void *m2, uint n) {
|
||||
const uchar *s1, *s2;
|
||||
|
||||
s1 = m1;
|
||||
s2 = m2;
|
||||
|
||||
while (n --> 0) {
|
||||
if(*s1 != *s2)
|
||||
return *s1 - *s2;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *memmove(void *dst, const void *src, uint n) {
|
||||
const char *s;
|
||||
char *d;
|
||||
|
||||
if(n == 0)
|
||||
return dst;
|
||||
|
||||
s = src;
|
||||
d = dst;
|
||||
if(s < d && s + n > d){
|
||||
s += n;
|
||||
d += n;
|
||||
while(n-- > 0)
|
||||
*--d = *--s;
|
||||
} else
|
||||
while(n-- > 0)
|
||||
*d++ = *s++;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memcpy(void *dst, const void *src, uint n) {
|
||||
return memmove(dst, src, n);
|
||||
}
|
||||
|
||||
int strncmp(const char *p, const char *q, uint n) {
|
||||
while(n > 0 && *p && *p == *q)
|
||||
n--, p++, q++;
|
||||
if(n == 0)
|
||||
return 0;
|
||||
return (uchar)*p - (uchar)*q;
|
||||
}
|
||||
|
||||
char *strncpy(char *s, const char *t, int n) {
|
||||
char *os;
|
||||
|
||||
os = s;
|
||||
while(n-- > 0 && (*s++ = *t++) != 0)
|
||||
;
|
||||
while(n-- > 0)
|
||||
*s++ = 0;
|
||||
return os;
|
||||
}
|
||||
|
||||
char *strcpy_s(char *s, const char *t, int n) {
|
||||
char *os;
|
||||
|
||||
os = s;
|
||||
if(n <= 0)
|
||||
return os;
|
||||
while(--n > 0 && (*s++ = *t++) != 0)
|
||||
;
|
||||
*s = 0;
|
||||
return os;
|
||||
}
|
||||
|
||||
int strlen(const char *s) {
|
||||
int n;
|
||||
|
||||
for(n = 0; s[n]; n++)
|
||||
;
|
||||
return n;
|
||||
}
|
||||
Reference in New Issue
Block a user