Skip to content
This repository has been archived by the owner on Jun 4, 2022. It is now read-only.

Commit

Permalink
XeonOS source uploaded
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexDev404 authored Oct 19, 2019
1 parent 9a3d0cb commit 95a2d8b
Show file tree
Hide file tree
Showing 92 changed files with 1,289 additions and 0 deletions.
Binary file added XeonOSv0.5.elf
Binary file not shown.
Binary file added build/v0.5/isoroot/boot/XeonOSv0.5.elf
Binary file not shown.
4 changes: 4 additions & 0 deletions build/v0.5/isoroot/boot/grub/grub.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
menuentry "XeonOS v0.5" {
multiboot /boot/XeonOSv0.5.elf
boot
}
103 changes: 103 additions & 0 deletions build/v0.5/source/kernel.c
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 added build/v0.5/source/kernel.o
Binary file not shown.
44 changes: 44 additions & 0 deletions build/v0.5/source/linker.ld
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 added build/v0.5/source/pre-built/XeonOSv0.5.elf
Binary file not shown.
Binary file added build/v0.5/source/pre-built/kernel.iso
Binary file not shown.
Binary file added build/v0.5/source/start.o
Binary file not shown.
74 changes: 74 additions & 0 deletions build/v0.5/source/start.s
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 added build/v0.9/isoroot/boot/avis.kernel
Binary file not shown.
3 changes: 3 additions & 0 deletions build/v0.9/isoroot/boot/grub/grub.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
menuentry "XeonOSv0.9" {
multiboot /boot/avis.kernel
}
Binary file added build/v0.9/pre-built/xeonos.iso
Binary file not shown.
103 changes: 103 additions & 0 deletions kernel.c
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 added kernel.o
Binary file not shown.
44 changes: 44 additions & 0 deletions linker.ld
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)
}
}
7 changes: 7 additions & 0 deletions meaty-skeleton/build.sh
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
Loading

0 comments on commit 95a2d8b

Please sign in to comment.