changeset 1:42ba76f77035 default tip

the kernel with output and mem alloc
author meillo@marmaro.de
date Sun, 01 Nov 2009 23:50:51 +0100
parents 99db6262c157
children
files io.c io.h kernel.c makefile mem.c mem.h
diffstat 6 files changed, 301 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/io.c	Sun Nov 01 23:50:51 2009 +0100
@@ -0,0 +1,151 @@
+#include <stdarg.h>
+#include "io.h"
+
+void prints(const char* str);
+
+static unsigned short* vidmem = (unsigned short*) 0xb8000;
+static unsigned short color = 0x0700;
+static int pos = 0;
+
+void
+cls(void)
+{
+	unsigned short* v;
+
+	for (v = vidmem; v < vidmem+(80*25); v++) {
+		*v = 0;
+	}
+	pos = 0;
+}
+
+
+void
+setcolor(int fg, int bg)
+{
+	color = (char) ((fg<<2) & (bg<<3));
+}
+
+void
+setpos(int line, int col)
+{
+	pos = line * 80 + col;
+}
+
+void
+relpos(int move)
+{
+	pos += move;
+}
+
+
+void
+printp(unsigned int n)
+{
+	int i, h;
+	char str[11];
+	//int n = (int) p;
+
+	str[0] = '0';
+	str[1] = 'x';
+	str[10] = '\0';
+	for (i=9; i>1; i--) {
+		h = n % 16;
+		str[i] = ('0' + h);
+		if (h > 9) {
+			str[i] += 'a' - '9' - 1;
+		}
+		n /= 16;
+	}
+	prints(str);
+}
+
+
+
+
+void
+printc(char c)
+{
+	putchar(c);
+}
+
+void
+prints(const char* str)
+{
+	const char* c;
+
+	for (c = str; *c; c++) {
+		printc(*c);
+	}
+}
+
+void
+printd(int n)
+{
+	int i;
+	char str[32];
+
+	str[31] = '\0';
+	for (i=30; i>0; i--) {
+		str[i] = ('0' + n%10);
+		if (n == 0) {
+			i++;
+			break;
+		}
+		n /= 10;
+	}
+	prints(&str[i]);
+}
+
+
+int
+putchar(int c)
+{
+	if (c == '\n') {
+		pos = ((pos/80)+1) * 80;
+	} else {
+		vidmem[pos++] = (unsigned short)c | color;
+	}
+	return (unsigned char)c;
+}
+
+int
+puts(const char* s)
+{
+	prints(s);
+	putchar('\n');
+	return 1;
+}
+
+int
+printf(const char* fmt, ...)
+{
+	va_list ap;
+	int i;
+
+	va_start(ap, fmt);
+	for (i=0; fmt[i]; i++) {
+		if (fmt[i] != '%') {
+			printc(fmt[i]);
+			continue;
+		}
+		switch (fmt[++i]) {
+		case '%':
+			printc('%');
+			break;
+		case 'c':
+			printc((char)va_arg(ap, int));
+			break;
+		case 's':
+			prints(va_arg(ap, char*));
+			break;
+		case 'd':
+			printd(va_arg(ap, int));
+			break;
+		case 'p':
+			printp(va_arg(ap, unsigned int));
+			break;
+		}
+	}
+	va_end(ap);
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/io.h	Sun Nov 01 23:50:51 2009 +0100
@@ -0,0 +1,9 @@
+
+void cls(void);
+void setcolor(int fg, int bg);
+void setpos(int line, int col);
+void relpos(int move);
+
+int putchar(int c);
+int puts(const char* s);
+int printf(const char* fmt, ...);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel.c	Sun Nov 01 23:50:51 2009 +0100
@@ -0,0 +1,31 @@
+/* markus schnalke <meillo@marmaro.de> */
+
+#include "io.h"
+#include "mem.h"
+
+void
+kmain(void)
+{
+	unsigned char* p;
+
+	cls();
+	printf("OS says: Hi!\n\n");
+
+	initmem(0x00400000);  /* heap starts at 4MB */
+
+	printf("init done\n");
+	printf("\n");
+
+	p = malloc(28);
+	printf("allocated %d bytes at %p\n", 28, p);
+	p = malloc(15);
+	printf("allocated %d bytes at %p\n", 15, p);
+
+	printf("aa %d bb %c cc %s\n", 5, '@', "hallo");
+	printf("minmem: %p\n", 0x00400000);
+
+	setpos(24, 0);
+	printf("loop\n");
+	while (1) {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/makefile	Sun Nov 01 23:50:51 2009 +0100
@@ -0,0 +1,28 @@
+
+CC = i386-elf-gcc
+CFLAGS = -Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs
+
+LD = i386-elf-ld
+LDFLAGS = -T linker.ld
+
+OBJ =  loader.o kernel.o io.o mem.o
+
+qemu: os.iso
+	qemu -m 16 -boot cd -cdrom os.iso
+
+os.iso: kernel
+	cp kernel os-isofiles/boot/kernel
+	genisoimage -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o os.iso os-isofiles
+
+loader.o: loader.s
+	yasm -f elf -o loader.o loader.s
+
+kernel: linker.ld $(OBJ)
+	i386-elf-ld -T linker.ld -o kernel $(OBJ)
+
+clean:
+	rm -f *.o
+	rm -f kernel
+
+distclean: clean
+	rm -f os.iso
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mem.c	Sun Nov 01 23:50:51 2009 +0100
@@ -0,0 +1,74 @@
+#include "mem.h"
+#include "io.h"
+
+
+void
+initmem(unsigned int memstart)
+{
+	unsigned int* p;
+	int step = 2*1024*1024;
+	unsigned int* zero = 0x0;
+
+
+	minmem = (unsigned char*)memstart;
+
+	/* disable cache */
+	__asm__ __volatile__ (
+		"movl %cr0, %eax\n\t"
+		"movl $0x60000000, %ebx\n\t"
+		"orl %ebx, %eax\n\t"
+		"movl %eax, %cr0"
+	);
+
+	/* test mem size */
+	p = (unsigned int*) ((unsigned int)minmem/sizeof(char));
+	do {
+		p += step;
+		*p = 0xf0f0f0f0;
+	} while (*p == 0xf0f0f0f0);
+	maxmem = (unsigned char*)p;
+
+	/* test mem mirroring */
+	p = 0;
+	*p = 0;
+	p++;
+	while (p < (unsigned int*)minmem) {
+		p = (unsigned int*) ((unsigned int)p * 2);
+	}
+	while (p < (unsigned int*)maxmem) {
+		*p = 0xf0f0f0f0;
+		if (*zero == 0xf0f0f0f0) {
+			maxmem = (unsigned char*)p;
+			break;
+		}
+		p = (unsigned int*) ((unsigned int)p * 2);
+	}
+
+	/* enable cache again */
+	__asm__ __volatile__ (
+		"movl %cr0, %eax\n\t"
+		"movl $0x60000000, %ebx \n\t"
+		"negl %ebx\n\t"
+		"andl %ebx, %eax\n\t"
+		"movl %eax, %cr0"
+	);
+
+	/* min, max */
+	printf("mem: start=%p end=%p size=%p\n", minmem, maxmem, (void*)(maxmem-minmem));
+
+	/* init heap */
+	newp = minmem;
+}
+
+
+void*
+malloc(unsigned int size)
+{
+	if (newp + size > maxmem) {
+		printf("Fatal error: memory exhausted!\n");
+		while (1) {
+		}
+	}
+	newp += size;
+	return newp - size;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mem.h	Sun Nov 01 23:50:51 2009 +0100
@@ -0,0 +1,8 @@
+
+unsigned char* newp;
+unsigned char* maxmem;
+unsigned char* minmem;
+
+void initmem(unsigned int memstart);
+void* malloc(unsigned int size);
+