This repository has been archived by the owner on Jun 4, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9a3d0cb
commit 95a2d8b
Showing
92 changed files
with
1,289 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
menuentry "XeonOS v0.5" { | ||
multiboot /boot/XeonOSv0.5.elf | ||
boot | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// GCC provides these header files automatically | ||
// They give us access to useful things like fixed-width types | ||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
// First, let's do some basic checks to make sure we are using our x86-elf cross-compiler correctly | ||
#if defined(__linux__) | ||
#error "This code must be compiled with a cross-compiler" | ||
#elif !defined(__i386__) | ||
#error "This code must be compiled with an x86-elf compiler" | ||
#endif | ||
|
||
// This is the x86's VGA textmode buffer. To display text, we write data to this memory location | ||
volatile uint16_t* vga_buffer = (uint16_t*)0xB8000; | ||
// By default, the VGA textmode buffer has a size of 80x25 characters | ||
const int cols = 80; | ||
const int rows = 25; | ||
|
||
// We start displaying text in the top-left of the screen (column = 0, row = 0) | ||
int term_col = 0; | ||
int term_row = 0; | ||
uint8_t term_color = 0x0F; // Black background, White foreground | ||
|
||
// This function initiates the terminal by clearing it | ||
void term_init() | ||
{ | ||
// Clear the textmode buffer | ||
for (int col = 0; col < cols; col ++) | ||
{ | ||
for (int row = 0; row < rows; row ++) | ||
{ | ||
// The VGA textmode buffer has size (cols * rows). | ||
// Given this, we find an index into the buffer for our character | ||
const size_t index = (cols * row) + col; | ||
// Entries in the VGA buffer take the binary form BBBBFFFFCCCCCCCC, where: | ||
// - B is the background color | ||
// - F is the foreground color | ||
// - C is the ASCII character | ||
vga_buffer[index] = ((uint16_t)term_color << 8) | ' '; // Set the character to blank (a space character) | ||
} | ||
} | ||
} | ||
|
||
// This function places a single character onto the screen | ||
void term_putc(char c) | ||
{ | ||
// Remember - we don't want to display ALL characters! | ||
switch (c) | ||
{ | ||
case '\n': // Newline characters should return the column to 0, and increment the row | ||
{ | ||
term_col = 0; | ||
term_row ++; | ||
break; | ||
} | ||
|
||
default: // Normal characters just get displayed and then increment the column | ||
{ | ||
const size_t index = (cols * term_row) + term_col; // Like before, calculate the buffer index | ||
vga_buffer[index] = ((uint16_t)term_color << 8) | c; | ||
term_col ++; | ||
break; | ||
} | ||
} | ||
|
||
// What happens if we get past the last column? We need to reset the column to 0, and increment the row to get to a new line | ||
if (term_col >= cols) | ||
{ | ||
term_col = 0; | ||
term_row ++; | ||
} | ||
|
||
// What happens if we get past the last row? We need to reset both column and row to 0 in order to loop back to the top of the screen | ||
if (term_row >= rows) | ||
{ | ||
term_col = 0; | ||
term_row = 0; | ||
} | ||
} | ||
|
||
// This function prints an entire string onto the screen | ||
void printf(const char* str) | ||
{ | ||
for (size_t i = 0; str[i] != '\0'; i ++) // Keep placing characters until we hit the null-terminating character ('\0') | ||
term_putc(str[i]); | ||
} | ||
|
||
|
||
|
||
// This is our kernel's main function | ||
void main() | ||
{ | ||
// We're here! Let's initiate the terminal and display a message to show we got here. | ||
|
||
// Initiate terminal | ||
term_init(); | ||
|
||
// Display some messages | ||
printf("Hello, World!\n"); | ||
printf("Welcome to the kernel.\n"); | ||
printf("\n"); | ||
printf("This is xeonos v0.5 Pre-Release Alpha Version (0.5-PR-A)"); | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* The bootloader will start execution at the symbol designated as the entry point. In this case, that's 'start' (defined in start.s) */ | ||
ENTRY(start) | ||
|
||
/* Tell the linker part of the compiler where the various sections of the kernel will be put in the final kernel executable. */ | ||
SECTIONS | ||
{ | ||
/* Begin putting sections at 1 Megabyte (1M), a good place for kernels to be loaded at by the bootloader. */ | ||
/* This is because memory below 1 Megabyte is reserved for other x86-related things, so we can't use it */ | ||
. = 1M; | ||
|
||
/* We align all sections in the executable at multiples of 4 Kilobytes (4K). This will become useful later in development when we add paging */ | ||
|
||
/* First put the multiboot header, as it's required to be near the start of the executable otherwise the bootloader won't find it */ | ||
/* The Multiboot header is Read-Only data, so we can put it in a '.rodata' section. */ | ||
.rodata BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(.multiboot) | ||
} | ||
|
||
/* Executable code */ | ||
.text BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(.text) | ||
} | ||
|
||
/* Read-only data. */ | ||
.rodata BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(.rodata) | ||
} | ||
|
||
/* Read-write data (initialized) */ | ||
.data BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(.data) | ||
} | ||
|
||
/* Read-write data (uninitialized) and stack */ | ||
.bss BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(COMMON) | ||
*(.bss) | ||
} | ||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// We declare the 'kernel_main' label as being external to this file. | ||
// That's because it's the name of the main C function in 'kernel.c'. | ||
|
||
|
||
.extern main | ||
|
||
// We declare the 'start' label as global (accessible from outside this file), since the linker will need to know where it is. | ||
// In a bit, we'll actually take a look at the code that defines this label. | ||
.global start | ||
|
||
// Our bootloader, GRUB, needs to know some basic information about our kernel before it can boot it. | ||
// We give GRUB this information using a standard known as 'Multiboot'. | ||
// To define a valid 'Multiboot header' that will be recognised by GRUB, we need to hard code some | ||
// constants into the executable. The following code calculates those constants. | ||
|
||
|
||
.set MB_MAGIC, 0x1BADB002 // This is a 'magic' constant that GRUB will use to detect our kernel's location. | ||
|
||
|
||
.set MB_FLAGS, (1 << 0) | (1 << 1) // This tells GRUB to 1: load modules on page boundaries and 2: provide a memory map (this is useful later in development) | ||
|
||
// Finally, we calculate a checksum that includes all the previous values | ||
|
||
|
||
.set MB_CHECKSUM, (0 - (MB_MAGIC + MB_FLAGS)) | ||
|
||
// We now start the section of the executable that will contain our Multiboot header | ||
|
||
|
||
.section .multiboot | ||
.align 4 // Make sure the following data is aligned on a multiple of 4 bytes | ||
|
||
// Use the previously calculated constants in executable code | ||
.long MB_MAGIC | ||
|
||
.long MB_FLAGS | ||
|
||
// Use the checksum we calculated earlier | ||
.long MB_CHECKSUM | ||
|
||
|
||
|
||
// This section contains data initialised to zeroes when the kernel is loaded | ||
.section .bss | ||
// Our C code will need a stack to run. Here, we allocate 4096 bytes (or 4 Kilobytes) for our stack. | ||
// We can expand this later if we want a larger stack. For now, it will be perfectly adequate. | ||
.align 16 | ||
stack_bottom: | ||
.skip 4096 // Reserve a 4096-byte (4K) stack | ||
stack_top: | ||
|
||
// This section contains our actual assembly code to be run when our kernel loads | ||
.section .text | ||
|
||
// Here is the 'start' label we mentioned before. This is the first code that gets run in our kernel. | ||
|
||
|
||
start: | ||
// First thing's first: we want to set up an environment that's ready to run C code. | ||
// C is very relaxed in its requirements: All we need to do is to set up the stack. | ||
// Please note that on x86, the stack grows DOWNWARD. This is why we start at the top. | ||
|
||
mov $stack_top, %esp // Set the stack pointer to the top of the stack | ||
|
||
// Now we have a C-worthy (haha!) environment ready to run the rest of our kernel. | ||
// At this point, we can call our main C function. | ||
|
||
call main | ||
|
||
// If, by some mysterious circumstances, the kernel's C code ever returns, all we want to do is to hang the CPU | ||
hang: | ||
cli // Disable CPU interrupts | ||
hlt // Halt the CPU | ||
jmp hang // If that didn't work, loop around and try again. |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
menuentry "XeonOSv0.9" { | ||
multiboot /boot/avis.kernel | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// GCC provides these header files automatically | ||
// They give us access to useful things like fixed-width types | ||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
// First, let's do some basic checks to make sure we are using our x86-elf cross-compiler correctly | ||
#if defined(__linux__) | ||
#error "This code must be compiled with a cross-compiler" | ||
#elif !defined(__i386__) | ||
#error "This code must be compiled with an x86-elf compiler" | ||
#endif | ||
|
||
// This is the x86's VGA textmode buffer. To display text, we write data to this memory location | ||
volatile uint16_t* vga_buffer = (uint16_t*)0xB8000; | ||
// By default, the VGA textmode buffer has a size of 80x25 characters | ||
const int cols = 80; | ||
const int rows = 25; | ||
|
||
// We start displaying text in the top-left of the screen (column = 0, row = 0) | ||
int term_col = 0; | ||
int term_row = 0; | ||
uint8_t term_color = 0x0F; // Black background, White foreground | ||
|
||
// This function initiates the terminal by clearing it | ||
void term_init() | ||
{ | ||
// Clear the textmode buffer | ||
for (int col = 0; col < cols; col ++) | ||
{ | ||
for (int row = 0; row < rows; row ++) | ||
{ | ||
// The VGA textmode buffer has size (cols * rows). | ||
// Given this, we find an index into the buffer for our character | ||
const size_t index = (cols * row) + col; | ||
// Entries in the VGA buffer take the binary form BBBBFFFFCCCCCCCC, where: | ||
// - B is the background color | ||
// - F is the foreground color | ||
// - C is the ASCII character | ||
vga_buffer[index] = ((uint16_t)term_color << 8) | ' '; // Set the character to blank (a space character) | ||
} | ||
} | ||
} | ||
|
||
// This function places a single character onto the screen | ||
void term_putc(char c) | ||
{ | ||
// Remember - we don't want to display ALL characters! | ||
switch (c) | ||
{ | ||
case '\n': // Newline characters should return the column to 0, and increment the row | ||
{ | ||
term_col = 0; | ||
term_row ++; | ||
break; | ||
} | ||
|
||
default: // Normal characters just get displayed and then increment the column | ||
{ | ||
const size_t index = (cols * term_row) + term_col; // Like before, calculate the buffer index | ||
vga_buffer[index] = ((uint16_t)term_color << 8) | c; | ||
term_col ++; | ||
break; | ||
} | ||
} | ||
|
||
// What happens if we get past the last column? We need to reset the column to 0, and increment the row to get to a new line | ||
if (term_col >= cols) | ||
{ | ||
term_col = 0; | ||
term_row ++; | ||
} | ||
|
||
// What happens if we get past the last row? We need to reset both column and row to 0 in order to loop back to the top of the screen | ||
if (term_row >= rows) | ||
{ | ||
term_col = 0; | ||
term_row = 0; | ||
} | ||
} | ||
|
||
// This function prints an entire string onto the screen | ||
void printf(const char* str) | ||
{ | ||
for (size_t i = 0; str[i] != '\0'; i ++) // Keep placing characters until we hit the null-terminating character ('\0') | ||
term_putc(str[i]); | ||
} | ||
|
||
|
||
|
||
// This is our kernel's main function | ||
void main() | ||
{ | ||
// We're here! Let's initiate the terminal and display a message to show we got here. | ||
|
||
// Initiate terminal | ||
term_init(); | ||
|
||
// Display some messages | ||
printf("Hello, World!\n"); | ||
printf("Welcome to the kernel.\n"); | ||
printf("\n"); | ||
printf("This is xeonos v0.5 Pre-Release Alpha Version (0.5-PR-A)"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* The bootloader will start execution at the symbol designated as the entry point. In this case, that's 'start' (defined in start.s) */ | ||
ENTRY(start) | ||
|
||
/* Tell the linker part of the compiler where the various sections of the kernel will be put in the final kernel executable. */ | ||
SECTIONS | ||
{ | ||
/* Begin putting sections at 1 Megabyte (1M), a good place for kernels to be loaded at by the bootloader. */ | ||
/* This is because memory below 1 Megabyte is reserved for other x86-related things, so we can't use it */ | ||
. = 1M; | ||
|
||
/* We align all sections in the executable at multiples of 4 Kilobytes (4K). This will become useful later in development when we add paging */ | ||
|
||
/* First put the multiboot header, as it's required to be near the start of the executable otherwise the bootloader won't find it */ | ||
/* The Multiboot header is Read-Only data, so we can put it in a '.rodata' section. */ | ||
.rodata BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(.multiboot) | ||
} | ||
|
||
/* Executable code */ | ||
.text BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(.text) | ||
} | ||
|
||
/* Read-only data. */ | ||
.rodata BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(.rodata) | ||
} | ||
|
||
/* Read-write data (initialized) */ | ||
.data BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(.data) | ||
} | ||
|
||
/* Read-write data (uninitialized) and stack */ | ||
.bss BLOCK(4K) : ALIGN(4K) | ||
{ | ||
*(COMMON) | ||
*(.bss) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/sh | ||
set -e | ||
. ./headers.sh | ||
|
||
for PROJECT in $PROJECTS; do | ||
(cd $PROJECT && DESTDIR="$SYSROOT" $MAKE install) | ||
done |
Oops, something went wrong.