commit ef90f516884b619dff3d686450b6ad39438d9a66 Author: pjht Date: Sat Feb 9 12:52:45 2019 -0600 Remove most code for a blank start diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1f6fb0f --- /dev/null +++ b/.gitattributes @@ -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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5d76e48 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +*.bin +*.dis +*.o +*.elf +*/*.o +bochsout.txt +stuff/* +cpu/memory.h +os.iso +disk.img diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ed426d4 --- /dev/null +++ b/Makefile @@ -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 diff --git a/bochsrc.txt b/bochsrc.txt new file mode 100644 index 0000000..b25cda2 --- /dev/null +++ b/bochsrc.txt @@ -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 diff --git a/cpu/cpu_init.h b/cpu/cpu_init.h new file mode 100644 index 0000000..392020c --- /dev/null +++ b/cpu/cpu_init.h @@ -0,0 +1,6 @@ +#ifndef CPU_INIT_H +#define CPU_INIT_H + +void cpu_init(); + +#endif diff --git a/cpu/halt.h b/cpu/halt.h new file mode 100644 index 0000000..219aaa7 --- /dev/null +++ b/cpu/halt.h @@ -0,0 +1,6 @@ +#ifndef HALT_H +#define HALT_H + +void halt() __attribute__((noreturn)); + +#endif diff --git a/cpu/i386/cpu_init.c b/cpu/i386/cpu_init.c new file mode 100644 index 0000000..e662164 --- /dev/null +++ b/cpu/i386/cpu_init.c @@ -0,0 +1,2 @@ +void cpu_init() { +} diff --git a/cpu/i386/halt.c b/cpu/i386/halt.c new file mode 100644 index 0000000..004c90b --- /dev/null +++ b/cpu/i386/halt.c @@ -0,0 +1,5 @@ +void halt() { + asm volatile("cli;\ + hltlabel: hlt;\ + jmp hltlabel"); +} diff --git a/cpu/i386/memory.c b/cpu/i386/memory.c new file mode 100644 index 0000000..8546a0b --- /dev/null +++ b/cpu/i386/memory.c @@ -0,0 +1,6 @@ +#include "paging.h" +#include + +void* alloc_memory(uint32_t num_blocks) { + return alloc_kern_pages(num_blocks,1); +} diff --git a/cpu/i386/memory.h b/cpu/i386/memory.h new file mode 100644 index 0000000..204a502 --- /dev/null +++ b/cpu/i386/memory.h @@ -0,0 +1,9 @@ +#ifndef CPU_MEMORY_H +#define CPU_MEMORY_H + +#include +#define BLK_SZ 4096 + +void* alloc_memory(uint32_t blocks); + +#endif diff --git a/cpu/i386/paging.c b/cpu/i386/paging.c new file mode 100644 index 0000000..9225c5d --- /dev/null +++ b/cpu/i386/paging.c @@ -0,0 +1,70 @@ +#include +#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)); +} diff --git a/cpu/i386/paging.h b/cpu/i386/paging.h new file mode 100644 index 0000000..c8b370d --- /dev/null +++ b/cpu/i386/paging.h @@ -0,0 +1,21 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +#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 diff --git a/cpu/i386/paging_helpers.asm b/cpu/i386/paging_helpers.asm new file mode 100644 index 0000000..d27ee3d --- /dev/null +++ b/cpu/i386/paging_helpers.asm @@ -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 diff --git a/cpu/i386/paging_helpers.h b/cpu/i386/paging_helpers.h new file mode 100644 index 0000000..26b65ed --- /dev/null +++ b/cpu/i386/paging_helpers.h @@ -0,0 +1,6 @@ +#ifndef PAGING_HELPERS_H +#define PAGING_HELPERS_H + +void load_page_directory(uint32_t* dir); + +#endif diff --git a/cpu/i386/ports.c b/cpu/i386/ports.c new file mode 100644 index 0000000..769be8b --- /dev/null +++ b/cpu/i386/ports.c @@ -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)); +} diff --git a/cpu/i386/ports.h b/cpu/i386/ports.h new file mode 100644 index 0000000..33bcca1 --- /dev/null +++ b/cpu/i386/ports.h @@ -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 diff --git a/drivers/parallel.h b/drivers/parallel.h new file mode 100644 index 0000000..388ba0f --- /dev/null +++ b/drivers/parallel.h @@ -0,0 +1,6 @@ +#ifndef PARALLEL_H +#define PARALLEL_H + +void parallel_init(); + +#endif diff --git a/drivers/pci.h b/drivers/pci.h new file mode 100644 index 0000000..2e2e3c2 --- /dev/null +++ b/drivers/pci.h @@ -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 diff --git a/drivers/ps2.h b/drivers/ps2.h new file mode 100644 index 0000000..e98c5c2 --- /dev/null +++ b/drivers/ps2.h @@ -0,0 +1,6 @@ +#ifndef PS2_EXT_H +#define PS2_EXT_H + +void ps2_init(); + +#endif diff --git a/drivers/screen.h b/drivers/screen.h new file mode 100644 index 0000000..35777a0 --- /dev/null +++ b/drivers/screen.h @@ -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 diff --git a/drivers/serial.h b/drivers/serial.h new file mode 100644 index 0000000..cacaaf4 --- /dev/null +++ b/drivers/serial.h @@ -0,0 +1,7 @@ +#ifndef SERIAL_H +#define SERIAL_H +#include + +void serial_init(); + +#endif diff --git a/drivers/timer.h b/drivers/timer.h new file mode 100644 index 0000000..6967145 --- /dev/null +++ b/drivers/timer.h @@ -0,0 +1,7 @@ +#ifndef TIMER_H +#define TIMER_H + +void wait(int milli); +void timer_init(); + +#endif diff --git a/dump.dat b/dump.dat new file mode 100644 index 0000000..e913196 Binary files /dev/null and b/dump.dat differ diff --git a/fs/devfs.c b/fs/devfs.c new file mode 100644 index 0000000..9000c1d --- /dev/null +++ b/fs/devfs.c @@ -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;ipath)==0) { +// return 1; +// } +// } +// return 0; +// } +// if (op==FSOP_GETC) { +// int i; +// for (i=0;ipath)==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;ipath)==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++; +// } diff --git a/fs/devfs.h b/fs/devfs.h new file mode 100644 index 0000000..6c13539 --- /dev/null +++ b/fs/devfs.h @@ -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 diff --git a/fs/initrd.c b/fs/initrd.c new file mode 100644 index 0000000..3a20a22 --- /dev/null +++ b/fs/initrd.c @@ -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;ipath)==0) { +// file_exists=1; +// } +// } +// return file_exists; +// } +// if (op==FSOP_GETC) { +// int i; +// for (i=0;ipath)==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"); +// } diff --git a/fs/initrd.h b/fs/initrd.h new file mode 100644 index 0000000..e421fa2 --- /dev/null +++ b/fs/initrd.h @@ -0,0 +1,6 @@ +#ifndef INITRD_H +#define INITRD_H + +uint32_t init_initrd(); + +#endif diff --git a/initrd/hi.txt b/initrd/hi.txt new file mode 100644 index 0000000..0cfe9af --- /dev/null +++ b/initrd/hi.txt @@ -0,0 +1,2 @@ +Hello! +This is hi.txt! diff --git a/initrd/myfile.txt b/initrd/myfile.txt new file mode 100644 index 0000000..d4a2d15 --- /dev/null +++ b/initrd/myfile.txt @@ -0,0 +1 @@ +This is another file! diff --git a/initrd/test.txt b/initrd/test.txt new file mode 100644 index 0000000..50fcd26 --- /dev/null +++ b/initrd/test.txt @@ -0,0 +1 @@ +File 1 diff --git a/iso/boot/grub/grub.cfg b/iso/boot/grub/grub.cfg new file mode 100644 index 0000000..0b34afe --- /dev/null +++ b/iso/boot/grub/grub.cfg @@ -0,0 +1,7 @@ +timeout=0 + +menuentry "My OS" { + multiboot /boot/kernel.elf + module /boot/initrd initrd + boot +} diff --git a/iso/boot/initrd b/iso/boot/initrd new file mode 100644 index 0000000..c5e7ac3 Binary files /dev/null and b/iso/boot/initrd differ diff --git a/kernel/boot.s b/kernel/boot.s new file mode 100644 index 0000000..ee514c1 --- /dev/null +++ b/kernel/boot.s @@ -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 diff --git a/kernel/kernel.c b/kernel/kernel.c new file mode 100644 index 0000000..da92200 --- /dev/null +++ b/kernel/kernel.c @@ -0,0 +1,5 @@ +#include "../cpu/cpu_init.h" + +void kmain() { + cpu_init(); +} diff --git a/libc/devbuf.c b/libc/devbuf.c new file mode 100644 index 0000000..7097c72 --- /dev/null +++ b/libc/devbuf.c @@ -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; +} diff --git a/libc/devbuf.h b/libc/devbuf.h new file mode 100644 index 0000000..785e978 --- /dev/null +++ b/libc/devbuf.h @@ -0,0 +1,16 @@ +#ifndef DEVBUF_H +#define DEVBUF_H + +#include + +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 diff --git a/libc/math.c b/libc/math.c new file mode 100644 index 0000000..d3cdb28 --- /dev/null +++ b/libc/math.c @@ -0,0 +1,7 @@ +float ceilf(float num) { + int inum=(int)num; + if (num==(float)inum) { + return (float)inum; + } + return (float)(inum+1); +} diff --git a/libc/math.h b/libc/math.h new file mode 100644 index 0000000..e1dec07 --- /dev/null +++ b/libc/math.h @@ -0,0 +1,6 @@ +#ifndef MATH_H +#define MATH_H + +float ceilf(float num); + +#endif diff --git a/libc/stdio.h b/libc/stdio.h new file mode 100644 index 0000000..cde815a --- /dev/null +++ b/libc/stdio.h @@ -0,0 +1,40 @@ +#ifndef STDIO_H +#define STDIO_H + +#include +#include +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 diff --git a/libc/stdlib.c b/libc/stdlib.c new file mode 100644 index 0000000..c66921a --- /dev/null +++ b/libc/stdlib.c @@ -0,0 +1,142 @@ +#include "../cpu/memory.h" +#include "string.h" +#include "stdlib.h" +#include "math.h" +#include +#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<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<=size) { + char* bmap=entry.bitmap; + uint32_t bmap_byt_sz=entry.bitmap_byt_size; + for(int i=0;i +#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 diff --git a/libc/string.c b/libc/string.c new file mode 100644 index 0000000..2969177 --- /dev/null +++ b/libc/string.c @@ -0,0 +1,137 @@ +#include "string.h" +#include +#include +#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 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;istrlen(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; +} diff --git a/libc/string.h b/libc/string.h new file mode 100644 index 0000000..d1fb59e --- /dev/null +++ b/libc/string.h @@ -0,0 +1,17 @@ +#ifndef STRING_H +#define STRING_H +#include + +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 diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..38b8abe --- /dev/null +++ b/linker.ld @@ -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 = .; +} diff --git a/log b/log new file mode 100644 index 0000000..999565b --- /dev/null +++ b/log @@ -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! diff --git a/makeinitrd.rb b/makeinitrd.rb new file mode 100644 index 0000000..ca1d441 --- /dev/null +++ b/makeinitrd.rb @@ -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 diff --git a/network.rb b/network.rb new file mode 100644 index 0000000..3070be5 --- /dev/null +++ b/network.rb @@ -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