Compare commits
3 Commits
b860e3bdff
...
master
Author | SHA1 | Date | |
---|---|---|---|
82056c0ead
|
|||
79a4f79a24 | |||
ad929efeb2 |
63
Dockerfile
Normal file
63
Dockerfile
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
ARG BINUTILS_VERSION=2.44
|
||||||
|
ARG GCC_VERSION=14.2.0
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
bison \
|
||||||
|
flex \
|
||||||
|
grub-pc-bin \
|
||||||
|
grub-efi-amd64-bin \
|
||||||
|
mtools qemu-system-x86 \
|
||||||
|
grub2 \
|
||||||
|
libgmp3-dev \
|
||||||
|
libmpc-dev \
|
||||||
|
libmpfr-dev \
|
||||||
|
libisl-dev \
|
||||||
|
libelf-dev \
|
||||||
|
wget
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PREFIX=/usr/local/opt/cross
|
||||||
|
ENV TARGET=i686-elf
|
||||||
|
ENV PATH="$PREFIX/bin:$PATH"
|
||||||
|
|
||||||
|
# Create build directory
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
# Download and extract sources
|
||||||
|
RUN wget https://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.gz && \
|
||||||
|
wget https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.gz && \
|
||||||
|
tar -xzf binutils-${BINUTILS_VERSION}.tar.gz && \
|
||||||
|
tar -xzf gcc-${GCC_VERSION}.tar.gz
|
||||||
|
|
||||||
|
RUN mkdir -p $PREFIX
|
||||||
|
|
||||||
|
# Build Binutils
|
||||||
|
RUN mkdir binutils-build && \
|
||||||
|
cd binutils-build && \
|
||||||
|
../binutils-${BINUTILS_VERSION}/configure --target=${TARGET} --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror && \
|
||||||
|
make && \
|
||||||
|
make install
|
||||||
|
|
||||||
|
# Build GCC
|
||||||
|
RUN mkdir gcc-build && \
|
||||||
|
cd gcc-build && \
|
||||||
|
../gcc-${GCC_VERSION}/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers --disable-hosted-libstdcxx && \
|
||||||
|
make all-gcc && \
|
||||||
|
make all-target-libgcc && \
|
||||||
|
make install-gcc && \
|
||||||
|
make install-target-libgcc
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
RUN rm -rf /build
|
||||||
|
|
||||||
|
# Check if the installation is successful
|
||||||
|
RUN $PREFIX/bin/$TARGET-gcc --version
|
||||||
|
|
||||||
|
RUN apt-get install -y xorriso
|
||||||
|
|
||||||
|
VOLUME /var/lib/deados
|
||||||
|
|
||||||
|
WORKDIR /var/lib/deados
|
8
Makefile
8
Makefile
@@ -16,7 +16,7 @@ OBJECTS = $(SOURCES_ASM:.s=.o) $(SOURCES_C:.c=.o)
|
|||||||
ISO_DIR = isodir
|
ISO_DIR = isodir
|
||||||
GRUB_DIR = $(ISO_DIR)/boot/grub
|
GRUB_DIR = $(ISO_DIR)/boot/grub
|
||||||
|
|
||||||
.PHONY: all clean iso
|
.PHONY: all clean iso docker-build docker-make
|
||||||
|
|
||||||
all: $(ISO)
|
all: $(ISO)
|
||||||
|
|
||||||
@@ -43,3 +43,9 @@ check-multiboot: $(KERNEL)
|
|||||||
clean:
|
clean:
|
||||||
rm -f $(OBJECTS) $(KERNEL) $(ISO)
|
rm -f $(OBJECTS) $(KERNEL) $(ISO)
|
||||||
rm -rf $(ISO_DIR)
|
rm -rf $(ISO_DIR)
|
||||||
|
|
||||||
|
docker-build:
|
||||||
|
docker build --progress=plain -t deados_builder .
|
||||||
|
|
||||||
|
docker-make:
|
||||||
|
docker run -it -v $(shell pwd):/var/lib/deados deados_builder bash -c "cd /var/lib/deados && make"
|
||||||
|
@@ -34,4 +34,5 @@ DeadOS is a minimalist operating system designed for x86 architecture, created s
|
|||||||
|
|
||||||
## Screenshot:
|
## Screenshot:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
17
boot.s
17
boot.s
@@ -1,7 +1,7 @@
|
|||||||
.set ALIGN, 1<<0
|
.set ALIGN, 1<<0
|
||||||
.set MEMINFO, 1<<1
|
.set MEMINFO, 1<<1
|
||||||
.set FLAGS, ALIGN | MEMINFO
|
.set FLAGS, ALIGN | MEMINFO
|
||||||
.set MAGIC, 0x1BADB002 /* multiboot 1 */
|
.set MAGIC, 0x1BADB002
|
||||||
.set CHECKSUM, -(MAGIC + FLAGS)
|
.set CHECKSUM, -(MAGIC + FLAGS)
|
||||||
|
|
||||||
.section .multiboot
|
.section .multiboot
|
||||||
@@ -10,7 +10,9 @@
|
|||||||
.long FLAGS
|
.long FLAGS
|
||||||
.long CHECKSUM
|
.long CHECKSUM
|
||||||
|
|
||||||
.section .stack, "aw", @nobits
|
.section .bss
|
||||||
|
.align 16
|
||||||
|
.global stack_bottom
|
||||||
.global stack_top
|
.global stack_top
|
||||||
stack_bottom:
|
stack_bottom:
|
||||||
.skip 16384
|
.skip 16384
|
||||||
@@ -22,8 +24,15 @@ stack_top:
|
|||||||
_start:
|
_start:
|
||||||
movl $stack_top, %esp
|
movl $stack_top, %esp
|
||||||
|
|
||||||
push %ebx
|
pushl $0
|
||||||
|
popf
|
||||||
|
|
||||||
|
pushl %ebx
|
||||||
|
|
||||||
call kernel_main
|
call kernel_main
|
||||||
1:
|
|
||||||
|
cli
|
||||||
|
1: hlt
|
||||||
jmp 1b
|
jmp 1b
|
||||||
|
|
||||||
|
.size _start, . - _start
|
36
gdt.c
36
gdt.c
@@ -25,39 +25,45 @@ static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t acc
|
|||||||
gdt[num].access = access;
|
gdt[num].access = access;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tss_install(uint8_t num, uint16_t kernel_ss, uint16_t kernel_esp)
|
void tss_install(uint8_t num, uint16_t kernel_ss, uint16_t kernel_esp)
|
||||||
{
|
{
|
||||||
uint32_t base = (uint32_t)&tss;
|
uint32_t base = (uint32_t)&tss;
|
||||||
uint32_t limit = base + sizeof(Tss_entry);
|
uint32_t limit = sizeof(Tss_entry);
|
||||||
|
|
||||||
gdt_set_gate(num, base, limit, 0xE9, 0x0);
|
|
||||||
|
|
||||||
memset(&tss, 0, sizeof(Tss_entry));
|
memset(&tss, 0, sizeof(Tss_entry));
|
||||||
|
|
||||||
tss.ss0 = kernel_ss;
|
tss.ss0 = kernel_ss;
|
||||||
tss.esp0 = kernel_esp + 0x1000; // SHIT
|
tss.esp0 = kernel_esp;
|
||||||
|
|
||||||
tss.cs = 0x1B;
|
tss.cs = 0x1b;
|
||||||
tss.ss = 0x23;
|
tss.ss = 0x23;
|
||||||
tss.es = 0x23;
|
|
||||||
tss.ds = 0x23;
|
tss.ds = 0x23;
|
||||||
|
tss.es = 0x23;
|
||||||
tss.fs = 0x23;
|
tss.fs = 0x23;
|
||||||
tss.gs = 0x23;
|
tss.gs = 0x23;
|
||||||
|
|
||||||
|
tss.iopb_off = sizeof(Tss_entry);
|
||||||
|
|
||||||
|
gdt_set_gate(num, base, limit, I86_GDT_DESC_ACCESS | I86_GDT_DESC_EXEC_CODE | I86_GDT_DESC_DPL | I86_GDT_DESC_MEMORY, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gdt_install()
|
void gdt_install()
|
||||||
{
|
{
|
||||||
gdt_set_gate(0, 0x0, 0x0, 0x0, 0x0); // Null segment
|
|
||||||
gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xCF); // 0x08 Kernel code segment
|
|
||||||
gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xCF); // 0x10 Kernel Data segment
|
|
||||||
gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xCF); // 0x18 User code segment
|
|
||||||
gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xCF); // 0x20 User data segment
|
|
||||||
|
|
||||||
tss_install(5, 0x10, stack_top);
|
|
||||||
|
|
||||||
gdtp.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1;
|
gdtp.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1;
|
||||||
gdtp.base = (uint32_t)&gdt;
|
gdtp.base = (uint32_t)&gdt;
|
||||||
|
|
||||||
|
gdt_set_gate(0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||||
|
|
||||||
|
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||||
|
|
||||||
|
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
||||||
|
|
||||||
|
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
||||||
|
|
||||||
|
tss_install(5, 0x10, (uint32_t)&stack_top);
|
||||||
|
|
||||||
gdt_flush((uint32_t)&gdtp);
|
gdt_flush((uint32_t)&gdtp);
|
||||||
tss_flush();
|
tss_flush();
|
||||||
}
|
}
|
||||||
|
38
gdt.h
38
gdt.h
@@ -3,7 +3,42 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern uint32_t stack_top;
|
extern void* stack_top;
|
||||||
|
|
||||||
|
//! set access bit
|
||||||
|
#define I86_GDT_DESC_ACCESS 0x0001 //00000001
|
||||||
|
|
||||||
|
//! descriptor is readable and writable. default: read only
|
||||||
|
#define I86_GDT_DESC_READWRITE 0x0002 //00000010
|
||||||
|
|
||||||
|
//! set expansion direction bit
|
||||||
|
#define I86_GDT_DESC_EXPANSION 0x0004 //00000100
|
||||||
|
|
||||||
|
//! executable code segment. Default: data segment
|
||||||
|
#define I86_GDT_DESC_EXEC_CODE 0x0008 //00001000
|
||||||
|
|
||||||
|
//! set code or data descriptor. defult: system defined descriptor
|
||||||
|
#define I86_GDT_DESC_CODEDATA 0x0010 //00010000
|
||||||
|
|
||||||
|
//! set dpl bits
|
||||||
|
#define I86_GDT_DESC_DPL 0x0060 //01100000
|
||||||
|
|
||||||
|
//! set "in memory" bit
|
||||||
|
#define I86_GDT_DESC_MEMORY 0x0080 //10000000
|
||||||
|
|
||||||
|
/** gdt descriptor grandularity bit flags ***/
|
||||||
|
|
||||||
|
//! masks out limitHi (High 4 bits of limit)
|
||||||
|
#define I86_GDT_GRAND_LIMITHI_MASK 0x0f //00001111
|
||||||
|
|
||||||
|
//! set os defined bit
|
||||||
|
#define I86_GDT_GRAND_OS 0x10 //00010000
|
||||||
|
|
||||||
|
//! set if 32bit. default: 16 bit
|
||||||
|
#define I86_GDT_GRAND_32BIT 0x40 //01000000
|
||||||
|
|
||||||
|
//! 4k grandularity. default: none
|
||||||
|
#define I86_GDT_GRAND_4K 0x80 //10000000
|
||||||
|
|
||||||
typedef struct gdt_entry_t Gdt_entry;
|
typedef struct gdt_entry_t Gdt_entry;
|
||||||
struct gdt_entry_t
|
struct gdt_entry_t
|
||||||
@@ -58,6 +93,7 @@ struct tss_entry_t
|
|||||||
uint32_t ldt;
|
uint32_t ldt;
|
||||||
uint16_t trap;
|
uint16_t trap;
|
||||||
uint16_t iomap;
|
uint16_t iomap;
|
||||||
|
uint16_t iopb_off;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
#endif
|
#endif
|
32
irq.c
32
irq.c
@@ -62,22 +62,22 @@ void irq_install(void)
|
|||||||
{
|
{
|
||||||
irq_remap();
|
irq_remap();
|
||||||
|
|
||||||
idt_set_gate(32, (uint32_t)irq0, 0x08, 0x8E);
|
idt_set_gate(32, (uint32_t)irq0, 0x08, 0xEE);
|
||||||
idt_set_gate(33, (uint32_t)irq1, 0x08, 0x8E);
|
idt_set_gate(33, (uint32_t)irq1, 0x08, 0xEE);
|
||||||
idt_set_gate(34, (uint32_t)irq2, 0x08, 0x8E);
|
idt_set_gate(34, (uint32_t)irq2, 0x08, 0xEE);
|
||||||
idt_set_gate(35, (uint32_t)irq3, 0x08, 0x8E);
|
idt_set_gate(35, (uint32_t)irq3, 0x08, 0xEE);
|
||||||
idt_set_gate(36, (uint32_t)irq4, 0x08, 0x8E);
|
idt_set_gate(36, (uint32_t)irq4, 0x08, 0xEE);
|
||||||
idt_set_gate(37, (uint32_t)irq5, 0x08, 0x8E);
|
idt_set_gate(37, (uint32_t)irq5, 0x08, 0xEE);
|
||||||
idt_set_gate(38, (uint32_t)irq6, 0x08, 0x8E);
|
idt_set_gate(38, (uint32_t)irq6, 0x08, 0xEE);
|
||||||
idt_set_gate(39, (uint32_t)irq7, 0x08, 0x8E);
|
idt_set_gate(39, (uint32_t)irq7, 0x08, 0xEE);
|
||||||
idt_set_gate(40, (uint32_t)irq8, 0x08, 0x8E);
|
idt_set_gate(40, (uint32_t)irq8, 0x08, 0xEE);
|
||||||
idt_set_gate(41, (uint32_t)irq9, 0x08, 0x8E);
|
idt_set_gate(41, (uint32_t)irq9, 0x08, 0xEE);
|
||||||
idt_set_gate(42, (uint32_t)irq10, 0x08, 0x8E);
|
idt_set_gate(42, (uint32_t)irq10, 0x08, 0xEE);
|
||||||
idt_set_gate(43, (uint32_t)irq11, 0x08, 0x8E);
|
idt_set_gate(43, (uint32_t)irq11, 0x08, 0xEE);
|
||||||
idt_set_gate(44, (uint32_t)irq12, 0x08, 0x8E);
|
idt_set_gate(44, (uint32_t)irq12, 0x08, 0xEE);
|
||||||
idt_set_gate(45, (uint32_t)irq13, 0x08, 0x8E);
|
idt_set_gate(45, (uint32_t)irq13, 0x08, 0xEE);
|
||||||
idt_set_gate(46, (uint32_t)irq14, 0x08, 0x8E);
|
idt_set_gate(46, (uint32_t)irq14, 0x08, 0xEE);
|
||||||
idt_set_gate(47, (uint32_t)irq15, 0x08, 0x8E);
|
idt_set_gate(47, (uint32_t)irq15, 0x08, 0xEE);
|
||||||
|
|
||||||
sys_enable_interrupts();
|
sys_enable_interrupts();
|
||||||
}
|
}
|
||||||
|
8
isr.c
8
isr.c
@@ -149,7 +149,13 @@ void fault_handler(Stack *registers)
|
|||||||
terminal_printf("Exception. System Halted!\n");
|
terminal_printf("Exception. System Halted!\n");
|
||||||
terminal_printf("Exception: ");
|
terminal_printf("Exception: ");
|
||||||
terminal_printf(exception_messages[registers->id]);
|
terminal_printf(exception_messages[registers->id]);
|
||||||
|
terminal_printf("\n");
|
||||||
|
terminal_printf("Error code: %d\n", registers->err_code);
|
||||||
|
terminal_printf("EIP: %x\n", registers->eip);
|
||||||
|
terminal_printf("CS: %x\n", registers->cs);
|
||||||
|
terminal_printf("EFLAGS: %x\n", registers->eflags);
|
||||||
|
terminal_printf("ESP: %x\n", registers->esp);
|
||||||
|
terminal_printf("SS: %x\n", registers->ss);
|
||||||
isr_call_handler(registers);
|
isr_call_handler(registers);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
|
37
kernel.c
37
kernel.c
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
void kernel_main(void)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
|
terminal_printf("Kernel start\n");
|
||||||
terminal_initialize();
|
terminal_initialize();
|
||||||
gdt_install();
|
gdt_install();
|
||||||
|
|
||||||
@@ -28,22 +29,42 @@ void kernel_main(void)
|
|||||||
|
|
||||||
rtc_init();
|
rtc_init();
|
||||||
|
|
||||||
|
terminal_printf("Kernel initialized\n");
|
||||||
|
|
||||||
syscall_init();
|
syscall_init();
|
||||||
|
terminal_printf("Syscall initialized\n");
|
||||||
|
|
||||||
|
sys_enable_interrupts();
|
||||||
|
terminal_printf("Interrupts enabled\n");
|
||||||
|
|
||||||
enter_user_space();
|
enter_user_space();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SYSCALLS {
|
||||||
|
SYS_GETCHAR = 0,
|
||||||
|
SYS_GET_TIME,
|
||||||
|
SYS_HALT,
|
||||||
|
SYS_PRINTF,
|
||||||
|
SYS_DELAY,
|
||||||
|
SYS_CLEAR,
|
||||||
|
SYS_SHELL_INIT
|
||||||
|
};
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{ //TODO: Rework user space calls
|
||||||
|
int ret;
|
||||||
for (int i = 1; i < 4; i++)
|
for (int i = 1; i < 4; i++)
|
||||||
{
|
{
|
||||||
terminal_printf("&cTest &7%d\n", i);
|
asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_PRINTF), "b"("&cTest &7%d\n"), "c"(i));
|
||||||
delay(200);
|
|
||||||
|
asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_DELAY), "b"(1000));
|
||||||
}
|
}
|
||||||
terminal_clear();
|
|
||||||
|
|
||||||
terminal_printf("Welcome to &cDeadOS&7.\n");
|
asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_CLEAR));
|
||||||
terminal_printf("You are now in user space.\n");
|
|
||||||
terminal_printf("Type 'help' for a list of available commands.\n");
|
|
||||||
|
|
||||||
shell_init();
|
asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_PRINTF), "b"("Welcome to &cDeadOS&7.\n"));
|
||||||
|
asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_PRINTF), "b"("You are now in user space.\n"));
|
||||||
|
asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_PRINTF), "b"("Type 'help' for a list of available commands.\n"));
|
||||||
|
|
||||||
|
asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_SHELL_INIT));
|
||||||
}
|
}
|
||||||
|
31
syscall.c
31
syscall.c
@@ -7,26 +7,31 @@
|
|||||||
#include "tty.h"
|
#include "tty.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
|
#include "shell.h"
|
||||||
#define NB_SYSCALL 3
|
#define NB_SYSCALL 7
|
||||||
|
|
||||||
void *syscalls[NB_SYSCALL] = {
|
void *syscalls[NB_SYSCALL] = {
|
||||||
keyboard_getchar,
|
keyboard_getchar,
|
||||||
get_rtc_time,
|
get_rtc_time,
|
||||||
|
sys_halt,
|
||||||
sys_halt};
|
terminal_printf,
|
||||||
|
delay,
|
||||||
|
terminal_clear,
|
||||||
|
shell_init
|
||||||
|
};
|
||||||
|
|
||||||
void syscall_handler(Stack *registers)
|
void syscall_handler(Stack *registers)
|
||||||
{
|
{
|
||||||
int sys_index = registers->eax;
|
if ((registers->cs & 0x3) != 0x3) return;
|
||||||
|
|
||||||
if (sys_index >= NB_SYSCALL)
|
int sys_index = registers->eax;
|
||||||
return;
|
if (sys_index >= NB_SYSCALL) return;
|
||||||
|
|
||||||
void *function = syscalls[sys_index];
|
void *function = syscalls[sys_index];
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
asm volatile(" push %1; \
|
asm volatile("sti");
|
||||||
|
asm volatile (" push %1; \
|
||||||
push %2; \
|
push %2; \
|
||||||
push %3; \
|
push %3; \
|
||||||
push %4; \
|
push %4; \
|
||||||
@@ -37,9 +42,13 @@ void syscall_handler(Stack *registers)
|
|||||||
pop %%ebx; \
|
pop %%ebx; \
|
||||||
pop %%ebx; \
|
pop %%ebx; \
|
||||||
pop %%ebx; \
|
pop %%ebx; \
|
||||||
" : "=a"(ret) : "r"(registers->edi), "r"(registers->esi),
|
" : "=a" (ret) :
|
||||||
"r"(registers->edx), "r"(registers->ecx),
|
"r" (registers->edi), "r" (registers->esi),
|
||||||
"r"(registers->ebx), "r"(function));
|
"r" (registers->edx), "r" (registers->ecx),
|
||||||
|
"r" (registers->ebx), "r" (function));
|
||||||
|
|
||||||
|
asm volatile("cli");
|
||||||
|
|
||||||
registers->eax = ret;
|
registers->eax = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user