Initial commit
This commit is contained in:
commit
ecd4fe2bc1
|
@ -0,0 +1,20 @@
|
||||||
|
.PHONY: all clean install
|
||||||
|
|
||||||
|
all: kernel
|
||||||
|
|
||||||
|
install: kernel
|
||||||
|
mount bootdisk.img /mnt -o loop
|
||||||
|
cp kernel /mnt/kernel
|
||||||
|
umount /mnt
|
||||||
|
|
||||||
|
kernel: start.o link.ld main.o vga.o
|
||||||
|
ld -m elf_i386 -T link.ld -o kernel start.o main.o vga.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
gcc -Wall -m32 -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o $@ $<
|
||||||
|
|
||||||
|
start.o: start.asm
|
||||||
|
nasm -f elf -o start.o start.asm
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o kernel
|
|
@ -0,0 +1,2 @@
|
||||||
|
# klange's OS Development Repo #
|
||||||
|
I'm writing an OS because I'm bored and want a massive project to suck up the little pieces of my time for the next few years.
|
Binary file not shown.
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef __SYSTEM_H
|
||||||
|
#define __SYSTEM_H
|
||||||
|
|
||||||
|
/* Kernel Main */
|
||||||
|
extern unsigned char *memcpy(unsigned char *dest, const unsigned char *src, int count);
|
||||||
|
extern unsigned char *memset(unsigned char *dest, unsigned char val, int count);
|
||||||
|
extern unsigned short *memsetw(unsigned short *dest, unsigned short val, int count);
|
||||||
|
extern int strlen(const char *str);
|
||||||
|
extern unsigned char inportb (unsigned short _port);
|
||||||
|
extern void outportb (unsigned short _port, unsigned char _data);
|
||||||
|
|
||||||
|
/* VGA driver */
|
||||||
|
extern void cls();
|
||||||
|
extern void putch(unsigned char c);
|
||||||
|
extern void puts(unsigned char *str);
|
||||||
|
extern void settextcolor(unsigned char forecolor, unsigned char backcolor);
|
||||||
|
extern void init_video();
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,25 @@
|
||||||
|
OUTPUT_FORMAT("binary")
|
||||||
|
ENTRY(start)
|
||||||
|
phys = 0x00100000;
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text phys : AT(phys) {
|
||||||
|
code = .;
|
||||||
|
*(.text)
|
||||||
|
*(.rodata)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
}
|
||||||
|
.data : AT(phys + (data - code))
|
||||||
|
{
|
||||||
|
data = .;
|
||||||
|
*(.data)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
}
|
||||||
|
.bss : AT(phys + (bss - code))
|
||||||
|
{
|
||||||
|
bss = .;
|
||||||
|
*(.bss)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
}
|
||||||
|
end = .;
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include <system.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* memcpy
|
||||||
|
* Copy from source to destination. Assumes that
|
||||||
|
* source and destination are not overlapping.
|
||||||
|
*/
|
||||||
|
unsigned char *
|
||||||
|
memcpy(
|
||||||
|
unsigned char *dest,
|
||||||
|
const unsigned char *src,
|
||||||
|
int count
|
||||||
|
) {
|
||||||
|
int i;
|
||||||
|
i = 0;
|
||||||
|
for ( ; i < count; ++i ) {
|
||||||
|
dest[i] = src[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* memset
|
||||||
|
* Set `count` bytes to `val`.
|
||||||
|
*/
|
||||||
|
unsigned char *
|
||||||
|
memset(
|
||||||
|
unsigned char *dest,
|
||||||
|
unsigned char val,
|
||||||
|
int count
|
||||||
|
) {
|
||||||
|
int i;
|
||||||
|
i = 0;
|
||||||
|
for ( ; i < count; ++i ) {
|
||||||
|
dest[i] = val;
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* memsetw
|
||||||
|
* Set `count` shorts to `val`.
|
||||||
|
*/
|
||||||
|
unsigned short *
|
||||||
|
memsetw(
|
||||||
|
unsigned short *dest,
|
||||||
|
unsigned short val,
|
||||||
|
int count
|
||||||
|
) {
|
||||||
|
int i;
|
||||||
|
i = 0;
|
||||||
|
for ( ; i < count; ++i ) {
|
||||||
|
dest[i] = val;
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* strlen
|
||||||
|
* Returns the length of a given `str`.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
strlen(
|
||||||
|
const char *str
|
||||||
|
) {
|
||||||
|
int i = 0;
|
||||||
|
while (str[i] != (char)0) {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* inportb
|
||||||
|
* Read from an I/O port.
|
||||||
|
*/
|
||||||
|
unsigned char
|
||||||
|
inportb(
|
||||||
|
unsigned short _port
|
||||||
|
) {
|
||||||
|
unsigned char rv;
|
||||||
|
__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* outportb
|
||||||
|
* Write to an I/O port.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
outportb(
|
||||||
|
unsigned short _port,
|
||||||
|
unsigned char _data
|
||||||
|
) {
|
||||||
|
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kernel Entry Point
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
main() {
|
||||||
|
init_video();
|
||||||
|
puts("Hello world!\n");
|
||||||
|
for (;;);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
[BITS 32]
|
||||||
|
global start
|
||||||
|
start:
|
||||||
|
mov esp, _sys_stack
|
||||||
|
jmp stublet
|
||||||
|
|
||||||
|
ALIGN 4
|
||||||
|
mboot:
|
||||||
|
MULTIBOOT_PAGE_ALIGN equ 1<<0
|
||||||
|
MULTIBOOT_MEMORY_INFO equ 1<<1
|
||||||
|
MULTIBOOT_AOUT_KLUDGE equ 1<<16
|
||||||
|
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
|
||||||
|
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
|
||||||
|
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||||
|
EXTERN code, bss, end
|
||||||
|
; GRUB Multiboot header, boot signature
|
||||||
|
dd MULTIBOOT_HEADER_MAGIC
|
||||||
|
dd MULTIBOOT_HEADER_FLAGS
|
||||||
|
dd MULTIBOOT_CHECKSUM
|
||||||
|
; AOUT kludge (must be physical addresses)
|
||||||
|
; Linker script fills these in
|
||||||
|
dd mboot
|
||||||
|
dd code
|
||||||
|
dd bss
|
||||||
|
dd end
|
||||||
|
dd start
|
||||||
|
|
||||||
|
; Main entrypoint
|
||||||
|
stublet:
|
||||||
|
extern main
|
||||||
|
call main
|
||||||
|
jmp $
|
||||||
|
|
||||||
|
; GDT
|
||||||
|
|
||||||
|
; Interrupt Service Routines
|
||||||
|
|
||||||
|
; BSS Section
|
||||||
|
SECTION .bss
|
||||||
|
resb 8192 ; 8KB of memory reserved
|
||||||
|
_sys_stack:
|
||||||
|
; This line intentionally left blank
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
#include <system.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Text pointer, background, foreground
|
||||||
|
*/
|
||||||
|
unsigned short * textmemptr;
|
||||||
|
int attrib = 0x0F;
|
||||||
|
int csr_x = 0, csr_y = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* scroll
|
||||||
|
* Scroll the screen
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
scroll() {
|
||||||
|
unsigned blank, temp;
|
||||||
|
blank = 0x20 | (attrib << 8);
|
||||||
|
if (csr_y >= 25) {
|
||||||
|
/*
|
||||||
|
* Move the current text chunk that makes up the screen
|
||||||
|
* back in the buffer by one line.
|
||||||
|
*/
|
||||||
|
temp = csr_y - 25 + 1;
|
||||||
|
memcpy(textmemptr, textmemptr + temp * 80, (25 - temp) * 80 * 2);
|
||||||
|
/*
|
||||||
|
* Set the chunk of memory that occupies
|
||||||
|
* the last line of text to the blank character
|
||||||
|
*/
|
||||||
|
memsetw(textmemptr + (25 - temp) * 80, blank, 80);
|
||||||
|
csr_y = 25 - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* move_csr
|
||||||
|
* Update the hardware cursor
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
move_csr() {
|
||||||
|
unsigned temp;
|
||||||
|
temp = csr_y * 80 + csr_x;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write stuff out.
|
||||||
|
*/
|
||||||
|
outportb(0x3D4, 14);
|
||||||
|
outportb(0x3D5, temp >> 8);
|
||||||
|
outportb(0x3D4, 15);
|
||||||
|
outportb(0x3D5, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cls
|
||||||
|
* Clear the screen
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cls() {
|
||||||
|
unsigned blank;
|
||||||
|
int i;
|
||||||
|
blank = 0x20 | (attrib << 8);
|
||||||
|
for (i = 0; i < 25; ++i) {
|
||||||
|
memsetw(textmemptr + i * 80, blank, 80);
|
||||||
|
}
|
||||||
|
csr_x = 0;
|
||||||
|
csr_y = 0;
|
||||||
|
move_csr();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* putch
|
||||||
|
* Puts a character to the screen
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
putch(
|
||||||
|
unsigned char c
|
||||||
|
) {
|
||||||
|
unsigned short *where;
|
||||||
|
unsigned att = attrib << 8;
|
||||||
|
if (c == 0x08) {
|
||||||
|
/* Backspace */
|
||||||
|
if (csr_x != 0) csr_x--;
|
||||||
|
} else if (c == 0x09) {
|
||||||
|
/* Tab */
|
||||||
|
csr_x = (csr_x + 8) & ~(8 - 1);
|
||||||
|
} else if (c == '\r') {
|
||||||
|
/* Carriage return */
|
||||||
|
csr_x = 0;
|
||||||
|
} else if (c == '\n') {
|
||||||
|
/* New line */
|
||||||
|
csr_x = 0;
|
||||||
|
csr_y++;
|
||||||
|
} else if (c >= ' ') {
|
||||||
|
where = textmemptr + (csr_y * 80 + csr_x);
|
||||||
|
*where = c | att;
|
||||||
|
csr_x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (csr_x >= 80) {
|
||||||
|
csr_x = 0;
|
||||||
|
csr_y++;
|
||||||
|
}
|
||||||
|
scroll();
|
||||||
|
move_csr();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* puts
|
||||||
|
* Put string to screen
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
puts(
|
||||||
|
unsigned char * text
|
||||||
|
){
|
||||||
|
int i;
|
||||||
|
int len = strlen(text);
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
putch(text[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* settextcolor
|
||||||
|
* Sets the foreground and background color
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
settextcolor(
|
||||||
|
unsigned char forecolor,
|
||||||
|
unsigned char backcolor
|
||||||
|
) {
|
||||||
|
attrib = (backcolor << 4) | (forecolor & 0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_video
|
||||||
|
* Initialize the VGA driver.
|
||||||
|
*/
|
||||||
|
void init_video() {
|
||||||
|
textmemptr = (unsigned short *)0xB8000;
|
||||||
|
cls();
|
||||||
|
}
|
Loading…
Reference in New Issue