Remove most code for a blank start
This commit is contained in:
commit
ef90f51688
3
.gitattributes
vendored
Normal file
3
.gitattributes
vendored
Normal 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
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
*.bin
|
||||||
|
*.dis
|
||||||
|
*.o
|
||||||
|
*.elf
|
||||||
|
*/*.o
|
||||||
|
bochsout.txt
|
||||||
|
stuff/*
|
||||||
|
cpu/memory.h
|
||||||
|
os.iso
|
||||||
|
disk.img
|
45
Makefile
Normal file
45
Makefile
Normal 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
57
bochsrc.txt
Normal 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
6
cpu/cpu_init.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef CPU_INIT_H
|
||||||
|
#define CPU_INIT_H
|
||||||
|
|
||||||
|
void cpu_init();
|
||||||
|
|
||||||
|
#endif
|
6
cpu/halt.h
Normal file
6
cpu/halt.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef HALT_H
|
||||||
|
#define HALT_H
|
||||||
|
|
||||||
|
void halt() __attribute__((noreturn));
|
||||||
|
|
||||||
|
#endif
|
2
cpu/i386/cpu_init.c
Normal file
2
cpu/i386/cpu_init.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
void cpu_init() {
|
||||||
|
}
|
5
cpu/i386/halt.c
Normal file
5
cpu/i386/halt.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
void halt() {
|
||||||
|
asm volatile("cli;\
|
||||||
|
hltlabel: hlt;\
|
||||||
|
jmp hltlabel");
|
||||||
|
}
|
6
cpu/i386/memory.c
Normal file
6
cpu/i386/memory.c
Normal 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
9
cpu/i386/memory.h
Normal 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
70
cpu/i386/paging.c
Normal 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
21
cpu/i386/paging.h
Normal 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
|
9
cpu/i386/paging_helpers.asm
Normal file
9
cpu/i386/paging_helpers.asm
Normal 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
|
6
cpu/i386/paging_helpers.h
Normal file
6
cpu/i386/paging_helpers.h
Normal 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
29
cpu/i386/ports.c
Normal 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
10
cpu/i386/ports.h
Normal 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
6
drivers/parallel.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef PARALLEL_H
|
||||||
|
#define PARALLEL_H
|
||||||
|
|
||||||
|
void parallel_init();
|
||||||
|
|
||||||
|
#endif
|
44
drivers/pci.h
Normal file
44
drivers/pci.h
Normal 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
6
drivers/ps2.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef PS2_EXT_H
|
||||||
|
#define PS2_EXT_H
|
||||||
|
|
||||||
|
void ps2_init();
|
||||||
|
|
||||||
|
#endif
|
9
drivers/screen.h
Normal file
9
drivers/screen.h
Normal 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
7
drivers/serial.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef SERIAL_H
|
||||||
|
#define SERIAL_H
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void serial_init();
|
||||||
|
|
||||||
|
#endif
|
7
drivers/timer.h
Normal file
7
drivers/timer.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef TIMER_H
|
||||||
|
#define TIMER_H
|
||||||
|
|
||||||
|
void wait(int milli);
|
||||||
|
void timer_init();
|
||||||
|
|
||||||
|
#endif
|
71
fs/devfs.c
Normal file
71
fs/devfs.c
Normal 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
8
fs/devfs.h
Normal 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
85
fs/initrd.c
Normal 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
6
fs/initrd.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef INITRD_H
|
||||||
|
#define INITRD_H
|
||||||
|
|
||||||
|
uint32_t init_initrd();
|
||||||
|
|
||||||
|
#endif
|
2
initrd/hi.txt
Normal file
2
initrd/hi.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Hello!
|
||||||
|
This is hi.txt!
|
1
initrd/myfile.txt
Normal file
1
initrd/myfile.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
This is another file!
|
1
initrd/test.txt
Normal file
1
initrd/test.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
File 1
|
7
iso/boot/grub/grub.cfg
Normal file
7
iso/boot/grub/grub.cfg
Normal 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
BIN
iso/boot/initrd
Normal file
Binary file not shown.
126
kernel/boot.s
Normal file
126
kernel/boot.s
Normal 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
5
kernel/kernel.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "../cpu/cpu_init.h"
|
||||||
|
|
||||||
|
void kmain() {
|
||||||
|
cpu_init();
|
||||||
|
}
|
37
libc/devbuf.c
Normal file
37
libc/devbuf.c
Normal 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
16
libc/devbuf.h
Normal 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
7
libc/math.c
Normal 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
6
libc/math.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef MATH_H
|
||||||
|
#define MATH_H
|
||||||
|
|
||||||
|
float ceilf(float num);
|
||||||
|
|
||||||
|
#endif
|
40
libc/stdio.h
Normal file
40
libc/stdio.h
Normal 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
142
libc/stdlib.c
Normal 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
12
libc/stdlib.h
Normal 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
137
libc/string.c
Normal 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
17
libc/string.h
Normal 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
32
linker.ld
Normal 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
33
log
Normal 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
14
makeinitrd.rb
Normal 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
65
network.rb
Normal 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
|
1
psinfo/i386/cc.txt
Normal file
1
psinfo/i386/cc.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
i386-elf-gcc
|
1
psinfo/i386/gdb.txt
Normal file
1
psinfo/i386/gdb.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
i386-elf-gdb
|
2
psinfo/i386/o.txt
Normal file
2
psinfo/i386/o.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
cpu/i386/paging_helpers.o
|
||||||
|
kernel/boot.o
|
56
qemu.log
Normal file
56
qemu.log
Normal 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
|
Loading…
Reference in New Issue
Block a user