initial commit
authorJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 7 Jun 2021 00:15:56 +0000 (03:15 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 7 Jun 2021 00:15:56 +0000 (03:15 +0300)
.gitignore [new file with mode: 0644]
sys1/kern/.gdbinit [new file with mode: 0644]
sys1/kern/Makefile [new file with mode: 0644]
sys1/kern/kern1.ld [new file with mode: 0644]
sys1/kern/src/libc/stdint.h [new file with mode: 0644]
sys1/kern/src/libc/stdlib.h [new file with mode: 0644]
sys1/kern/src/libc/string.c [new file with mode: 0644]
sys1/kern/src/libc/string.h [new file with mode: 0644]
sys1/kern/src/main.c [new file with mode: 0644]
sys1/kern/src/start.asm [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..c7f577c
--- /dev/null
@@ -0,0 +1,6 @@
+*.o
+*.d
+*.swp
+*.elf
+*.map
+*.log
diff --git a/sys1/kern/.gdbinit b/sys1/kern/.gdbinit
new file mode 100644 (file)
index 0000000..8d7b810
--- /dev/null
@@ -0,0 +1,2 @@
+target remote localhost:1234
+set disassembly-flavor intel
diff --git a/sys1/kern/Makefile b/sys1/kern/Makefile
new file mode 100644 (file)
index 0000000..5ad379f
--- /dev/null
@@ -0,0 +1,42 @@
+csrc = $(wildcard src/*.c) $(wildcard src/libc/*.c)
+asmsrc = $(wildcard src/*.asm) $(wildcard src/libc/*.asm)
+obj = $(csrc:.c=.o) $(asmsrc:.asm=-asm.o)
+dep = $(csrc:.c=.d)
+elf = kern1.elf
+
+warn = -pedantic -Wall
+dbg = -g
+inc = -Isrc -Isrc/libc
+
+CFLAGS = $(carch) $(warn) $(dbg) $(inc) -fno-pic -ffreestanding -nostdinc \
+                -fno-builtin -MMD
+LDFLAGS = $(ldarch) -nostdlib -T kern1.ld -Map kern1.map
+
+ifeq ($(shell uname -m), x86_64)
+       carch = -m32
+       ldarch = -m elf_i386
+endif
+
+$(elf): $(obj)
+       $(LD) -o $@ $(obj) $(LDFLAGS)
+
+-include $(dep)
+
+%-asm.o: %.asm
+       nasm -f elf32 -o $@ $<
+
+.PHONY: clean
+clean:
+       rm -f $(obj) $(elf) link.map
+
+.PHONY: cleandep
+cleandep:
+       rm -f $(dep)
+
+.PHONY: run
+run: $(elf)
+       qemu-system-i386 -kernel $(elf) -serial file:serial.log
+
+.PHONY: debug
+debug: $(elf)
+       qemu-system-i386 -kernel $(elf) -serial file:serial.log -s -S
diff --git a/sys1/kern/kern1.ld b/sys1/kern/kern1.ld
new file mode 100644 (file)
index 0000000..f286e93
--- /dev/null
@@ -0,0 +1,29 @@
+OUTPUT_ARCH(i386)
+
+SECTIONS {
+       /* kernel will be loaded at 1MB by the boot loader */
+       . = 1M;
+
+       /* .startup needs to be first for the entry point to be at 1MB */
+       .startup : { * (.startup); }
+       /* the rest of the image sections */
+       .text : { * (.text); }
+       .rodata : { * (.rodata); }
+       .data : { * (.data); }
+
+       /* create markers for the start/end of the .bss section so that startup
+        * can initialize it to zero before transfering control to the C code.
+        */
+       .bss ALIGN(4): {
+               _bss_start = .;
+               * (.bss);
+               . = ALIGN(4);
+               _bss_end = .;
+       }
+       _bss_size = SIZEOF(.bss);
+
+       /* end of kernel marker. the allocator will mark all memory up to this
+        * point as used.
+        */
+       _kern_end = .;
+};
diff --git a/sys1/kern/src/libc/stdint.h b/sys1/kern/src/libc/stdint.h
new file mode 100644 (file)
index 0000000..2614e32
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef KLIBC_STDINT_H_
+#define KLIBC_STDINT_H_
+
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+
+#endif /* KLIBC_STDINT_H_ */
diff --git a/sys1/kern/src/libc/stdlib.h b/sys1/kern/src/libc/stdlib.h
new file mode 100644 (file)
index 0000000..dfd634f
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef KLIBC_STDLIB_H_
+#define KLIBC_STDLIB_H_
+
+typedef int ssize_t;
+typedef unsigned int size_t;
+
+#endif /* KLIBC_STDLIB_H_ */
diff --git a/sys1/kern/src/libc/string.c b/sys1/kern/src/libc/string.c
new file mode 100644 (file)
index 0000000..3b11896
--- /dev/null
@@ -0,0 +1,30 @@
+#include "string.h"
+#include "stdint.h"
+
+void *memset(void *dest, int val, size_t num)
+{
+       unsigned char *p = dest;
+
+       while(num--) *p++ = val;
+
+       return dest;
+}
+
+void *memset16(void *dest, int val, size_t num)
+{
+       uint16_t *p = dest;
+
+       while(num--) *p++ = val;
+
+       return dest;
+}
+
+void *memcpy(void *dest, void *src, size_t num)
+{
+       unsigned char *d = dest;
+       unsigned char *s = src;
+
+       while(num--) *d++ = *s++;
+
+       return dest;
+}
diff --git a/sys1/kern/src/libc/string.h b/sys1/kern/src/libc/string.h
new file mode 100644 (file)
index 0000000..8024665
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef KLIBC_STRING_H_
+#define KLIBC_STRING_H_
+
+#include <stdlib.h>
+
+void *memset(void *dest, int val, size_t num);
+void *memset16(void *dest, int val, size_t num);
+void *memcpy(void *dest, void *src, size_t num);
+
+#endif /* KLIBC_STRING_H_ */
diff --git a/sys1/kern/src/main.c b/sys1/kern/src/main.c
new file mode 100644 (file)
index 0000000..b89a98b
--- /dev/null
@@ -0,0 +1,22 @@
+#include <string.h>
+#include <stdint.h>
+
+void clearscr(void)
+{
+       memset((void*)0xb8000, 0, 80 * 25 * 2);
+}
+
+void drawtext(int x, int y, const char *s)
+{
+       uint16_t *vptr = (uint16_t*)0xb8000 + y * 80 + x;
+
+       while(*s) {
+               *vptr++ = 0x0c00 | *s++;
+       }
+}
+
+void kmain(void)
+{
+       clearscr();
+       drawtext(10, 5, "3sys kernel 1");
+}
diff --git a/sys1/kern/src/start.asm b/sys1/kern/src/start.asm
new file mode 100644 (file)
index 0000000..f9baf52
--- /dev/null
@@ -0,0 +1,45 @@
+       bits 32
+       section .text
+
+       extern _bss_start
+       extern _bss_size
+       extern kmain
+
+MB_MAGIC equ 0x1badb002
+MB_FLAGS equ 0
+
+
+       global start
+start:
+       jmp .skip_mboot_hdr
+
+       ; multiboot header
+       align 4
+       dd MB_MAGIC
+       dd MB_FLAGS
+       dd -(MB_MAGIC + MB_FLAGS)       ; checksum
+       times 5 dd 0
+
+.skip_mboot_hdr:
+       ; init temporary kernel stack at the top of conventional memory
+       mov esp, 0xa0000
+
+       ; clear .bss (if it's not empty)
+       ; due to the ALIGN(4) statements in the linker script, it's guaranteed
+       ; that _bss_start and _bss_end will be 32bit-aligned, so we can use
+       ; rep stosd to clear it
+       mov ecx, _bss_size
+       test ecx, ecx
+       jz .skip_bss
+       xor eax, eax
+       mov edi, _bss_start
+       shr ecx, 2      ; _bss_size is in bytes, we need count in "dwords"
+       rep stosd
+.skip_bss:
+
+       call kmain
+       ; kmain shouldn't ever return, but we'll enter a hlt loop just in case
+.inf:  hlt
+       jmp .inf
+
+; vi:ft=nasm: