rearraged files, set up to use grub bootloader
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,8 +1,11 @@
|
|||||||
*.iso
|
*.iso
|
||||||
isodir
|
*.img
|
||||||
sysroot
|
*.o
|
||||||
|
*.bin
|
||||||
|
*.elf
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
build
|
build
|
||||||
|
isodir
|
||||||
|
|||||||
14
boot/boot.ld
14
boot/boot.ld
@@ -1,14 +0,0 @@
|
|||||||
ENTRY(_start)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
. = 0x7C00;
|
|
||||||
|
|
||||||
.text : {
|
|
||||||
*(.text)
|
|
||||||
}
|
|
||||||
|
|
||||||
.data : {
|
|
||||||
*(.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
129
boot/boot.s
129
boot/boot.s
@@ -1,129 +0,0 @@
|
|||||||
.code16
|
|
||||||
.text
|
|
||||||
.global _start
|
|
||||||
_start:
|
|
||||||
ljmp $0x07C0, $something
|
|
||||||
|
|
||||||
something:
|
|
||||||
cli
|
|
||||||
cld
|
|
||||||
|
|
||||||
mov %cs, %ax
|
|
||||||
mov %ax, %ds
|
|
||||||
mov %ax, %es
|
|
||||||
|
|
||||||
# stack stuff
|
|
||||||
mov $0x0000, %ax
|
|
||||||
mov %ax, %ss
|
|
||||||
mov $0xFFF0, %sp
|
|
||||||
|
|
||||||
# copy the first 12 bytes of our MBR table entry
|
|
||||||
mov %dl, (disk_number)
|
|
||||||
mov $mbr_entry, %di
|
|
||||||
mov $12, %cx
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
mov $0, %ah
|
|
||||||
int $0x13
|
|
||||||
|
|
||||||
mov $0x08, %ah
|
|
||||||
int $0x13
|
|
||||||
and 0b00111111, %cl
|
|
||||||
mov %cl, (total_sectors)
|
|
||||||
mov %ch, (total_cylinders)
|
|
||||||
mov %dh, (total_heads)
|
|
||||||
|
|
||||||
mov $0x1000, %ax
|
|
||||||
mov %ax, %es
|
|
||||||
mov $0x0000, %bx
|
|
||||||
|
|
||||||
mov (disk_number), %dl
|
|
||||||
mov $0, %ch #cylinder
|
|
||||||
mov $0, %dh #head
|
|
||||||
mov $2, %cl #sector
|
|
||||||
|
|
||||||
load_sector:
|
|
||||||
mov $1, %al
|
|
||||||
mov $0x02, %ah
|
|
||||||
int $0x13
|
|
||||||
|
|
||||||
mov (kernel_sectors), %ax
|
|
||||||
cmp $0xffff, %ax
|
|
||||||
jne check_last_sector
|
|
||||||
mov %es:20, %eax
|
|
||||||
shr $9, %eax
|
|
||||||
inc %eax
|
|
||||||
|
|
||||||
check_last_sector:
|
|
||||||
dec %ax
|
|
||||||
mov %ax, kernel_sectors
|
|
||||||
cmp $0, %ax
|
|
||||||
je done
|
|
||||||
|
|
||||||
move: # inc our offset. If it hits 0, we've moved a segment, inc that too.
|
|
||||||
add $512, %bx
|
|
||||||
cmp $0, %bx
|
|
||||||
jnz read_next_sector
|
|
||||||
mov %es, %ax
|
|
||||||
add $1000, %ax
|
|
||||||
mov %ax, %es
|
|
||||||
|
|
||||||
read_next_sector: # find the next valid sector, head, cylinder combo on the disk
|
|
||||||
inc %cl
|
|
||||||
mov (total_sectors), %al
|
|
||||||
cmp %al, %cl
|
|
||||||
jle load_sector
|
|
||||||
mov $1, %cl #go back to sector 1.. of the next head
|
|
||||||
|
|
||||||
inc %dh #next head
|
|
||||||
mov (total_heads), %al
|
|
||||||
cmp %al, %dh
|
|
||||||
jle load_sector
|
|
||||||
mov $0, %dh # go back to head 0.. of the next cylinder
|
|
||||||
|
|
||||||
inc %ch # next cylinder
|
|
||||||
mov (total_cylinders), %al
|
|
||||||
cmp %al, %ch
|
|
||||||
jle load_sector
|
|
||||||
# no more disk... fall through
|
|
||||||
done:
|
|
||||||
mov $0, %ah
|
|
||||||
int $0x13
|
|
||||||
|
|
||||||
mov $0x1000, %ax
|
|
||||||
mov %ax, %ds
|
|
||||||
ljmp $0x1000, $0x0000
|
|
||||||
|
|
||||||
disk_number:
|
|
||||||
.byte 0
|
|
||||||
total_cylinders:
|
|
||||||
.byte 0
|
|
||||||
total_heads:
|
|
||||||
.byte 0
|
|
||||||
total_sectors:
|
|
||||||
.byte 0
|
|
||||||
|
|
||||||
kernel_sectors:
|
|
||||||
.word 0xFFFF
|
|
||||||
|
|
||||||
mbr_entry:
|
|
||||||
partition_status:
|
|
||||||
.byte 0
|
|
||||||
partition_start_chs:
|
|
||||||
.byte 0
|
|
||||||
.byte 0
|
|
||||||
.byte 0
|
|
||||||
partition_type:
|
|
||||||
.byte 0
|
|
||||||
partition_stop_chs:
|
|
||||||
.byte 0
|
|
||||||
.byte 0
|
|
||||||
.byte 0
|
|
||||||
partition_start_lba:
|
|
||||||
.long 0
|
|
||||||
partition_start_length:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
.org 510
|
|
||||||
magic:
|
|
||||||
.word 0xAA55
|
|
||||||
@@ -1,45 +1,19 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"file": "boot.s",
|
"file": "kernel/kmain.c",
|
||||||
"arguments": [
|
"arguments": [
|
||||||
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
"-m32",
|
|
||||||
"-c",
|
"-c",
|
||||||
"boot.s",
|
"kernel/kmain.c",
|
||||||
"-o",
|
"-o",
|
||||||
"boot.o"
|
"obj/kernel/kmain.o",
|
||||||
],
|
|
||||||
"directory": "/home/slinky/source/RockOS",
|
|
||||||
"output": "boot.o"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"file": "prekernel.s",
|
|
||||||
"arguments": [
|
|
||||||
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
|
||||||
"-m32",
|
|
||||||
"-c",
|
|
||||||
"prekernel.s",
|
|
||||||
"-o",
|
|
||||||
"prekernel.o"
|
|
||||||
],
|
|
||||||
"directory": "/home/slinky/source/RockOS",
|
|
||||||
"output": "prekernel.o"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"file": "kmain.c",
|
|
||||||
"arguments": [
|
|
||||||
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
|
||||||
"-m32",
|
|
||||||
"-ffreestanding",
|
"-ffreestanding",
|
||||||
"-O2",
|
"-O2",
|
||||||
"-Wall",
|
"-Wall",
|
||||||
"-Wextra",
|
"-Wextra",
|
||||||
"-c",
|
"-Ikernel"
|
||||||
"kmain.c",
|
|
||||||
"-o",
|
|
||||||
"kmain.o"
|
|
||||||
],
|
],
|
||||||
"directory": "/home/slinky/source/RockOS",
|
"directory": "/home/slinky/source/RockOS",
|
||||||
"output": "kmain.o"
|
"output": "obj/kernel/kmain.o"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
28
kernel/boot/boot.s
Normal file
28
kernel/boot/boot.s
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
.set ALIGN, 1<<0 /* align loaded modules on page boundaries */
|
||||||
|
.set MEMINFO, 1<<1 /* provide memory map */
|
||||||
|
.set FLAGS, ALIGN | MEMINFO /* this is the Multiboot 'flag' field */
|
||||||
|
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
|
||||||
|
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
|
||||||
|
|
||||||
|
.section .multiboot
|
||||||
|
.align 4
|
||||||
|
.long MAGIC
|
||||||
|
.long FLAGS
|
||||||
|
.long CHECKSUM
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
.align 16
|
||||||
|
stack_bottom:
|
||||||
|
.skip 16384 # 16 KiB
|
||||||
|
stack_top:
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
.global _start
|
||||||
|
.type _start, @function
|
||||||
|
_start:
|
||||||
|
mov $stack_top, %esp
|
||||||
|
call kernel_main
|
||||||
|
|
||||||
|
cli
|
||||||
|
1: hlt
|
||||||
|
jmp 1b
|
||||||
72
kernel/drivers/vga_stream_writer.c
Normal file
72
kernel/drivers/vga_stream_writer.c
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <lib/stream.h>
|
||||||
|
|
||||||
|
#define VGA_WIDTH 80
|
||||||
|
#define VGA_HEIGHT 25
|
||||||
|
#define VGA_MEMORY 0xB8000
|
||||||
|
|
||||||
|
enum vga_color {
|
||||||
|
VGA_COLOR_BLACK = 0,
|
||||||
|
VGA_COLOR_BLUE = 1,
|
||||||
|
VGA_COLOR_GREEN = 2,
|
||||||
|
VGA_COLOR_CYAN = 3,
|
||||||
|
VGA_COLOR_RED = 4,
|
||||||
|
VGA_COLOR_MAGENTA = 5,
|
||||||
|
VGA_COLOR_BROWN = 6,
|
||||||
|
VGA_COLOR_LIGHT_GREY = 7,
|
||||||
|
VGA_COLOR_DARK_GREY = 8,
|
||||||
|
VGA_COLOR_LIGHT_BLUE = 9,
|
||||||
|
VGA_COLOR_LIGHT_GREEN = 10,
|
||||||
|
VGA_COLOR_LIGHT_CYAN = 11,
|
||||||
|
VGA_COLOR_LIGHT_RED = 12,
|
||||||
|
VGA_COLOR_LIGHT_MAGENTA = 13,
|
||||||
|
VGA_COLOR_LIGHT_BROWN = 14,
|
||||||
|
VGA_COLOR_WHITE = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t terminal_row;
|
||||||
|
size_t terminal_column;
|
||||||
|
uint8_t terminal_color;
|
||||||
|
uint16_t* terminal_buffer = (uint16_t*)VGA_MEMORY;
|
||||||
|
|
||||||
|
static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg)
|
||||||
|
{
|
||||||
|
return fg | bg << 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t vga_entry(unsigned char uc, uint8_t color)
|
||||||
|
{
|
||||||
|
return (uint16_t) uc | (uint16_t) color << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_initialize()
|
||||||
|
{
|
||||||
|
terminal_row = 0;
|
||||||
|
terminal_column = 0;
|
||||||
|
terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
|
||||||
|
|
||||||
|
for (size_t y = 0; y < VGA_HEIGHT; y++) {
|
||||||
|
for (size_t x = 0; x < VGA_WIDTH; x++) {
|
||||||
|
const size_t index = y * VGA_WIDTH + x;
|
||||||
|
terminal_buffer[index] = vga_entry(' ', terminal_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_putchar(char c)
|
||||||
|
{
|
||||||
|
const size_t index = terminal_row * VGA_WIDTH + terminal_column;
|
||||||
|
terminal_buffer[index] = vga_entry(c, terminal_color);
|
||||||
|
if (++terminal_column == VGA_WIDTH) {
|
||||||
|
terminal_column = 0;
|
||||||
|
if (++terminal_row == VGA_HEIGHT)
|
||||||
|
terminal_row = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_stream_t vga_print_stream = {
|
||||||
|
.putchar = vga_putchar,
|
||||||
|
.trunc = vga_initialize,
|
||||||
|
};
|
||||||
62
kernel/gdt.c
Normal file
62
kernel/gdt.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SEG_DESCTYPE(x) ((x) << 0x04) // Descriptor type (0 for system, 1 for code/data)
|
||||||
|
#define SEG_PRES(x) ((x) << 0x07) // Present
|
||||||
|
#define SEG_SAVL(x) ((x) << 0x0C) // Available for system use
|
||||||
|
#define SEG_LONG(x) ((x) << 0x0D) // Long mode
|
||||||
|
#define SEG_SIZE(x) ((x) << 0x0E) // Size (0 for 16-bit, 1 for 32)
|
||||||
|
#define SEG_GRAN(x) ((x) << 0x0F) // Granularity (0 for 1B - 1MB, 1 for 4KB - 4GB)
|
||||||
|
#define SEG_PRIV(x) (((x) & 0x03) << 0x05) // Set privilege level (0 - 3)
|
||||||
|
|
||||||
|
#define SEG_DATA_RD 0x00 // Read-Only
|
||||||
|
#define SEG_DATA_RDA 0x01 // Read-Only, accessed
|
||||||
|
#define SEG_DATA_RDWR 0x02 // Read/Write
|
||||||
|
#define SEG_DATA_RDWRA 0x03 // Read/Write, accessed
|
||||||
|
#define SEG_DATA_RDEXPD 0x04 // Read-Only, expand-down
|
||||||
|
#define SEG_DATA_RDEXPDA 0x05 // Read-Only, expand-down, accessed
|
||||||
|
#define SEG_DATA_RDWREXPD 0x06 // Read/Write, expand-down
|
||||||
|
#define SEG_DATA_RDWREXPDA 0x07 // Read/Write, expand-down, accessed
|
||||||
|
#define SEG_CODE_EX 0x08 // Execute-Only
|
||||||
|
#define SEG_CODE_EXA 0x09 // Execute-Only, accessed
|
||||||
|
#define SEG_CODE_EXRD 0x0A // Execute/Read
|
||||||
|
#define SEG_CODE_EXRDA 0x0B // Execute/Read, accessed
|
||||||
|
#define SEG_CODE_EXC 0x0C // Execute-Only, conforming
|
||||||
|
#define SEG_CODE_EXCA 0x0D // Execute-Only, conforming, accessed
|
||||||
|
#define SEG_CODE_EXRDC 0x0E // Execute/Read, conforming
|
||||||
|
#define SEG_CODE_EXRDCA 0x0F // Execute/Read, conforming, accessed
|
||||||
|
|
||||||
|
#define GDT_CODE_PL0 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
|
||||||
|
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
|
||||||
|
SEG_PRIV(0) | SEG_CODE_EXRD
|
||||||
|
|
||||||
|
#define GDT_DATA_PL0 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
|
||||||
|
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
|
||||||
|
SEG_PRIV(0) | SEG_DATA_RDWR
|
||||||
|
|
||||||
|
#define GDT_CODE_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
|
||||||
|
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
|
||||||
|
SEG_PRIV(3) | SEG_CODE_EXRD
|
||||||
|
|
||||||
|
#define GDT_DATA_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
|
||||||
|
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
|
||||||
|
SEG_PRIV(3) | SEG_DATA_RDWR
|
||||||
|
|
||||||
|
uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag)
|
||||||
|
{
|
||||||
|
uint64_t descriptor;
|
||||||
|
|
||||||
|
// Create the high 32 bit segment
|
||||||
|
descriptor = limit & 0x000F0000; // set limit bits 19:16
|
||||||
|
descriptor |= (flag << 8) & 0x00F0FF00; // set type, p, dpl, s, g, d/b, l and avl fields
|
||||||
|
descriptor |= (base >> 16) & 0x000000FF; // set base bits 23:16
|
||||||
|
descriptor |= base & 0xFF000000; // set base bits 31:24
|
||||||
|
|
||||||
|
// Shift by 32 to allow for low part of segment
|
||||||
|
descriptor <<= 32;
|
||||||
|
|
||||||
|
// Create the low 32 bit segment
|
||||||
|
descriptor |= base << 16; // set base bits 15:0
|
||||||
|
descriptor |= limit & 0x0000FFFF; // set limit bits 15:0
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
3
kernel/globals.c
Normal file
3
kernel/globals.c
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#include <lib/stream.h>
|
||||||
|
|
||||||
|
print_stream_t* kout;
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
ENTRY(_start)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
. = 0x10000;
|
|
||||||
|
|
||||||
.text : {
|
|
||||||
*(.text)
|
|
||||||
}
|
|
||||||
|
|
||||||
.rodata : {
|
|
||||||
*(.rodata)
|
|
||||||
}
|
|
||||||
|
|
||||||
.data : {
|
|
||||||
*(.data)
|
|
||||||
}
|
|
||||||
|
|
||||||
.bss : {
|
|
||||||
*(.bss)
|
|
||||||
}
|
|
||||||
|
|
||||||
_end = .;
|
|
||||||
}
|
|
||||||
@@ -1,28 +1,12 @@
|
|||||||
#include <stdint.h>
|
#include <lib/print.h>
|
||||||
|
#include <lib/stream.h>
|
||||||
|
|
||||||
extern void halt();
|
void kernel_main(void)
|
||||||
extern void idt_load();
|
{
|
||||||
extern void reboot();
|
extern print_stream_t vga_print_stream;
|
||||||
|
extern print_stream_t* kout;
|
||||||
|
kout = &vga_print_stream;
|
||||||
|
kout->trunc();
|
||||||
|
|
||||||
typedef struct {
|
kprint("RockOS booting...");
|
||||||
uint16_t offset_low;
|
|
||||||
uint16_t selector;
|
|
||||||
uint8_t zero;
|
|
||||||
uint8_t flags;
|
|
||||||
uint16_t offset_high;
|
|
||||||
} idt_entry_t __attribute__((packed));
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t limit;
|
|
||||||
uint32_t base;
|
|
||||||
} idt_ptr_t;
|
|
||||||
|
|
||||||
idt_entry_t idt[256];
|
|
||||||
idt_ptr_t idtr;
|
|
||||||
|
|
||||||
void load_idt() {}
|
|
||||||
|
|
||||||
void kmain() {
|
|
||||||
load_idt();
|
|
||||||
halt();
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
kernel/lib/print.c
Normal file
11
kernel/lib/print.c
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include "print.h"
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
extern print_stream_t* kout;
|
||||||
|
|
||||||
|
void kprint(const char *str) {
|
||||||
|
while (*str) {
|
||||||
|
kout->putchar(*str);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
kernel/lib/print.h
Normal file
6
kernel/lib/print.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef KLIBPRINT_H
|
||||||
|
#define KLIBPRINT_H
|
||||||
|
|
||||||
|
void kprint(const char* str);
|
||||||
|
|
||||||
|
#endif
|
||||||
3
kernel/lib/stream.c
Normal file
3
kernel/lib/stream.c
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
print_stream_t* pout;
|
||||||
9
kernel/lib/stream.h
Normal file
9
kernel/lib/stream.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef KSTREAM_H
|
||||||
|
#define KSTREAM_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void (*putchar)(char c);
|
||||||
|
void (*trunc)();
|
||||||
|
} print_stream_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
28
kernel/linker.ld
Normal file
28
kernel/linker.ld
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 2M;
|
||||||
|
|
||||||
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.multiboot)
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.rodata)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(COMMON)
|
||||||
|
*(.bss)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
.code16
|
|
||||||
.text
|
|
||||||
.global _start
|
|
||||||
_start:
|
|
||||||
jmp everything
|
|
||||||
|
|
||||||
.org 20
|
|
||||||
.global kernel_size
|
|
||||||
kernel_size:
|
|
||||||
.long _end - _start
|
|
||||||
|
|
||||||
everything:
|
|
||||||
mov $0x1000, %ax
|
|
||||||
mov %ax, %es
|
|
||||||
mov %ax, %ds
|
|
||||||
|
|
||||||
# reset disk
|
|
||||||
mov $0, %ah
|
|
||||||
int $0x13
|
|
||||||
|
|
||||||
# stop the cursor
|
|
||||||
mov $1, %ah
|
|
||||||
mov $0,%cl
|
|
||||||
mov $0x20,%ch
|
|
||||||
int $0x11
|
|
||||||
|
|
||||||
# get the system memory, if this call fails then halt
|
|
||||||
clc
|
|
||||||
mov $0, %bx
|
|
||||||
mov $0xe801, %ax
|
|
||||||
int $0x15
|
|
||||||
jc halt
|
|
||||||
shr $10, %ax
|
|
||||||
shr $4, %bx
|
|
||||||
add %ax, %bx
|
|
||||||
mov %bx, total_mem_mb-_start
|
|
||||||
|
|
||||||
# vga text mode
|
|
||||||
mov $0x0003, %ax
|
|
||||||
int $0x10
|
|
||||||
|
|
||||||
enable_a20:
|
|
||||||
#enable the a20 gate
|
|
||||||
inb $0x92, %al
|
|
||||||
orb $2, %al
|
|
||||||
outb %al, $0x92
|
|
||||||
prep_protected:
|
|
||||||
cli
|
|
||||||
lgdt gdt_init-_start
|
|
||||||
mov %cr0, %eax
|
|
||||||
or $0x01, %eax
|
|
||||||
mov %eax, %cr0 # protected bit set
|
|
||||||
ljmpl $8, $protected
|
|
||||||
|
|
||||||
halt16:
|
|
||||||
jmp halt16
|
|
||||||
|
|
||||||
.code32
|
|
||||||
protected:
|
|
||||||
mov $16, %ax
|
|
||||||
mov %ax, %es
|
|
||||||
mov %ax, %ds
|
|
||||||
mov %ax, %ss
|
|
||||||
mov $5*8, %ax
|
|
||||||
ltr %ax
|
|
||||||
mov $0, %ax
|
|
||||||
mov %ax, %fs
|
|
||||||
mov %ax, %gs
|
|
||||||
mov $0xFFF0, %sp
|
|
||||||
mov $0xFFF0, %bp
|
|
||||||
ljmpl $8, $kmain
|
|
||||||
|
|
||||||
# some assembly stubs we can call from the kernel
|
|
||||||
|
|
||||||
.global idt_load
|
|
||||||
.extern idtr
|
|
||||||
idt_load:
|
|
||||||
lidt idtr
|
|
||||||
ret
|
|
||||||
|
|
||||||
.global reboot
|
|
||||||
reboot:
|
|
||||||
cli
|
|
||||||
lidt reboot_struct
|
|
||||||
int $1
|
|
||||||
reboot_struct:
|
|
||||||
.word 0
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
.global halt
|
|
||||||
halt:
|
|
||||||
cli
|
|
||||||
hlt
|
|
||||||
jmp halt
|
|
||||||
|
|
||||||
# kernel data structures
|
|
||||||
|
|
||||||
.align 16
|
|
||||||
.global gdt
|
|
||||||
gdt:
|
|
||||||
.word 0,0,0,0
|
|
||||||
.word 0xffff, 0x0000, 0x9a00, 0x00cf
|
|
||||||
.word 0xffff, 0x0000, 0x9200, 0x00cf
|
|
||||||
.word 0xffff, 0x0000, 0xfa00, 0x00cf
|
|
||||||
.word 0xffff, 0x0000, 0xf200, 0x00cf
|
|
||||||
.word 0x0068, (tss-_start), 0x8901, 0x00cf
|
|
||||||
gdt_init:
|
|
||||||
.word gdt_init-gdt
|
|
||||||
.long gdt
|
|
||||||
|
|
||||||
.align 16
|
|
||||||
.global tss
|
|
||||||
tss:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
.global total_mem_mb
|
|
||||||
total_mem_mb:
|
|
||||||
.word 0
|
|
||||||
65
makefile
65
makefile
@@ -1,55 +1,38 @@
|
|||||||
CC = i686-elf-gcc
|
CC = i686-elf-gcc
|
||||||
LD = i686-elf-ld
|
LD = i686-elf-ld
|
||||||
OBJCOPY = i686-elf-objcopy
|
|
||||||
|
|
||||||
CFLAGS = -m32 -ffreestanding -O2 -Wall -Wextra -nostdlib
|
OSNAME := rockos
|
||||||
ASFLAGS = -m32
|
|
||||||
|
|
||||||
BOOT_DIR := boot
|
C_SOURCES := $(shell find kernel -type f -name '*.c')
|
||||||
KERNEL_DIR := kernel
|
S_SOURCES := $(shell find kernel -type f -name '*.s')
|
||||||
BUILD_DIR := build
|
|
||||||
|
|
||||||
BOOT_BIN := $(BUILD_DIR)/boot.bin
|
OBJECTS := $(patsubst %.c, obj/%.o, $(C_SOURCES)) $(patsubst %.s, obj/%.o, $(S_SOURCES))
|
||||||
KERNEL_BIN := $(BUILD_DIR)/kernel.bin
|
|
||||||
IMAGE := os.img
|
|
||||||
|
|
||||||
.PHONY: all clean run
|
CFLAGS := -ffreestanding -O2 -Wall -Wextra -Ikernel
|
||||||
|
LDFLAGS := -T kernel/linker.ld
|
||||||
|
|
||||||
all: $(IMAGE)
|
.PHONY: all run clean
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(BOOT_DIR)/%.s | $(BUILD_DIR)
|
$(OSNAME).bin: $(OBJECTS)
|
||||||
$(CC) $(ASFLAGS) -c $< -o $@
|
$(LD) $(LDFLAGS) -o $@ $(OBJECTS)
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(KERNEL_DIR)/%.s | $(BUILD_DIR)
|
$(OSNAME).iso: $(OSNAME).bin grub.cfg
|
||||||
$(CC) $(ASFLAGS) -c $< -o $@
|
mkdir -p isodir/boot/grub
|
||||||
|
cp $(OSNAME).bin isodir/boot/$(OSNAME)
|
||||||
|
cp grub.cfg isodir/boot/grub/grub.cfg
|
||||||
|
grub-mkrescue -o $(OSNAME).iso isodir
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: $(KERNEL_DIR)/%.c | $(BUILD_DIR)
|
obj/%.o: %.c
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) -c $< -o $@ $(CFLAGS)
|
||||||
|
|
||||||
$(BUILD_DIR)/boot.elf: $(BUILD_DIR)/boot.o $(BOOT_DIR)/boot.ld
|
obj/%.o: %.s
|
||||||
$(LD) -T $(BOOT_DIR)/boot.ld -o $@ $(BUILD_DIR)/boot.o
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) -c $< -o $@ $(CFLAGS)
|
||||||
|
|
||||||
$(BOOT_BIN): $(BUILD_DIR)/boot.elf
|
run: $(OSNAME).iso
|
||||||
$(OBJCOPY) -O binary $< $@
|
qemu-system-i386 -cdrom $(OSNAME).iso
|
||||||
|
|
||||||
KERNEL_OBJS := $(BUILD_DIR)/prekernel.o $(BUILD_DIR)/kmain.o
|
|
||||||
|
|
||||||
$(BUILD_DIR)/kernel.elf: $(KERNEL_OBJS) $(KERNEL_DIR)/kernel.ld
|
|
||||||
$(LD) -T $(KERNEL_DIR)/kernel.ld -o $@ $(KERNEL_OBJS)
|
|
||||||
|
|
||||||
$(KERNEL_BIN): $(BUILD_DIR)/kernel.elf
|
|
||||||
$(OBJCOPY) -O binary $< $@
|
|
||||||
|
|
||||||
$(BUILD_DIR):
|
|
||||||
mkdir -p $(BUILD_DIR)
|
|
||||||
|
|
||||||
$(IMAGE): $(BOOT_BIN) $(KERNEL_BIN)
|
|
||||||
dd if=$(BOOT_BIN) of=$@ bs=512 count=1
|
|
||||||
dd if=$(KERNEL_BIN) of=$@ bs=512 seek=1
|
|
||||||
truncate -s 1440k $@
|
|
||||||
|
|
||||||
run: $(IMAGE)
|
|
||||||
qemu-system-i386 -drive format=raw,file=$(IMAGE)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR) $(IMAGE)
|
@echo "Cleaning up build artifacts..."
|
||||||
|
rm -rf $(OSNAME).iso $(OSNAME).bin obj isodir
|
||||||
Reference in New Issue
Block a user