Remove most code for a blank start

This commit is contained in:
pjht 2019-02-09 12:52:45 -06:00
commit ef90f51688
52 changed files with 1303 additions and 0 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
*.img[[:space:]]*.vdi filter=lfs diff=lfs merge=lfs -text
*.vdi filter=lfs diff=lfs merge=lfs -text
*.img filter=lfs diff=lfs merge=lfs -text

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
*.bin
*.dis
*.o
*.elf
*/*.o
bochsout.txt
stuff/*
cpu/memory.h
os.iso
disk.img

45
Makefile Normal file
View File

@ -0,0 +1,45 @@
PLAT=i386
C_SOURCES = $(wildcard kernel/*.c drivers/$(PLAT)/*.c drivers/$(PLAT)/*/*.c libc/*.c cpu/$(PLAT)/*.c fs/*.c)
OBJ = $(C_SOURCES:.c=.o $(shell cat psinfo/$(PLAT)/o.txt))
CC = $(shell cat psinfo/$(PLAT)/cc.txt)
GDB = $(shell cat psinfo/$(PLAT)/gdb.txt)
CFLAGS = -Wall -g -ffreestanding
QFLAGS = -m 2G -boot d -cdrom os.iso -serial vc #-chardev socket,id=s1,port=3000,host=localhost -serial chardev:s1
all: os.iso
run: os.iso
qemu-system-i386 $(QFLAGS) -monitor stdio
debug: os.iso kernel/kernel.elf
qemu-system-i386 -s $(QFLAGS) &
$(GDB) -ex "target remote localhost:1234" -ex "symbol-file kernel/kernel.elf"
os.iso: kernel/kernel.elf initrd/*
cp kernel/kernel.elf iso/boot
ruby makeinitrd.rb initrd iso/boot/initrd
grub-mkrescue -o $@ iso
kernel/kernel.elf: $(OBJ)
i386-elf-ld -T linker.ld -o $@ $^
%.o: %.c h_files
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.asm
nasm $< -f elf -o $@
%.o: %.s
i386-elf-as $< -o $@
h_files: cpu/$(PLAT)/memory.h
rm -f cpu/memory.h
cp cpu/$(PLAT)/memory.h cpu/memory.h
pipe:
rm -f pipe.in pipe.out
mkfifo pipe.in
ln pipe.in pipe.out
clean:
rm -rf $(OBJ) kernel/cstart.o cpu/memory.h os.iso */*.elf iso/boot/initrd.tar

57
bochsrc.txt Normal file
View File

@ -0,0 +1,57 @@
# configuration file generated by Bochs
plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, iodebug=1
config_interface: textconfig
display_library: sdl2
memory: host=32, guest=32
romimage: file="/usr/local/Cellar/bochs/2.6.9_2/share/bochs/BIOS-bochs-latest", address=0x0, options=none
vgaromimage: file="/usr/local/Cellar/bochs/2.6.9_2/share/bochs/VGABIOS-lgpl-latest"
boot: cdrom
floppy_bootsig_check: disabled=0
# no floppya
# no floppyb
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=cdrom, path="os.iso", status=inserted, model="Generic 1234", biosdetect=auto
ata0-slave: type=none
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata1-master: type=none
ata1-slave: type=none
ata2: enabled=0
ata3: enabled=0
optromimage1: file=none
optromimage2: file=none
optromimage3: file=none
optromimage4: file=none
optramimage1: file=none
optramimage2: file=none
optramimage3: file=none
optramimage4: file=none
pci: enabled=1, chipset=i440fx
vga: extension=vbe, update_freq=5, realtime=1
cpu: count=1:1:1, ips=640000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU "
cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0
cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, avx_f16c=0, avx_fma=0, bmi=0, xop=0, fma4=0
cpuid: tbm=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0, smep=0, smap=0, mwait=1, vmx=1
print_timestamps: enabled=0
debugger_log: -
magic_break: enabled=0
port_e9_hack: enabled=0
private_colormap: enabled=0
clock: sync=none, time0=local, rtc_sync=0
# no cmosimage
# no loader
log: bochsout.txt
logprefix: %t%e%d
debug: action=ignore,pci=report,pci2isa=report,pci_ide=report
info: action=report
error: action=report
panic: action=ask
keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none
mouse: type=ps2, enabled=1, toggle=ctrl+mbutton
speaker: enabled=1, mode=gui
parport1: enabled=1, file=none
parport2: enabled=0
com1: enabled=0
com2: enabled=0
com3: enabled=0
com4: enabled=0

6
cpu/cpu_init.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef CPU_INIT_H
#define CPU_INIT_H
void cpu_init();
#endif

6
cpu/halt.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef HALT_H
#define HALT_H
void halt() __attribute__((noreturn));
#endif

2
cpu/i386/cpu_init.c Normal file
View File

@ -0,0 +1,2 @@
void cpu_init() {
}

5
cpu/i386/halt.c Normal file
View File

@ -0,0 +1,5 @@
void halt() {
asm volatile("cli;\
hltlabel: hlt;\
jmp hltlabel");
}

6
cpu/i386/memory.c Normal file
View File

@ -0,0 +1,6 @@
#include "paging.h"
#include <stdint.h>
void* alloc_memory(uint32_t num_blocks) {
return alloc_kern_pages(num_blocks,1);
}

9
cpu/i386/memory.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef CPU_MEMORY_H
#define CPU_MEMORY_H
#include <stdint.h>
#define BLK_SZ 4096
void* alloc_memory(uint32_t blocks);
#endif

70
cpu/i386/paging.c Normal file
View File

@ -0,0 +1,70 @@
#include <stdint.h>
#include "paging_helpers.h"
#include "paging.h"
uint32_t page_directory [1024] __attribute__((aligned(4096)));
uint32_t page_tables [1048576] __attribute__((aligned(4096)));
void* next_kern_virt=(void*)KERN_VIRT_START;
void* next_kern_phys=(void*)KERN_PHYS_START;
void set_directory_entry(int entry,char usr,char wr,char p,uint32_t* page_directory,uint32_t* page_tables) {
int flags=p&1;
flags=flags|((wr&1)<<1);
flags=flags|((usr&1)<<2);
page_directory[entry]=(((uint32_t)&(page_tables[entry*1024]))-0xC0000000)|flags;
}
void set_table_entry(uint32_t page,uint32_t base_addr,char usr,char wr,char p,uint32_t* page_tables) {
int flags=p&1;
flags=flags|((wr&1)<<1);
flags=flags|((usr&1)<<2);
page_tables[page]=base_addr|flags;
}
void alloc_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr,uint32_t* page_directory,uint32_t* page_tables) {
uint32_t virt_addr=(uint32_t)virt_addr_ptr;
uint32_t phys_addr=(uint32_t)phys_addr_ptr;
int dir_entry=(virt_addr&0xFFC00000)>>22;
int table_entry=(virt_addr&0x3FF000)>>12;
for (int i=0;i<=num_pages;i++) {
set_table_entry((dir_entry*1024)+table_entry,phys_addr,usr,wr,1,page_tables);
table_entry++;
phys_addr+=0x1000;
if (table_entry==1024) {
table_entry=0;
set_directory_entry(dir_entry,usr,wr,1,page_directory,page_tables);
dir_entry++;
} else if (i==num_pages) {
set_directory_entry(dir_entry,usr,wr,1,page_directory,page_tables);
}
}
}
void* alloc_kern_pages(int num_pages,char wr) {
void* starting=next_kern_virt;
alloc_pages(next_kern_virt,next_kern_phys,num_pages,1,wr,page_directory,page_tables);
next_kern_virt+=num_pages*4096;
next_kern_phys+=num_pages*4096;
return starting;
}
int dir_entry_present(int entry) {
uint32_t dir_entry=page_directory[entry];
return dir_entry&1;
}
void* virt_to_phys(void* virt_addr_ptr) {
uint32_t virt_addr=(uint32_t)virt_addr_ptr;
int dir_num=(virt_addr&0xFFC00000)>>22;
int table_num=(virt_addr&0x3FF000)>>12;
int offset=(virt_addr&0xFFF);
uint32_t table_entry=page_tables[(dir_num*1024)+table_num];
table_entry=table_entry&0xFFFFF000;
return (void*)(table_entry+offset);
}
void init_paging() {
alloc_kern_pages(NUM_KERN_DIRS*1024,1);
load_page_directory((uint32_t*)((uint32_t)page_directory-0xC0000000));
}

21
cpu/i386/paging.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef PAGING_H
#define PAGING_H
#include <stdint.h>
#include "paging_helpers.h"
#define NUM_KERN_DIRS 4
#define KERN_VIRT_START 0xC0000000
#define KERN_PHYS_START 0x0
extern uint32_t page_directory[1024];
extern uint32_t page_tables[1048576];
void alloc_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr,uint32_t* page_directory,uint32_t* page_tables);
void* alloc_kern_pages(int num_pages,char wr);
int dir_entry_present(int entry);
void* virt_to_phys(void* virt_addr_ptr);
void init_paging();
#endif

View File

@ -0,0 +1,9 @@
global load_page_directory
load_page_directory:
push ebp
mov ebp, esp
mov eax, [esp+8]
mov cr3, eax
mov esp, ebp
pop ebp
ret

View File

@ -0,0 +1,6 @@
#ifndef PAGING_HELPERS_H
#define PAGING_HELPERS_H
void load_page_directory(uint32_t* dir);
#endif

29
cpu/i386/ports.c Normal file
View File

@ -0,0 +1,29 @@
unsigned char port_byte_in(unsigned short port) {
unsigned char result;
asm("in %%dx, %%al":"=a"(result):"d"(port));
return result;
}
void port_byte_out(unsigned short port,unsigned char data) {
asm("out %%al, %%dx":: "a"(data),"d"(port));
}
unsigned short port_word_in(unsigned short port) {
unsigned short result;
asm("in %%dx, %%ax":"=a"(result):"d"(port));
return result;
}
void port_word_out(unsigned short port,unsigned short data) {
asm("out %%ax, %%dx":: "a" (data), "d" (port));
}
unsigned long port_long_in(unsigned short port) {
unsigned long result;
asm("inl %%dx, %%eax":"=a"(result):"d"(port));
return result;
}
void port_long_out(unsigned short port,unsigned long data) {
asm("outl %%eax, %%dx":: "a" (data), "d" (port));
}

10
cpu/i386/ports.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef PORTS_H
#define PORTS_H
unsigned char port_byte_in(unsigned short port);
void port_byte_out(unsigned short port,unsigned char data);
unsigned short port_word_in(unsigned short port);
void port_word_out(unsigned short port,unsigned short data);
unsigned long port_long_in(unsigned short port);
void port_long_out(unsigned short port,unsigned long data);
#endif

6
drivers/parallel.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef PARALLEL_H
#define PARALLEL_H
void parallel_init();
#endif

44
drivers/pci.h Normal file
View File

@ -0,0 +1,44 @@
#ifndef PCI_H
#define PCI_H
typedef struct {
uint16_t vend_id;
uint16_t dev_id;
uint16_t command;
uint16_t status;
uint8_t rev_id;
uint8_t prog_if;
uint8_t subclass;
uint8_t class_code;
uint8_t cache_line_size;
uint8_t lat_timer;
uint8_t header_type;
uint8_t bist;
} __attribute__((packed)) pci_dev_common_info;
typedef enum {
PCI_CLASS_UNCLASSIFIED=0x0,
PCI_CLASS_STORAGE=0x1,
PCI_CLASS_NETWORK=0x2,
PCI_CLASS_DISPLAY=0x3,
PCI_CLASS_MULTIMEDIA=0x4,
PCI_CLASS_MEMORY=0x5,
PCI_CLASS_BRIDGE=0x6,
PCI_CLASS_SIMPCOM=0x7,
PCI_CLASS_BASEPERIPH=0x8,
PCI_CLASS_INPDEV=0x9,
PCI_CLASS_DOCK=0xa,
PCI_CLASS_CPU=0xb,
PCI_CLASS_SERBUS=0xc,
PCI_CLASS_WIRELESS=0xd,
PCI_CLASS_INTELLIGENT=0xe,
PCI_CLASS_SATELLITE=0xf,
PCI_CLASS_ENCRYPTION=0x10,
PCI_CLASS_SIGPROCESS=0x11,
} pci_class;
extern pci_dev_common_info** pci_devs;
extern uint32_t pci_num_devs;
void pci_init();
#endif

6
drivers/ps2.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef PS2_EXT_H
#define PS2_EXT_H
void ps2_init();
#endif

9
drivers/screen.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef SCREEN_H
#define SCREEN_H
void screen_init();
void screen_write_string(const char *string);
void screen_clear();
void screen_backspace();
#endif

7
drivers/serial.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef SERIAL_H
#define SERIAL_H
#include <stdint.h>
void serial_init();
#endif

7
drivers/timer.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef TIMER_H
#define TIMER_H
void wait(int milli);
void timer_init();
#endif

BIN
dump.dat Normal file

Binary file not shown.

71
fs/devfs.c Normal file
View File

@ -0,0 +1,71 @@
// #include "../kernel/vfs.h"
// #include "../libc/stdlib.h"
// #include "../libc/string.h"
// #include "../libc/stdio.h"
// #include "devfs.h"
//
// char** devices;
// dev_drv* dev_drivers;
// uint32_t num_devices;
// uint32_t max_devices;
//
// char devfs_drv(fs_op op,FILE* stream,void* data1,void* data2) {
// if (op==FSOP_MOUNT) {
// return 1;
// }
// if (op==FSOP_OPEN) {
// for (int i=0;i<num_devices;i++) {
// if (strcmp(devices[i],stream->path)==0) {
// return 1;
// }
// }
// return 0;
// }
// if (op==FSOP_GETC) {
// int i;
// for (i=0;i<num_devices;i++) {
// if (strcmp(devices[i],stream->path)==0) {
// break;
// }
// }
// *((int*)data1)=dev_drivers[i]((char*)stream->path,0,stream->pos,0);
// stream->pos+=1;
// return 1;
// }
// if (op==FSOP_PUTC) {
// int i;
// for (i=0;i<num_devices;i++) {
// if (strcmp(devices[i],stream->path)==0) {
// break;
// }
// }
// dev_drivers[i]((char*)stream->path,*((int*)data1),stream->pos,1);
// stream->pos+=1;
// return 1;
// }
// if (op==FSOP_CLOSE) {
// return 1;
// }
// return 0;
// }
//
// void init_devfs() {
// devices=malloc(sizeof(char*)*32);
// dev_drivers=malloc(sizeof(dev_drv)*32);
// num_devices=0;
// max_devices=0;
// register_fs(devfs_drv,"devfs");
// mount("/dev/","","devfs");
// }
//
// void add_dev(dev_drv drv,char* name) {
// if (num_devices==max_devices) {
// devices=realloc(devices,sizeof(char*)*(max_devices+32));
// dev_drivers=realloc(dev_drivers,sizeof(dev_drv)*(max_devices+32));
// max_devices+=32;
// }
// dev_drivers[num_devices]=drv;
// devices[num_devices]=malloc(sizeof(char)*(strlen(name)+1));
// strcpy(devices[num_devices],name);
// num_devices++;
// }

8
fs/devfs.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef DEVFS_H
#define DEVFS_H
typedef int (*dev_drv)(char* filename,int c,long pos,char wr);
void init_devfs();
void add_dev(dev_drv drv,char* name);
#endif

85
fs/initrd.c Normal file
View File

@ -0,0 +1,85 @@
// #include "../kernel/vfs.h"
// #include "../cpu/halt.h"
// #include "../libc/stdlib.h"
// #include "../libc/stdio.h"
// #include "../libc/string.h"
//
// char** names;
// uint32_t* offsets;
// uint32_t* sizes;
// uint32_t num_files;
// FILE* initrd_fd;
//
// char initrd_drv(fs_op op,FILE* stream,void* data1,void* data2) {
// if (op==FSOP_MOUNT) {
// return 1;
// }
// if (op==FSOP_OPEN) {
// char file_exists=0;
// for (int i=0;i<num_files;i++) {
// if (strcmp(names[i],stream->path)==0) {
// file_exists=1;
// }
// }
// return file_exists;
// }
// if (op==FSOP_GETC) {
// int i;
// for (i=0;i<num_files;i++) {
// if (strcmp(names[i],stream->path)==0) {
// break;
// }
// }
// if (stream->pos>=sizes[i]) {
// *((int*)data1)=EOF;
// stream->eof=1;
// return 1;
// }
// fseek(initrd_fd,offsets[i]+stream->pos,SEEK_SET);
// *((int*)data1)=fgetc(initrd_fd);
// stream->pos+=1;
// return 1;
// }
// if (op==FSOP_CLOSE) {
// return 1;
// }
// return 0;
// }
//
// void init_initrd() {
// initrd_fd=fopen("/dev/initrd","r");
// if (!initrd_fd) {
// printf("PANIC: Cannot open initrd!");
// halt();
// }
// uint32_t max_files=32;
// num_files=0;
// names=malloc(sizeof(char*)*32);
// offsets=malloc(sizeof(uint32_t)*32);
// sizes=malloc(sizeof(uint32_t)*32);
// for (uint32_t i=0;;i++) {
// if (i==max_files) {
// names=realloc(names,sizeof(char*)*(max_files+32));
// offsets=realloc(offsets,sizeof(uint32_t)*(max_files+32));
// sizes=realloc(sizes,sizeof(uint32_t)*(max_files+32));
// max_files+=32;
// }
// uint32_t name_size;
// fread(&name_size,4,1,initrd_fd);
// if (name_size==0) {
// break;
// }
// char* name=malloc(sizeof(char)*(name_size+1));
// fread(name,1,name_size+1,initrd_fd);
// long contents_size;
// fread(&contents_size,4,1,initrd_fd);
// long datapos=ftell(initrd_fd);
// fseek(initrd_fd,contents_size,SEEK_CUR);
// names[i]=name;
// offsets[i]=datapos;
// sizes[i]=contents_size;
// num_files++;
// }
// fseek(initrd_fd,0,SEEK_SET);
// register_fs(initrd_drv,"initrd");
// }

6
fs/initrd.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef INITRD_H
#define INITRD_H
uint32_t init_initrd();
#endif

2
initrd/hi.txt Normal file
View File

@ -0,0 +1,2 @@
Hello!
This is hi.txt!

1
initrd/myfile.txt Normal file
View File

@ -0,0 +1 @@
This is another file!

1
initrd/test.txt Normal file
View File

@ -0,0 +1 @@
File 1

7
iso/boot/grub/grub.cfg Normal file
View File

@ -0,0 +1,7 @@
timeout=0
menuentry "My OS" {
multiboot /boot/kernel.elf
module /boot/initrd initrd
boot
}

BIN
iso/boot/initrd Normal file

Binary file not shown.

126
kernel/boot.s Normal file
View File

@ -0,0 +1,126 @@
# Declare constants for the multiboot header.
.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
# Declare a multiboot header that marks the program as a kernel.
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
# Allocate the initial stack.
.section .bootstrap_stack, "aw", @nobits
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
.global int_stack_top
.section .interrupt_stack, "aw", @nobits
int_stack_bottom:
.skip 16384 # 16 KiB
int_stack_top:
# Preallocate pages used for paging. Don't hard-code addresses and assume they
# are available, as the bootloader might have loaded its multiboot structures or
# modules there. This lets the bootloader know it must avoid the addresses.
.section .bss, "aw", @nobits
.align 4096
boot_page_directory:
.skip 4096
boot_page_tables:
boot_page_table1:
.skip 4096
boot_page_table2:
.skip 4096
boot_page_table3:
.skip 4096
boot_page_table4:
.skip 4096
# Further page tables may be required if the kernel grows beyond 3 MiB.
# The kernel entry point.
.section .text
.global _start
.type _start, @function
_start:
cmp $0x2BADB002, %eax
jnz no_multiboot
# Physical address of boot_page_tables.
# TODO: I recall seeing some assembly that used a macro to do the
# conversions to and from physical. Maybe this should be done in this
# code as well?
movl $(boot_page_tables - 0xC0000000), %edi
# First address to map is address 0.
# TODO: Start at the first kernel page instead. Alternatively map the first
# 1 MiB as it can be generally useful, and there's no need to
# specially map the VGA buffer.
movl $0, %esi
# Map 4096 pages.
movl $4096, %ecx
1:
# Map physical address as "present, writable". Note that this maps
# .text and .rodata as writable. Mind security and map them as non-writable.
movl %esi, %edx
orl $0x007, %edx
movl %edx, (%edi)
# Size of page is 4096 bytes.
addl $4096, %esi
# Size of entries in boot_page_tables is 4 bytes.
addl $4, %edi
# Loop to the next entry if we haven't finished.
loop 1b
# The page table is used at both page directory entry 0 (virtually from 0x0
# to 0x3FFFFF) (thus identity mapping the kernel) and page directory entry
# 768 (virtually from 0xC0000000 to 0xC03FFFFF) (thus mapping it in the
# higher half). The kernel is identity mapped because enabling paging does
# not change the next instruction, which continues to be physical. The CPU
# would instead page fault if there was no identity mapping.
# Map the page table to both virtual addresses 0x00000000 and 0xC0000000.
movl $(boot_page_table1 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 0
movl $(boot_page_table1 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 768 * 4
movl $(boot_page_table2 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 769 * 4
movl $(boot_page_table3 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 770 * 4
movl $(boot_page_table4 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 771 * 4
# Set cr3 to the address of the boot_page_directory.
movl $(boot_page_directory - 0xC0000000), %ecx
movl %ecx, %cr3
# Enable paging and the write-protect bit.
movl %cr0, %ecx
orl $0x80010000, %ecx
movl %ecx, %cr0
# Jump to higher half with an absolute jump.
lea 4f, %ecx
jmp *%ecx
4:
# At this point, paging is fully set up and enabled.
# Unmap the identity mapping as it is now unnecessary.
movl $0, boot_page_directory + 0
# Reload crc3 to force a TLB flush so the changes to take effect.
movl %cr3, %ecx
movl %ecx, %cr3
# Set up the stack.
mov $stack_top, %esp
# Enter the high-level kernel.
add $0xC0000000, %ebx
push %ebx
call kmain
# Infinite loop if the system has nothing more to do.
no_multiboot:
loop: jmp loop

5
kernel/kernel.c Normal file
View File

@ -0,0 +1,5 @@
#include "../cpu/cpu_init.h"
void kmain() {
cpu_init();
}

37
libc/devbuf.c Normal file
View File

@ -0,0 +1,37 @@
#include "devbuf.h"
#include "stdlib.h"
#include "stdio.h"
devbuf* devbuf_init() {
devbuf* buf=malloc(sizeof(devbuf));
buf->rd=0;
buf->wr=0;
for (int i=0;i<256;i++) {
buf->buf[i]=EOF;
}
}
void devbuf_add(char byte,devbuf* buf) {
buf->buf[buf->wr]=byte;
buf->wr++;
if (buf->wr==buf->rd) {
buf->wr--;
}
}
int devbuf_get(devbuf* buf) {
if (buf->buf[buf->rd]==-1) {
buf->rd++;
if (buf->buf[buf->rd]==-1) {
buf->rd--;
while (buf->buf[buf->rd]==-1);
}
}
int data=buf->buf[buf->rd];
buf->buf[buf->rd]=-1;
buf->rd++;
if (buf->rd>buf->wr) {
buf->rd=buf->wr-1;
}
return data;
}

16
libc/devbuf.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef DEVBUF_H
#define DEVBUF_H
#include <stdint.h>
typedef struct {
int buf[256];
uint8_t rd;
uint8_t wr;
} devbuf;
devbuf* devbuf_init();
void devbuf_add(char byte,devbuf* buf);
int devbuf_get(devbuf* buf);
#endif

7
libc/math.c Normal file
View File

@ -0,0 +1,7 @@
float ceilf(float num) {
int inum=(int)num;
if (num==(float)inum) {
return (float)inum;
}
return (float)(inum+1);
}

6
libc/math.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef MATH_H
#define MATH_H
float ceilf(float num);
#endif

40
libc/stdio.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef STDIO_H
#define STDIO_H
#include <stddef.h>
#include <stdint.h>
typedef struct {
char* mntpnt;
const char* path;
uint32_t type;
long pos;
int eof;
} FILE;
#define NO_FD 0xFFFFFFFF
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 3
#define EOF -1
extern uint32_t stdin;
extern uint32_t stdout;
extern uint32_t stderr;
uint32_t fopen(const char* filename,const char* mode);
int fgetc(FILE* stream);
int getc();
char* fgets(char* str,int count,FILE* stream);
size_t fread(void* buffer,size_t size,size_t count,FILE* stream);
int fputc(int c,FILE* stream);
int putc(int c);
int fputs(const char* s,FILE* stream);
int puts(const char* s);
int fprintf(FILE* stream,const char* format,...);
int printf(const char* format,...);
int fseek(FILE* stream,long offset,int origin);
long ftell(FILE* stream);
int fclose(FILE* file);
#endif

142
libc/stdlib.c Normal file
View File

@ -0,0 +1,142 @@
#include "../cpu/memory.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include <stdint.h>
#define MAX_BLOCKS 512
#define MALLOC_DEBUG 1
typedef struct {
char* bitmap;
uint32_t bitmap_byt_size;
uint32_t bitmap_bit_size;
uint32_t avail_data_size;
void* data_block;
} heap_block;
heap_block entries[MAX_BLOCKS];
uint32_t num_used_entries;
char get_bmap_bit(char* bmap,uint32_t index) {
uint32_t byte=index/8;
uint32_t bit=index%8;
char entry=bmap[byte];
return (entry&(1<<bit))>0;
}
void set_bmap_bit(char* bmap,uint32_t index) {
uint32_t byte=index/8;
uint32_t bit=index%8;
bmap[byte]=bmap[byte]|(1<<bit);
}
void clear_bmap_bit(char* bmap,uint32_t index) {
uint32_t byte=index/8;
uint32_t bit=index%8;
bmap[byte]=bmap[byte]&(~(1<<bit));
}
void reserve_block(uint32_t mem_blks) {
uint32_t bmap_byts=((mem_blks*BLK_SZ)/4)/8;
entries[num_used_entries].bitmap=alloc_memory((uint32_t)ceilf((double)bmap_byts/BLK_SZ));
entries[num_used_entries].bitmap_byt_size=bmap_byts;
entries[num_used_entries].bitmap_bit_size=bmap_byts*8;
char* bmap=entries[num_used_entries].bitmap;
char bmap_byt_sz=entries[num_used_entries].bitmap_byt_size;
for(uint32_t i=0;i<bmap_byt_sz;i++) {
bmap[i]=0;
}
entries[num_used_entries].avail_data_size=mem_blks*BLK_SZ;
entries[num_used_entries].data_block=alloc_memory(mem_blks);
num_used_entries++;
}
void* malloc(uint32_t size) {
uint32_t num_4b_grps=(uint32_t)ceilf((float)size/4);
num_4b_grps+=3;
int blk_indx=-1;
uint32_t bmap_index;
heap_block entry;
for (int i=0;i<num_used_entries;i++) {
uint32_t remaining_blks;
entry=entries[i];
if (entry.avail_data_size>=size) {
char* bmap=entry.bitmap;
uint32_t bmap_byt_sz=entry.bitmap_byt_size;
for(int i=0;i<bmap_byt_sz;i++) {
if (bmap[i]!=0xFF) {
char got_0=0;
remaining_blks=num_4b_grps;
uint32_t old_j;
for (uint32_t j=i*8;;j++) {
char bit=get_bmap_bit(bmap,j);
if (got_0) {
if (bit) {
if (remaining_blks==0) {
bmap_index=old_j;
break;
} else {
i+=j/8;
i--;
break;
}
} else {
remaining_blks--;
}
} else {
if (!bit) {
got_0=1;
old_j=j;
remaining_blks--;
}
}
if (remaining_blks==0) {
bmap_index=old_j;
break;
}
}
}
if (remaining_blks==0) {
break;
}
}
}
if (remaining_blks==0) {
blk_indx=i;
break;
}
}
if (blk_indx==-1) {
// reserve_block((uint32_t)ceilf((double)size/BLK_SZ));
reserve_block(256);
return malloc(size);
}
for (int i=0;i<num_4b_grps;i++) {
set_bmap_bit(entry.bitmap,bmap_index+i);
}
uint32_t data_offset=(bmap_index*8)+12;
uint32_t* info=(void*)(((uint32_t)entry.data_block)+data_offset-12);
info[0]=num_4b_grps;
info[1]=bmap_index;
info[2]=blk_indx;
entry.avail_data_size-=size+12;
return (void*)(((uint32_t)entry.data_block)+data_offset);
}
void* realloc(void *mem, size_t new_sz) {
void* ptr=malloc(new_sz);
uint32_t num_4b_grps=*((uint32_t*)((uint32_t)mem-12));
memcpy(ptr,mem,num_4b_grps*4);
free(mem);
mem=ptr;
return ptr;
}
void free(void* mem) {
uint32_t* info=(uint32_t*)((uint32_t)mem-12);
uint32_t num_4b_grps=info[0];
uint32_t bmap_index=info[1];
uint32_t blk_indx=info[2];
heap_block entry=entries[blk_indx];
for (int i=0;i<num_4b_grps;i++) {
clear_bmap_bit(entry.bitmap,bmap_index+i);
}
entry.avail_data_size+=(num_4b_grps*4)+12;
}

12
libc/stdlib.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef STDLIB_H
#define STDLIB_H
#include <stddef.h>
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
void* malloc(size_t size);
void* realloc(void *mem, size_t new_sz);
void free(void* mem);
#endif

137
libc/string.c Normal file
View File

@ -0,0 +1,137 @@
#include "string.h"
#include <stddef.h>
#include <stdint.h>
#include "stdlib.h"
void* memcpy(void* dest_ptr,const void* source_ptr,size_t len) {
char* source=(char*)source_ptr;
char* dest=(char*)dest_ptr;
for(size_t i=0;i<len;i++) {
dest[i]=source[i];
}
return dest_ptr;
}
void* memset(void *dest_ptr,int val,size_t len) {
char* dest=(char*)dest_ptr;
for (size_t i=0;i<len;i++){
dest[i]=(char)val;
}
return dest_ptr;
}
int strcmp(const char* s1,const char* s2) {
int i;
for (i = 0; s1[i] == s2[i]; i++) {
if (s1[i] == '\0') return 0;
}
return s1[i] - s2[i];
}
size_t strlen(const char* str) {
size_t i;
for (i=0;str[i]!='\0';i++);
return i;
}
char* strcpy(char* dest,const char* src) {
int i;
for (i=0;i<strlen(src);i++) {
dest[i]=src[i];
}
dest[i]='\0';
return dest;
}
char* strrev(char* str) {
char chr;
int j;
for (int i=0,j=strlen(str)-1;i<j;i++,j--) {
chr=str[i];
str[i]=str[j];
str[j]=chr;
}
return str;
}
void int_to_ascii(int n,char* str) {
int i;
int sign;
if ((sign = n)<0) {
n=-n;
}
i=0;
do {
str[i++]=n%10+'0';
} while ((n /= 10) > 0);
if (sign < 0) {
str[i++] = '-';
}
str[i]='\0';
strrev(str);
}
void hex_to_ascii(int n, char* str) {
append(str, '0');
append(str, 'x');
char zeros = 0;
unsigned int tmp;
int i;
for (i = 28; i > 0; i -= 4) {
tmp = (n >> i) & 0xF;
if (tmp == 0 && zeros == 0) continue;
zeros = 1;
if (tmp > 0xA) append(str, tmp - 0xA + 'a');
else append(str, tmp + '0');
}
tmp = n & 0xF;
if (tmp >= 0xA) append(str, tmp - 0xA + 'a');
else append(str, tmp + '0');
}
void append(char* s, char n) {
int len = strlen(s);
s[len] = n;
s[len+1] = '\0';
}
void backspace(char* s) {
int len = strlen(s);
s[len-1] = '\0';
}
char* strtok_str=NULL;
size_t strtok_index;
char strtok_delim_check(char* delim) {
for (int i=0;i<strlen(delim);i++) {
if (strtok_str[strtok_index]==delim[i]||strtok_str[strtok_index]=='\0') {
return 0;
}
}
return 1;
}
char* strtok(char* str, const char* delim) {
if (str!=NULL) {
strtok_str=str;
strtok_index=0;
}
if (!strtok_str || strtok_index>strlen(strtok_str)) {
return NULL;
}
char* tok=malloc(sizeof(char)*32);
tok[0]='\0';
size_t max_len=32;
for (;strtok_delim_check(delim);strtok_index++) {
if (strlen(tok)+1==max_len) {
tok=realloc(tok,sizeof(char)*(max_len+32));
max_len+=32;
}
append(tok,strtok_str[strtok_index]);
}
strtok_index++;
return tok;
}

17
libc/string.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef STRING_H
#define STRING_H
#include <stddef.h>
void* memcpy(void* dest,const void* src,size_t len);
void* memset(void* dest,int val,size_t len);
int strcmp(const char* s1,const char* s2);
size_t strlen(const char* str);
char* strcpy(char* dest,const char* src);
char* strtok(char* str, const char* delim);
char* strrev(char *str);
void int_to_ascii(int n,char* str);
void hex_to_ascii(int n, char* str);
void append(char* s, char n);
void backspace(char* s);
#endif

32
linker.ld Normal file
View File

@ -0,0 +1,32 @@
ENTRY (_start)
SECTIONS
{
/* The kernel will live at 3GB + 1MB in the virtual address space, */
/* which will be mapped to 1MB in the physical address space. */
/* Note that we page-align the sections. */
. = 0xC0100000;
/* Add a symbol that indicates the start address of the kernel. */
_kernel_start = .;
.text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000)
{
*(.multiboot)
*(.text)
}
.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
{
*(.rodata)
}
.data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
{
*(.data)
}
.bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000)
{
*(COMMON)
*(.bss)
*(.bootstrap_stack)
}
/* Add a symbol that indicates the end address of the kernel. */
_kernel_end = .;
}

33
log Normal file
View File

@ -0,0 +1,33 @@
[INFO] First PS/2 port OK
[INFO] Keyboard on PS/2 port 1
[INFO] Registered keyboard driver on PS/2 port 1
[INFO] Finished initializing PS/2 driver
[INFO] Scanning for serial ports
[INFO] Found COM1
[INFO] Found COM2
[INFO] Scanning for parallel ports
[INFO] Found LPT1
[INFO] Found PCI device. Class code:0x6, Subclass:0x0 Prog IF:0x0
[INFO] Found PCI device. Class code:0x6, Subclass:0x1 Prog IF:0x0
[INFO] Found PCI device. Class code:0x1, Subclass:0x1 Prog IF:0x80
[INFO] Found PCI device. Class code:0x6, Subclass:0x80 Prog IF:0x0
[INFO] Found PCI device. Class code:0x3, Subclass:0x0 Prog IF:0x0
[INFO] Found PCI device. Class code:0x2, Subclass:0x0 Prog IF:0x0
[INFO] Found network controller, detecting type
[INFO] Unknown network card
>pci list (Shows PCI devices and types)
PCI device 0:
Main class:Bridge
PCI device 1:
Main class:Bridge
PCI device 2:
Main class:Storage
PCI device 3:
Main class:Bridge
PCI device 4:
Main class:Display
PCI device 5:
Main class:Network
>cat /hi.txt (Outputs contents of file)
Hello!
This is hi.txt!

14
makeinitrd.rb Normal file
View File

@ -0,0 +1,14 @@
folder=ARGV[0]
output=ARGV[1]
outf=File.open(output,"w")
for name in Dir.glob("#{folder}/*")
name=File.basename(name)
contents=File.read("#{folder}/#{name}")
outf.print [name.length].pack("L")
outf.print name
outf.print "\0"
outf.print [contents.length].pack("L")
outf.print contents
end
outf.print [0].pack("L")
outf.close

65
network.rb Normal file
View File

@ -0,0 +1,65 @@
require "socket"
s=TCPServer.new("localhost",3000)
c=s.accept
udpsocks=[]
tcpsocks=[]
next_sock=0
puts "Connection established"
while true
ch=c.getc
if ch==nil
next
end
cmd=ch.ord
if cmd==0
c.print [192,168,0,10].pack("CCCC")
end
if cmd==1
sock=UDPSocket.new()
sock.bind("10.0.0.180",0)
c.print [next_sock,sock.addr[1]].pack("L<L<")
udpsocks[next_sock]=sock
next_sock+=1;
end
if cmd==4
info=c.read(12).unpack("L<CCCCS<S<")
msg=c.read(info[6])
udpsocks[info[0]].send(msg,0,"#{info[1]}.#{info[2]}.#{info[3]}.#{info[4]}",info[5])
end
if cmd==5
id=c.read(4).unpack("L<")[0]
msg=udpsocks[id].recv(65536)
if msg==""
c.print [0].pack("L<")
else
c.print [msg.length].pack("L<")
c.print msg
end
end
if cmd==6
id=c.read(4).unpack("L<")[0]
udpsocks[id]=nil
end
if cmd==7
info=c.read(6).unpack("CCCCS<")
sock=TCPSocket.new("#{info[0]}.#{info[1]}.#{info[2]}.#{info[3]}",info[4])
c.print [next_sock].pack("L<")
tcpsocks[next_sock]=sock
next_sock+=1;
end
if cmd==8
info=c.read(6).unpack("L<S<")
msg=c.read(info[1])
tcpsocks[info[0]].print msg
end
if cmd==9
id=c.read(4).unpack("L<")[0]
if !tcpsocks[id].ready? and tcpsocks[id].closed?
c.print [0].pack("L<")
else
msg=tcpsocks[id].gets
c.print [msg.length].pack("L<")
c.print msg
end
end
end

0
os Normal file
View File

1
psinfo/i386/cc.txt Normal file
View File

@ -0,0 +1 @@
i386-elf-gcc

1
psinfo/i386/gdb.txt Normal file
View File

@ -0,0 +1 @@
i386-elf-gdb

2
psinfo/i386/o.txt Normal file
View File

@ -0,0 +1,2 @@
cpu/i386/paging_helpers.o
kernel/boot.o

56
qemu.log Normal file
View File

@ -0,0 +1,56 @@
CPU Reset (CPU 0)
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=00000000 EFL=00000000 [-------] CPL=0 II=0 A20=0 SMM=0 HLT=0
ES =0000 00000000 00000000 00000000
CS =0000 00000000 00000000 00000000
SS =0000 00000000 00000000 00000000
DS =0000 00000000 00000000 00000000
FS =0000 00000000 00000000 00000000
GS =0000 00000000 00000000 00000000
LDT=0000 00000000 00000000 00000000
TR =0000 00000000 00000000 00000000
GDT= 00000000 00000000
IDT= 00000000 00000000
CR0=00000000 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=00000000 DR7=00000000
CCS=00000000 CCD=00000000 CCO=DYNAMIC
EFER=0000000000000000
FCW=0000 FSW=0000 [ST=0] FTW=ff MXCSR=00000000
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
CPU Reset (CPU 0)
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000663
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=0000fff0 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 0000ffff 00009300
CS =f000 ffff0000 0000ffff 00009b00
SS =0000 00000000 0000ffff 00009300
DS =0000 00000000 0000ffff 00009300
FS =0000 00000000 0000ffff 00009300
GS =0000 00000000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT= 00000000 0000ffff
IDT= 00000000 0000ffff
CR0=60000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=00000000 CCO=DYNAMIC
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000