diff --git a/cpu/x86_64/boot.asm b/cpu/x86_64/boot.asm new file mode 100644 index 0000000..5e57b88 --- /dev/null +++ b/cpu/x86_64/boot.asm @@ -0,0 +1,101 @@ +section .multiboot_header +header_start: + dd 0xe85250d6 ; magic number (multiboot 2) + dd 0 ; architecture 0 (protected mode i386) + dd header_end - header_start ; header length + ; checksum + dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) + + ; insert optional multiboot tags here + + ; required end tag + dw 0 ; type + dw 0 ; flags + dd 8 ; size +header_end: + +global start + +section .text +bits 32 +start: + mov esp, stack_top + call check_multiboot + call check_cpuid + call check_long_mode + ; print `OK` to screen + mov dword [0xb8000], 0x2f4b2f4f + hlt + +check_multiboot: + cmp eax, 0x36d76289 + jne .no_multiboot + ret +.no_multiboot: + mov al, "0" + jmp error + +check_cpuid: + ; Check if CPUID is supported by attempting to flip the ID bit (bit 21) + ; in the FLAGS register. If we can flip it, CPUID is available. + + ; Copy FLAGS in to EAX via stack + pushfd + pop eax + + ; Copy to ECX as well for comparing later on + mov ecx, eax + + ; Flip the ID bit + xor eax, 1 << 21 + + ; Copy EAX to FLAGS via the stack + push eax + popfd + + ; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported) + pushfd + pop eax + + ; Restore FLAGS from the old version stored in ECX (i.e. flipping the + ; ID bit back if it was ever flipped). + push ecx + popfd + + ; Compare EAX and ECX. If they are equal then that means the bit + ; wasn't flipped, and CPUID isn't supported. + cmp eax, ecx + je .no_cpuid + ret +.no_cpuid: + mov al, "1" + jmp error + +check_long_mode: + ; test if extended processor info in available + mov eax, 0x80000000 ; implicit argument for cpuid + cpuid ; get highest supported argument + cmp eax, 0x80000001 ; it needs to be at least 0x80000001 + jb .no_long_mode ; if it's less, the CPU is too old for long mode + + ; use extended info to test if long mode is available + mov eax, 0x80000001 ; argument for extended processor info + cpuid ; returns various feature bits in ecx and edx + test edx, 1 << 29 ; test if the LM-bit is set in the D-register + jz .no_long_mode ; If it's not set, there is no long mode + ret +.no_long_mode: + mov al, "2" + jmp error + +error: + mov dword [0xb8000], 0x4f524f45 + mov dword [0xb8004], 0x4f3a4f52 + mov dword [0xb8008], 0x4f204f20 + mov byte [0xb800a], al + hlt + +section .bss +stack_bottom: + resb 16*4096 +stack_top: diff --git a/cpu/x86_64/linker.ld b/cpu/x86_64/linker.ld new file mode 100644 index 0000000..1fbea46 --- /dev/null +++ b/cpu/x86_64/linker.ld @@ -0,0 +1,16 @@ +ENTRY(start) + +SECTIONS { + . = 1M; + + .boot : + { + /* ensure that the multiboot header is at the beginning */ + *(.multiboot_header) + } + + .text : + { + *(.text) + } +} diff --git a/iso/boot/grub/grub.cfg b/iso/boot/grub/grub.cfg index 0b34afe..a60949f 100644 --- a/iso/boot/grub/grub.cfg +++ b/iso/boot/grub/grub.cfg @@ -1,7 +1,7 @@ timeout=0 menuentry "My OS" { - multiboot /boot/kernel.elf + multiboot2 /boot/kernel.elf module /boot/initrd initrd boot } diff --git a/kernel/kernel.c b/kernel/kernel.c index 83146a2..28632f4 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,150 +1,151 @@ -#include "../cpu/cpu_init.h" -#include "../drivers/vga.h" -#include "../drivers/pci.h" -#include "../drivers/serial.h" -#include "../cpu/i386/ports.h" -#include "vfs.h" -#include "../fs/devfs.h" -#include "../fs/initrd.h" -#include -#include -#include -#include -#include +// #include "../cpu/cpu_init.h" +// #include "../drivers/vga.h" +// #include "../drivers/pci.h" +// #include "../drivers/serial.h" +// #include "../cpu/i386/ports.h" +// #include "vfs.h" +// #include "../fs/devfs.h" +// #include "../fs/initrd.h" +// #include +// #include +// #include +// #include +// #include #include -#include "klog.h" -#include "elf.h" -#include -#include "../drivers/ide.h" -#include "parts.h" -#include "../fs/ext2.h" - -static long initrd_sz; -static char* initrd; -static multiboot_info_t* mbd; -typedef int (*func_ptr)(); - -static int console_dev_drv(char* filename,int c,long pos,char wr) { - if (wr) { - if (c=='\f') { - vga_clear(); - } else if (c=='\b') { - vga_backspace(); - } - char str[2]; - str[0]=(char)c; - str[1]='\0'; - vga_write_string(str); - return 0; - } else { - return 0; - // return devbuf_get(kbd_buf); - } -} - -static int initrd_dev_drv(char* filename,int c,long pos,char wr) { - if (wr) { - return 0; - } - if (pos>=initrd_sz) { - return EOF; - } - return initrd[pos]; -} - -static void read_initrd(multiboot_info_t* mbd) { - if ((mbd->flags&MULTIBOOT_INFO_MODS)!=0) { - uint32_t mods_count=mbd->mods_count; - if (mods_count>0) { - while (mods_count>0) { - multiboot_module_t* mods_addr=(multiboot_module_t*)(mbd->mods_addr+0xC0000000); - if (strcmp((char*)(mods_addr->cmdline+0xC0000000),"initrd")==0) { - initrd=malloc(sizeof(char)*(mods_addr->mod_end-mods_addr->mod_start)); - initrd_sz=(mods_addr->mod_end-mods_addr->mod_start); - memcpy(initrd,(void*)mods_addr->mod_start+0xC0000000,initrd_sz); - }; - mods_count--; - } - } - } else { - klog("PANIC","Cannnot load initrd. No modules found!"); - for(;;) {} - } - if (!initrd) { - klog("PANIC","Cannnot load initrd. Initrd module not found!"); - for(;;) {} - } -} - -static void init() { - init_vfs(); - init_devfs(); - devfs_add(console_dev_drv,"console"); - stdout=fopen("/dev/console","w"); - stdin=fopen("/dev/console","r"); - stderr=fopen("/dev/console","w"); - read_initrd(mbd); - devfs_add(initrd_dev_drv,"initrd"); - initrd_init(); - mount("/initrd/","","initrd"); - // Detect PCI - port_long_out(0xCF8,(1<<31)); - uint32_t word=port_long_in(0xCFC); - port_long_out(0xCF8,(1<<31)|0x4); - if (word!=port_long_in(0xCFC)) { - // pci_init(); - } - // Detect and initailize serial ports - serial_init(); - FILE* file=fopen("/initrd/prog.elf","r"); - elf_header header; - fread(&header,sizeof(elf_header),1,file); - if (header.magic!=ELF_MAGIC) { - klog("INFO","Invalid magic number for prog.elf"); - fclose(file); - } else { - fseek(file,header.prog_hdr,SEEK_SET); - elf_pheader pheader; - fread(&pheader,sizeof(elf_pheader),1,file); - alloc_memory_virt(1,(void*)pheader.vaddr); - fseek(file,pheader.offset,SEEK_SET); - fread((void*)pheader.vaddr,pheader.filesz,1,file); - klog("INFO","VADDR:%x",pheader.vaddr); - func_ptr prog=(func_ptr)header.entry; - int val=prog(); - klog("INFO","RAN PROG:%d",val); - } - ide_init(); - load_parts("/dev/hda"); - init_ext2(); - mount("/","/dev/hda1","ext2"); - klog("INFO","MOUNT"); - FILE* f=fopen("/file","r"); - char str[256]; - fgets(str,256,f); - str[strlen(str)-1]='\0'; - klog("INFO","Got string %s",str); - for(;;) { - yield(); - } -} - +// #include "klog.h" +// #include "elf.h" +// #include +// #include "../drivers/ide.h" +// #include "parts.h" +// #include "../fs/ext2.h" +// +// static long initrd_sz; +// static char* initrd; +// static multiboot_info_t* mbd; +// typedef int (*func_ptr)(); +// +// static int console_dev_drv(char* filename,int c,long pos,char wr) { +// if (wr) { +// if (c=='\f') { +// vga_clear(); +// } else if (c=='\b') { +// vga_backspace(); +// } +// char str[2]; +// str[0]=(char)c; +// str[1]='\0'; +// vga_write_string(str); +// return 0; +// } else { +// return 0; +// // return devbuf_get(kbd_buf); +// } +// } +// +// static int initrd_dev_drv(char* filename,int c,long pos,char wr) { +// if (wr) { +// return 0; +// } +// if (pos>=initrd_sz) { +// return EOF; +// } +// return initrd[pos]; +// } +// +// static void read_initrd(multiboot_info_t* mbd) { +// if ((mbd->flags&MULTIBOOT_INFO_MODS)!=0) { +// uint32_t mods_count=mbd->mods_count; +// if (mods_count>0) { +// while (mods_count>0) { +// multiboot_module_t* mods_addr=(multiboot_module_t*)(mbd->mods_addr+0xC0000000); +// if (strcmp((char*)(mods_addr->cmdline+0xC0000000),"initrd")==0) { +// initrd=malloc(sizeof(char)*(mods_addr->mod_end-mods_addr->mod_start)); +// initrd_sz=(mods_addr->mod_end-mods_addr->mod_start); +// memcpy(initrd,(void*)mods_addr->mod_start+0xC0000000,initrd_sz); +// }; +// mods_count--; +// } +// } +// } else { +// klog("PANIC","Cannnot load initrd. No modules found!"); +// for(;;) {} +// } +// if (!initrd) { +// klog("PANIC","Cannnot load initrd. Initrd module not found!"); +// for(;;) {} +// } +// } +// +// static void init() { +// init_vfs(); +// init_devfs(); +// devfs_add(console_dev_drv,"console"); +// stdout=fopen("/dev/console","w"); +// stdin=fopen("/dev/console","r"); +// stderr=fopen("/dev/console","w"); +// read_initrd(mbd); +// devfs_add(initrd_dev_drv,"initrd"); +// initrd_init(); +// mount("/initrd/","","initrd"); +// // Detect PCI +// port_long_out(0xCF8,(1<<31)); +// uint32_t word=port_long_in(0xCFC); +// port_long_out(0xCF8,(1<<31)|0x4); +// if (word!=port_long_in(0xCFC)) { +// // pci_init(); +// } +// // Detect and initailize serial ports +// serial_init(); +// FILE* file=fopen("/initrd/prog.elf","r"); +// elf_header header; +// fread(&header,sizeof(elf_header),1,file); +// if (header.magic!=ELF_MAGIC) { +// klog("INFO","Invalid magic number for prog.elf"); +// fclose(file); +// } else { +// fseek(file,header.prog_hdr,SEEK_SET); +// elf_pheader pheader; +// fread(&pheader,sizeof(elf_pheader),1,file); +// alloc_memory_virt(1,(void*)pheader.vaddr); +// fseek(file,pheader.offset,SEEK_SET); +// fread((void*)pheader.vaddr,pheader.filesz,1,file); +// klog("INFO","VADDR:%x",pheader.vaddr); +// func_ptr prog=(func_ptr)header.entry; +// int val=prog(); +// klog("INFO","RAN PROG:%d",val); +// } +// ide_init(); +// load_parts("/dev/hda"); +// init_ext2(); +// mount("/","/dev/hda1","ext2"); +// klog("INFO","MOUNT"); +// FILE* f=fopen("/file","r"); +// char str[256]; +// fgets(str,256,f); +// str[strlen(str)-1]='\0'; +// klog("INFO","Got string %s",str); +// for(;;) { +// yield(); +// } +// } +// void kmain(multiboot_info_t* header) { - mbd=header; - cpu_init(mbd); - text_fb_info info; - if (header->flags&MULTIBOOT_INFO_FRAMEBUFFER_INFO&&header->framebuffer_type==2) { - info.address=(char*)(((uint32_t)header->framebuffer_addr&0xFFFFFFFF)+0xC0000000); - info.width=header->framebuffer_width; - info.height=header->framebuffer_height; - } else { - info.address=(char*)0xC00B8000; - info.width=80; - info.height=25; - } - vga_init(info); - createTask(init); - for (;;) { - yield(); - } + // mbd=header; + // cpu_init(mbd); + // text_fb_info info; + // if (header->flags&MULTIBOOT_INFO_FRAMEBUFFER_INFO&&header->framebuffer_type==2) { + // info.address=(char*)(((uint32_t)header->framebuffer_addr&0xFFFFFFFF)+0xC0000000); + // info.width=header->framebuffer_width; + // info.height=header->framebuffer_height; + // } else { + // info.address=(char*)0xC00B8000; + // info.width=80; + // info.height=25; + // } + // vga_init(info); + // createTask(init); + // for (;;) { + // yield(); + // } + for(;;); } diff --git a/prog/Makefile b/prog/Makefile index 45dbf34..505d62a 100644 --- a/prog/Makefile +++ b/prog/Makefile @@ -5,6 +5,7 @@ CC = i386-elf-gcc prog.elf: $(OBJ) i386-elf-ld -o $@ $^ + rm -rf *.o %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ diff --git a/psinfo/x86_64/ar.txt b/psinfo/x86_64/ar.txt new file mode 100644 index 0000000..e995c6e --- /dev/null +++ b/psinfo/x86_64/ar.txt @@ -0,0 +1 @@ +/Users/peterterpstra/x86_64-elf/bin/x86_64-elf-ar diff --git a/psinfo/x86_64/as.txt b/psinfo/x86_64/as.txt new file mode 100644 index 0000000..c5a7c7f --- /dev/null +++ b/psinfo/x86_64/as.txt @@ -0,0 +1 @@ +/Users/peterterpstra/x86_64-elf/bin/x86_64-elf-as diff --git a/psinfo/x86_64/cc.txt b/psinfo/x86_64/cc.txt new file mode 100644 index 0000000..a3a5480 --- /dev/null +++ b/psinfo/x86_64/cc.txt @@ -0,0 +1 @@ +/Users/peterterpstra/x86_64-elf/bin/x86_64-elf-gcc diff --git a/psinfo/x86_64/emu.txt b/psinfo/x86_64/emu.txt new file mode 100644 index 0000000..0e38e1b --- /dev/null +++ b/psinfo/x86_64/emu.txt @@ -0,0 +1 @@ +qemu-system-x86_64 diff --git a/psinfo/x86_64/gdb.txt b/psinfo/x86_64/gdb.txt new file mode 100644 index 0000000..be4dcb4 --- /dev/null +++ b/psinfo/x86_64/gdb.txt @@ -0,0 +1 @@ +/Users/peterterpstra/x86_64-elf/bin/x86_64-elf-gdb diff --git a/psinfo/x86_64/nasm.txt b/psinfo/x86_64/nasm.txt new file mode 100644 index 0000000..3a9d2b0 --- /dev/null +++ b/psinfo/x86_64/nasm.txt @@ -0,0 +1 @@ +nasm -felf64