Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added EDI-OS/EDI-OS.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 84 additions & 0 deletions EDI-OS/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# EDI-OS

EDI-OS is an operating system simplified for educational purposes. This OS covers the minimum requirements of an OS but keeps the source code understandable and easy to comprehend.

![EDI-OS Boot Screen](./EDI-OS.png)

## Features

• Custom bootloader
• 32-bit protected mode kernel
• VGA text mode display (80x25)
• Basic keyboard input handling
• Command-line interface
• Color-coded debug/status messages
• Memory management initialization
• PS/2 keyboard controller support
• Basic command set: help, clear, version, about

### Dependencies

• NASM: Netwide Assembler
• GCC with support for 32-bit target
- LD (GNU Linkер)
- QEMU (for emulation)
- Make

For Debian/Ubuntu-based systems:
```bash
sudo apt-get install nasm gcc gcc-multilib qemu-system-x86 make
```

### Running

For running in QEMU :
```bash
make run
```

For debug mode with QEMU monitor:
```bash
make debug
```

## Project Structure

- `boot.asm` - Bootloader with detailed messages
- `kernel.c` - Main kernel with terminal and routines
- `keyboard.c` - Keyboard handling and command processing
- `kernel.h` - Kernel header with type definitions and function declarations
- `linker.ld` - Linker script for kernel building
- `Makefile` - Build automation

## Boot Sequence

1. Initialization of bootloader
2. Check memory
3. Initialization of disk system
4. Loading kernel
5. Switch to protected mode
6. Initialization of kernel
- Setup video
- Memory management
- Setup keyboard controller
- Setup interrupt handlers

## Available Commands

- `help` - View list of available commands
- `clear` - Clear screen
- `version` - View OS version
- `about` - View information about EDI-OS

## Technical Details

Boots from a virtual floppy disk (1.44MB)
Loads at the 1MB mark
Uses a custom GDT setup
imple I/O port handling
VGA text mode with color support
PS/2 keyboard support with scancode mapping

## Contributing

Contributions are welcome! Feel free to send a Pull Request.
59 changes: 59 additions & 0 deletions EDI-OS/src/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Compiler and flags
CC = gcc
AS = nasm
LD = ld

CFLAGS = -m32 -fno-pie -ffreestanding -fno-builtin -O2 -Wall -Wextra -fno-stack-protector -nostdlib -nodefaultlibs
ASFLAGS = -f elf32
LDFLAGS = -m elf_i386 -T linker.ld --oformat binary

# Source files
BOOT_SRC = boot.asm
KERNEL_ENTRY_SRC = kernel_entry.asm
KERNEL_SRC = kernel.c
KEYBOARD_SRC = keyboard.c

# Object files
BOOT_BIN = boot.bin
KERNEL_ENTRY_OBJ = kernel_entry.o
KERNEL_OBJ = kernel.o
KEYBOARD_OBJ = keyboard.o
KERNEL_BIN = kernel.bin
OS_IMAGE = os-image.bin

# Build rules
all: $(OS_IMAGE)

$(BOOT_BIN): $(BOOT_SRC)
$(AS) -f bin -o $@ $<

$(KERNEL_ENTRY_OBJ): $(KERNEL_ENTRY_SRC)
$(AS) $(ASFLAGS) -o $@ $<

$(KERNEL_OBJ): $(KERNEL_SRC)
$(CC) $(CFLAGS) -c $< -o $@

$(KEYBOARD_OBJ): $(KEYBOARD_SRC)
$(CC) $(CFLAGS) -c $< -o $@

$(KERNEL_BIN): $(KERNEL_ENTRY_OBJ) $(KERNEL_OBJ) $(KEYBOARD_OBJ)
$(LD) $(LDFLAGS) -o $@ $^

$(OS_IMAGE): $(BOOT_BIN) $(KERNEL_BIN)
# Create a blank 1.44MB floppy image
dd if=/dev/zero of=$@ bs=1024 count=1440
# Write boot sector to first sector
dd if=$(BOOT_BIN) of=$@ conv=notrunc
# Write kernel starting at second sector
dd if=$(KERNEL_BIN) of=$@ seek=1 conv=notrunc

run: $(OS_IMAGE)
qemu-system-i386 -fda $(OS_IMAGE)

debug: $(OS_IMAGE)
qemu-system-i386 -fda $(OS_IMAGE) -monitor stdio

clean:
rm -f *.bin *.o

.PHONY: all clean run debug
184 changes: 184 additions & 0 deletions EDI-OS/src/boot.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
[org 0x7c00]
[bits 16]

; Constants
KERNEL_OFFSET equ 0x1000
VIDEO_MODE equ 0x03 ; 80x25 text mode
STACK_BASE equ 0x9000
SECTORS_TO_READ equ 15 ; Number of sectors for kernel

; Initialize segments and stack
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, STACK_BASE

; Save boot drive number
mov [BOOT_DRIVE], dl

; Set video mode
mov ah, 0x00
mov al, VIDEO_MODE
int 0x10

; Print initial boot message
mov si, MSG_BOOT
call print_string
mov cx, 5 ; Number of delay iterations
call long_delay

; Print memory check message
mov si, MSG_MEM_CHECK
call print_string
mov cx, 4
call long_delay

; Reset disk system and show message
mov si, MSG_DISK_RESET
call print_string
xor ah, ah
mov dl, [BOOT_DRIVE]
int 0x13
jc disk_error
mov cx, 4
call long_delay

; Load kernel message
mov si, MSG_LOAD_KERNEL
call print_string

; Load kernel
mov bx, KERNEL_OFFSET ; Destination address
mov dh, SECTORS_TO_READ ; Sectors to read
call load_disk
mov cx, 4
call long_delay

; Switch to protected mode message
mov si, MSG_PROT_MODE
call print_string
mov cx, 4
call long_delay

; Switch to protected mode
cli ; Clear interrupts
lgdt [GDT_DESCRIPTOR] ; Load GDT
mov eax, cr0
or eax, 0x1 ; Set protected mode bit
mov cr0, eax
jmp CODE_SEG:init_pm ; Far jump to 32-bit code

; Function to add a longer delay
; cx = number of iterations
long_delay:
push cx ; Save outer loop counter
.outer_loop:
push cx
mov cx, 0xFFFF ; Maximum 16-bit value
.inner_loop1:
push cx
mov cx, 0x0FFF ; Increased inner delay
.inner_loop2:
loop .inner_loop2
pop cx
loop .inner_loop1
pop cx
loop .outer_loop
pop cx ; Restore outer loop counter
ret

load_disk:
push dx ; Save DX

mov ah, 0x02 ; BIOS read function
mov al, dh ; Number of sectors
mov ch, 0 ; Cylinder 0
mov dh, 0 ; Head 0
mov cl, 2 ; Start from sector 2
mov dl, [BOOT_DRIVE]

int 0x13
jc disk_error ; Check for error

pop dx ; Restore DX
cmp dh, al ; Compare sectors read
jne disk_error ; Error if not equal

; Print success message
mov si, MSG_LOAD_OK
call print_string
ret

disk_error:
mov si, DISK_ERROR_MSG
call print_string
jmp $

print_string:
mov ah, 0x0E ; BIOS teletype function
.loop:
lodsb ; Load next character
test al, al ; Check for null terminator
jz .done ; If zero, we're done
int 0x10 ; Otherwise, print
jmp .loop
.done:
ret

[bits 32]
init_pm:
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax

mov ebp, STACK_BASE
mov esp, ebp

jmp KERNEL_OFFSET

; Data
BOOT_DRIVE db 0
MSG_BOOT db 'EDI-OS Bootloader starting...', 0x0D, 0x0A, 0
MSG_MEM_CHECK db 'Checking memory map...OK', 0x0D, 0x0A, 0
MSG_DISK_RESET db 'Resetting disk system...', 0x0D, 0x0A, 0
MSG_LOAD_KERNEL db 'Loading kernel into memory...', 0x0D, 0x0A, 0
MSG_LOAD_OK db 'Kernel loaded successfully!', 0x0D, 0x0A, 0
MSG_PROT_MODE db 'Switching to protected mode...', 0x0D, 0x0A, 0
DISK_ERROR_MSG db 'Disk read error!', 0x0D, 0x0A, 0

; GDT
GDT_START:
dq 0 ; Null descriptor

GDT_CODE:
dw 0xFFFF ; Limit (0-15)
dw 0 ; Base (0-15)
db 0 ; Base (16-23)
db 10011010b ; Access byte
db 11001111b ; Flags and limit (16-19)
db 0 ; Base (24-31)

GDT_DATA:
dw 0xFFFF
dw 0
db 0
db 10010010b
db 11001111b
db 0

GDT_END:

GDT_DESCRIPTOR:
dw GDT_END - GDT_START - 1
dd GDT_START

CODE_SEG equ GDT_CODE - GDT_START
DATA_SEG equ GDT_DATA - GDT_START

; Boot signature
times 510-($-$$) db 0
dw 0xAA55
Loading
Loading