mirror of
https://github.com/samsonjs/kernel.git
synced 2026-03-25 09:25:46 +00:00
first commit
This commit is contained in:
commit
9c18212f37
13 changed files with 403 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
src/*.o
|
||||
bochs.out
|
||||
src/kernel
|
||||
9
bochsrc
Normal file
9
bochsrc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
megs: 32
|
||||
romimage: file=/usr/share/bochs/BIOS-bochs-latest
|
||||
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest
|
||||
floppya: 1_44=/dev/loop0, status=inserted
|
||||
boot: a
|
||||
log: bochs.out
|
||||
mouse: enabled=0
|
||||
clock: sync=realtime
|
||||
cpu: ips=500000
|
||||
BIN
floppy.img
Normal file
BIN
floppy.img
Normal file
Binary file not shown.
6
run_bochs.sh
Executable file
6
run_bochs.sh
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
losetup /dev/loop0 floppy.img
|
||||
bochs -f bochsrc
|
||||
sleep 1
|
||||
losetup -d /dev/loop0
|
||||
16
src/Makefile
Normal file
16
src/Makefile
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
SOURCES=boot.o main.o common.o monitor.o
|
||||
|
||||
CFLAGS=-nostdlib -nostdinc -fno-builtin -fno-stack-protector
|
||||
LDFLAGS=-T link.ld
|
||||
ASFLAGS=-f elf
|
||||
|
||||
all: $(SOURCES) link
|
||||
|
||||
clean:
|
||||
-rm *.o kernel
|
||||
|
||||
link:
|
||||
ld $(LDFLAGS) -o kernel $(SOURCES)
|
||||
|
||||
.s.o:
|
||||
yasm $(ASFLAGS) $<
|
||||
45
src/boot.s
Normal file
45
src/boot.s
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
;;
|
||||
;; boot.s -- Kernel start location. Also defines multiboot header.
|
||||
;; Based on Bran's kernel development tutorial file start.asm
|
||||
;;
|
||||
|
||||
MBOOT_PAGE_ALIGN equ 1<<0 ; Load kernel and modules on a page boundary
|
||||
MBOOT_MEM_INFO equ 1<<1 ; Provide your kernel with memory info
|
||||
MBOOT_HEADER_MAGIC equ 0x1BADB002 ; Multiboot Magic value
|
||||
;; NOTE: We do not use MBOOT_AOUT_KLUDGE. It means that GRUB does not
|
||||
;; pass us a symbol table.
|
||||
MBOOT_HEADER_FLAGS equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO
|
||||
MBOOT_CHECKSUM equ -(MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS)
|
||||
|
||||
|
||||
[BITS 32] ; All instructions should be 32-bit.
|
||||
|
||||
[GLOBAL mboot] ; Make 'mboot' accessible from C.
|
||||
[EXTERN code] ; Start of the '.text' section.
|
||||
[EXTERN bss] ; Start of the .bss section.
|
||||
[EXTERN end] ; End of the last loadable section.
|
||||
|
||||
mboot:
|
||||
dd MBOOT_HEADER_MAGIC ; GRUB will search for this value on each
|
||||
;; 4-byte boundary in your kernel file
|
||||
dd MBOOT_HEADER_FLAGS ; How GRUB should load your file / settings
|
||||
dd MBOOT_CHECKSUM ; To ensure that the above values are correct
|
||||
|
||||
dd mboot ; Location of this descriptor
|
||||
dd code ; Start of kernel '.text' (code) section.
|
||||
dd bss ; End of kernel '.data' section.
|
||||
dd end ; End of kernel.
|
||||
dd start ; Kernel entry point (initial EIP).
|
||||
|
||||
[GLOBAL start] ; Kernel entry point.
|
||||
[EXTERN main] ; This is the entry point of our C code
|
||||
|
||||
start:
|
||||
push ebx ; Load multiboot header location
|
||||
|
||||
;; Execute the kernel:
|
||||
cli ; Disable interrupts.
|
||||
call main ; call our main() function.
|
||||
jmp $ ; Enter an infinite loop, to stop the processor
|
||||
;; executing whatever rubbish is in the memory
|
||||
;; after our kernel!
|
||||
36
src/common.c
Normal file
36
src/common.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// common.c -- Defines some global functions.
|
||||
// From JamesM's kernel development tutorials.
|
||||
|
||||
#include "common.h"
|
||||
|
||||
// Write a byte out to the specified port.
|
||||
void outb(u16int port, u8int value)
|
||||
{
|
||||
|
||||
asm volatile ("outb %1, %0" : : "dN" (port), "a" (value));
|
||||
|
||||
}
|
||||
|
||||
|
||||
u8int inb(u16int port)
|
||||
{
|
||||
|
||||
u8int ret;
|
||||
|
||||
asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port));
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
u16int inw(u16int port)
|
||||
{
|
||||
|
||||
u16int ret;
|
||||
|
||||
asm volatile ("inw %1, %0" : "=a" (ret) : "dN" (port));
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
29
src/common.h
Normal file
29
src/common.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// common.h -- Defines typedefs and some global functions.
|
||||
// From JamesM's kernel development tutorials.
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
// Some nice typedefs, to standardise sizes across platforms.
|
||||
// These typedefs are written for 32-bit X86.
|
||||
typedef unsigned int u32int;
|
||||
|
||||
typedef int s32int;
|
||||
|
||||
typedef unsigned short u16int;
|
||||
|
||||
typedef short s16int;
|
||||
|
||||
typedef unsigned char u8int;
|
||||
|
||||
typedef char s8int;
|
||||
|
||||
|
||||
void outb(u16int port, u8int value);
|
||||
|
||||
u8int inb(u16int port);
|
||||
|
||||
u16int inw(u16int port);
|
||||
|
||||
|
||||
#endif
|
||||
32
src/link.ld
Normal file
32
src/link.ld
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* Link.ld -- Linker script for the kernel - ensure everything goes in the */
|
||||
/* Correct place. */
|
||||
/* Original file taken from Bran's Kernel Development */
|
||||
/* tutorials: http://www.osdever.net/bkerndev/index.php. */
|
||||
|
||||
ENTRY(start)
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x100000 :
|
||||
{
|
||||
code = .; _code = .; __code = .;
|
||||
*(.text)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
.data :
|
||||
{
|
||||
data = .; _data = .; __data = .;
|
||||
*(.data)
|
||||
*(.rodata)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
bss = .; _bss = .; __bss = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
end = .; _end = .; __end = .;
|
||||
}
|
||||
18
src/main.c
Normal file
18
src/main.c
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// main.c -- Defines the C-code kernel entry point, calls initialisation routines.
|
||||
// Made for JamesM's tutorials
|
||||
|
||||
#include "monitor.h"
|
||||
|
||||
int main(struct multiboot *mboot_ptr)
|
||||
{
|
||||
monitor_clear();
|
||||
monitor_write("Hello, world!");
|
||||
|
||||
monitor_newline();
|
||||
monitor_write_dec(42);
|
||||
|
||||
monitor_newline();
|
||||
monitor_write_hex(0xdeadbeef);
|
||||
|
||||
return 0xdeadbeef;
|
||||
}
|
||||
174
src/monitor.c
Normal file
174
src/monitor.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
#include "monitor.h"
|
||||
|
||||
// The VGA framebuffer starts at 0xB8000.
|
||||
u16int *video_memory = (u16int *)0xB8000;
|
||||
u8int cursor_x = 0;
|
||||
u8int cursor_y = 0;
|
||||
|
||||
// Updates the hardware cursor.
|
||||
static void move_cursor()
|
||||
{
|
||||
// The screen is 80 characters wide...
|
||||
u16int cursorLocation = cursor_y * 80 + cursor_x;
|
||||
|
||||
outb(0x3D4, 14);
|
||||
// Tell the VGA board we are setting the high cursor byte.
|
||||
outb(0x3D5, cursorLocation >> 8);
|
||||
// Send the high cursor byte.
|
||||
outb(0x3D4, 15);
|
||||
// Tell the VGA board we are setting the low cursor byte.
|
||||
outb(0x3D5, cursorLocation);
|
||||
// Send the low cursor byte.
|
||||
}
|
||||
|
||||
// Scrolls the text on the screen up by one line.
|
||||
static void scroll()
|
||||
{
|
||||
// Get a space character with the default colour attributes.
|
||||
u8int attributeByte = (0 /*black*/ << 4) | (15 /*white*/ & 0x0F);
|
||||
u16int blank = 0x20 /* space */ | (attributeByte << 8);
|
||||
|
||||
// Row 25 is the end, this means we need to scroll up
|
||||
if (cursor_y >= 25) {
|
||||
// Move the current text chunk that makes up the screen
|
||||
// back in the buffer by a line
|
||||
int i;
|
||||
|
||||
for (i = 0*80; i < 24*80; i++) {
|
||||
video_memory[i] = video_memory[i+80];
|
||||
}
|
||||
|
||||
// The last line should now be blank. Do this by writing
|
||||
// 80 spaces to it.
|
||||
for (i = 24*80; i < 25*80; i++) {
|
||||
video_memory[i] = blank;
|
||||
}
|
||||
|
||||
// The cursor should now be on the last line.
|
||||
cursor_y = 24;
|
||||
}
|
||||
}
|
||||
|
||||
// Writes a single character out to the screen.
|
||||
void monitor_put(char c)
|
||||
{
|
||||
// The background colour is black (0), the foreground is white (15).
|
||||
u8int backColour = 0;
|
||||
u8int foreColour = 15;
|
||||
|
||||
// The attribute byte is made up of two nibbles - the lower being the
|
||||
// foreground colour, and the upper the background colour.
|
||||
u8int attributeByte = (backColour << 4) | (foreColour & 0x0F);
|
||||
|
||||
// The attribute byte is the top 8 bits of the word we have to send to the
|
||||
// VGA board.
|
||||
u16int attribute = attributeByte << 8;
|
||||
u16int *location;
|
||||
|
||||
// Handle a backspace, by moving the cursor back one space
|
||||
if (c == 0x08 && cursor_x) {
|
||||
cursor_x--;
|
||||
}
|
||||
|
||||
// Handle a tab by increasing the cursor's X, but only to a point
|
||||
// where it is divisible by 8.
|
||||
else if (c == 0x09) {
|
||||
cursor_x = (cursor_x+8) & ~(8-1);
|
||||
}
|
||||
|
||||
// Handle carriage return
|
||||
else if (c == '\r') {
|
||||
cursor_x = 0;
|
||||
}
|
||||
|
||||
|
||||
// Handle newline by moving cursor back to left and increasing the row
|
||||
else if (c == '\n') {
|
||||
cursor_x = 0;
|
||||
cursor_y++;
|
||||
}
|
||||
|
||||
// Handle any other printable character.
|
||||
else if(c >= ' ') {
|
||||
location = video_memory + (cursor_y*80 + cursor_x);
|
||||
*location = c | attribute;
|
||||
cursor_x++;
|
||||
}
|
||||
|
||||
// Check if we need to insert a new line because we have reached the end
|
||||
// of the screen.
|
||||
if (cursor_x >= 80) {
|
||||
cursor_x = 0;
|
||||
cursor_y ++;
|
||||
}
|
||||
|
||||
// Scroll the screen if needed.
|
||||
scroll();
|
||||
|
||||
// Move the hardware cursor.
|
||||
move_cursor();
|
||||
}
|
||||
|
||||
// Clears the screen, by copying lots of spaces to the framebuffer.
|
||||
void monitor_clear()
|
||||
{
|
||||
// Make an attribute byte for the default colours
|
||||
u8int attributeByte = (0 /*black*/ << 4) | (15 /*white*/ & 0x0F);
|
||||
u16int blank = 0x20 /* space */ | (attributeByte << 8);
|
||||
int i;
|
||||
for (i = 0; i < 80*25; i++) {
|
||||
video_memory[i] = blank;
|
||||
}
|
||||
|
||||
// Move the hardware cursor back to the start.
|
||||
cursor_x = 0;
|
||||
cursor_y = 0;
|
||||
move_cursor();
|
||||
}
|
||||
|
||||
// Outputs a null-terminated ASCII string to the monitor.
|
||||
void monitor_write(char *c)
|
||||
{
|
||||
int i = 0;
|
||||
while (c[i]) {
|
||||
monitor_put(c[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
void monitor_newline()
|
||||
{
|
||||
while (cursor_x > 0) monitor_put(' ');
|
||||
}
|
||||
|
||||
void monitor_write_hex(u32int n)
|
||||
{
|
||||
static char hex_chars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
u32int mask = 0xf0000000;
|
||||
int i = 28;
|
||||
while (i >= 0) {
|
||||
monitor_put(hex_chars[(n & mask) >> i]);
|
||||
mask >>= 4;
|
||||
i -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
u32int pow(base, exp)
|
||||
{
|
||||
u32int n = base;
|
||||
if (exp == 0) return 1;
|
||||
while (exp > 1) {
|
||||
n *= base;
|
||||
exp--;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void monitor_write_dec(u32int n)
|
||||
{
|
||||
static char dec_chars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||
int i = 7;
|
||||
while (i >= 0) {
|
||||
monitor_put(dec_chars[(n / pow(10, i--)) % 10]);
|
||||
}
|
||||
}
|
||||
27
src/monitor.h
Normal file
27
src/monitor.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// monitor.h -- Defines the interface for monitor.h
|
||||
// From JamesM's kernel development tutorials.
|
||||
|
||||
#ifndef MONITOR_H
|
||||
#define MONITOR_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
// Write a single character out to the screen.
|
||||
void monitor_put(char c);
|
||||
|
||||
// Clear the screen to all black.
|
||||
void monitor_clear();
|
||||
|
||||
// Output a null-terminated ASCII string to the monitor.
|
||||
void monitor_write(char *c);
|
||||
|
||||
// Move the cursor to the next line
|
||||
void monitor_newline();
|
||||
|
||||
// Output a number to the screen in hexadecimal notation.
|
||||
void monitor_write_hex(u32int n);
|
||||
|
||||
// Output a number to the screen in decimal notation.
|
||||
void monitor_write_dec(u32int n);
|
||||
|
||||
#endif // MONITOR_H
|
||||
8
update_image.sh
Executable file
8
update_image.sh
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
losetup /dev/loop0 floppy.img
|
||||
mount /dev/loop0 /mnt
|
||||
cp src/kernel /mnt/kernel
|
||||
sleep 1
|
||||
umount /mnt
|
||||
losetup -d /dev/loop0
|
||||
Loading…
Reference in a new issue