fixed x86_64

This commit is contained in:
Morten Delenk 2017-04-29 11:25:19 +00:00
parent 3382121c3a
commit e63320f97c
3 changed files with 106 additions and 176 deletions

View file

@ -92,7 +92,7 @@
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 #define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000
#ifndef ASM_FILE #ifndef ASM_FILE
#define multiboot_PACKED __attribute__((packed))
typedef unsigned char multiboot_uint8_t; typedef unsigned char multiboot_uint8_t;
typedef unsigned short multiboot_uint16_t; typedef unsigned short multiboot_uint16_t;
typedef unsigned int multiboot_uint32_t; typedef unsigned int multiboot_uint32_t;
@ -230,7 +230,7 @@ struct multiboot_mmap_entry {
#define MULTIBOOT_MEMORY_NVS 4 #define MULTIBOOT_MEMORY_NVS 4
#define MULTIBOOT_MEMORY_BADRAM 5 #define MULTIBOOT_MEMORY_BADRAM 5
multiboot_uint32_t type; multiboot_uint32_t type;
} GRUB_PACKED; } multiboot_PACKED;
typedef struct multiboot_mmap_entry multiboot_memory_map_t; typedef struct multiboot_mmap_entry multiboot_memory_map_t;
struct multiboot_mod_list { struct multiboot_mod_list {
@ -248,15 +248,15 @@ typedef struct multiboot_mod_list multiboot_module_t;
/* APM BIOS info. */ /* APM BIOS info. */
struct multiboot_apm_info { struct multiboot_apm_info {
grub_uint16_t version; multiboot_uint16_t version;
grub_uint16_t cseg; multiboot_uint16_t cseg;
grub_uint32_t offset; multiboot_uint32_t offset;
grub_uint16_t cseg_16; multiboot_uint16_t cseg_16;
grub_uint16_t dseg; multiboot_uint16_t dseg;
grub_uint16_t flags; multiboot_uint16_t flags;
grub_uint16_t cseg_len; multiboot_uint16_t cseg_len;
grub_uint16_t cseg_16_len; multiboot_uint16_t cseg_16_len;
grub_uint16_t dseg_len; multiboot_uint16_t dseg_len;
}; };
#endif /* ! ASM_FILE */ #endif /* ! ASM_FILE */

View file

@ -1,8 +1,22 @@
#include <config.h>
#include <multiboot.h>
#ifndef ENABLE_FRAMEBUFFER
#include "../../../hw/pc/cgaterm/cgaterm.hpp" #include "../../../hw/pc/cgaterm/cgaterm.hpp"
#else
#include "../../../hw/pc/vesafb/vesafb.hpp"
#endif
#include <base.hpp> #include <base.hpp>
static multiboot_info_t *mb_info;
#ifndef ENABLE_FRAMEBUFFER
CGATerm term; CGATerm term;
#else
VESAfb term(mb_info);
#endif
void main(); void main();
extern "C" void start() { main(); } extern "C" void start(int eax, multiboot_info_t *ebx) {
mb_info = ebx;
main();
}
void drivers_init() { void drivers_init() {
setMainTTY(&term); setMainTTY(&term);
--term; --term;

View file

@ -1,173 +1,89 @@
#define ASM_FILE 1 #define ASM_FILE 1
#include <config.h> #include <config.h>
#include <multiboot.h> #include <multiboot.h>
.code32 .code32.section.text.boot.global _start _start : jmp _start2.align MULTIBOOT_HEADER_ALIGN
.section .text.boot .int MULTIBOOT_HEADER_MAGIC
.global _start #ifndef ENABLE_FRAMEBUFFER
_start: .int 0x0.int -
jmp _start2 (MULTIBOOT_HEADER_MAGIC)
.align MULTIBOOT_HEADER_ALIGN #else
.int MULTIBOOT_HEADER_MAGIC .int 0x7.int -
.int 0x0 (MULTIBOOT_HEADER_MAGIC + 0x7).int 0,
.int -(MULTIBOOT_HEADER_MAGIC) 0, 0, 0, 0.int 0.int 1024, 768,
.align MULTIBOOT_HEADER_ALIGN 24
.extern start #endif
_start2: .align MULTIBOOT_HEADER_ALIGN.extern start _start2 : mov $mb_ptr,
mov $mb_ptr, %edi % edi stosl mov % ebx,
stosl % eax stosl // Store mb stuff
mov %ebx, %eax
stosl // Store mb stuff
#ifdef ENABLE_FPU #ifdef ENABLE_FPU
finit //Enable FPU finit // Enable FPU
#endif #endif
#ifdef ENABLE_SSE #ifdef ENABLE_SSE
//No check for SSE as SSE2+ is always present on x86_64 // No check for SSE as SSE2+ is always present on x86_64
mov %cr0, %eax mov
and $0xFFFB, %ax % cr0,
or $0x2, %ax % eax and $0xFFFB, % ax or $0x2, % ax mov % eax, % cr0 mov % cr4, % eax or $3 << 9, % ax mov % eax,
mov %eax, %cr0 % cr4
mov %cr4, %eax
or $3<<9, %ax
mov %eax, %cr4
#endif #endif
mov $kernel_stack, %esp mov $kernel_stack,
mov $0x80000001, %eax % esp mov $0x80000001, % eax cpuid and $0x20000000,
cpuid % edx // Check if long mode is supported
and $0x20000000, %edx //Check if long mode is supported jz x86_64_err jmp x86_64_OK x86_64_err : cli hlt jmp x86_64_err x86_64_OK :
jz x86_64_err // Assume PAE is supported
jmp x86_64_OK mov $pmfill,
x86_64_err: % esi mov $pagemapL4, % edi movsl movsl mov $pagedirPT, % edi mov $0x87, % eax xor % ebx, % ebx mov $1023,
cli % ecx.ptloop : stosl xchg % eax, % ebx stosl xchg % eax, % ebx add $0x40000000,
hlt % eax jnc.ptloop_nc inc % ebx.ptloop_nc : loop.ptloop mov % cr4, % eax or $0x20, % eax mov % eax,
jmp x86_64_err % cr4 // Activate PAE
x86_64_OK: mov $0xC0000080,
//Assume PAE is supported % ecx rdmsr or $0x00000100,
mov $pmfill, %esi % eax wrmsr // Activate x86_64
mov $pagemapL4, %edi mov $pagemapL4,
movsl % eax mov % eax,
movsl % cr3 // Load page table
mov $pagedirPT, %edi mov
mov $0x87, %eax % cr0,
xor %ebx, %ebx % eax bswap % eax or $0x80, % eax bswap % eax mov % eax,
mov $1023, %ecx % cr0 // Activate paging
.ptloop: lgdt gdtr mov $0x30,
stosl % ax ljmp $0x28,
xchg %eax, %ebx $_start3 // Jump into long mode
stosl .code64 _start3 : mov
xchg %eax, %ebx % ax,
add $0x40000000, %eax % ds mov % ax, % es mov % ax, % fs mov % ax, % gs mov % ax,
jnc .ptloop_nc % ss // Load 64-bit data
inc %ebx mov $mb_ptr,
.ptloop_nc: % rsi lodsl mov % rax, % rdi lodsl mov % rax,
loop .ptloop %
mov %cr4, %eax rsi call start _stop : cli hlt jmp _stop
or $0x20, %eax
mov %eax, %cr4 //Activate PAE
mov $0xC0000080, %ecx
rdmsr
or $0x00000100, %eax
wrmsr //Activate x86_64
mov $pagemapL4, %eax
mov %eax, %cr3 //Load page table
mov %cr0, %eax
bswap %eax
or $0x80, %eax
bswap %eax
mov %eax, %cr0 //Activate paging
lgdt gdtr
mov $0x30, %ax
ljmp $0x28, $_start3 //Jump into long mode
.code64
_start3:
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss //Load 64-bit data
mov $mb_ptr, %rsi
lodsl
mov %rax, %rdi
lodsl
mov %rax, %rsi
call start
_stop:
cli
hlt
jmp _stop
.section.data gdtr :.word 9 *
.section .data 8.int gdt gdt :
gdtr: .quad 0 // NULL
.word 9 * 8 // 32-bit kernel code
.int gdt .word 0xFFFF.word 0x0000.byte 0x00.byte 0x9A.byte
gdt: 0xCF.byte 0x00
.quad 0 //NULL // 32-bit kernel code
//32-bit kernel code .word 0xFFFF.word 0x0000.byte 0x00.byte 0x92.byte
.word 0xFFFF 0xCF.byte 00
.word 0x0000 // 32-bit user code
.byte 0x00 .word 0xFFFF.word 0x0000.byte 0x00.byte 0xFA.byte
.byte 0x9A 0xCF.byte 0x00
.byte 0xCF // 32-bit user data
.byte 0x00 .word 0xFFFF.word 0x0000.byte 0x00.byte 0xF2.byte
//32-bit kernel code 0xCF.byte 00
.word 0xFFFF // 64-bit kernel code
.word 0x0000 .word 0xFFFF.word 0x0000.byte 0x00.byte 0x9B.byte
.byte 0x00 0xAF.byte 0x00
.byte 0x92 // 64-bit kernel code
.byte 0xCF .word 0xFFFF.word 0x0000.byte 0x00.byte 0x93.byte
.byte 00 0xCF.byte 00
//32-bit user code // 64-bit user code
.word 0xFFFF .word 0xFFFF.word 0x0000.byte 0x00.byte 0xFB.byte
.word 0x0000 0xAF.byte 0x00
.byte 0x00 // 64-bit user data
.byte 0xFA .word 0xFFFF.word 0x0000.byte 0x00.byte 0xF3.byte 0xCF.byte 00 pmfill :.int pagedirPT
.byte 0xCF +
.byte 0x00 0x7.int 0.section.bss mb_ptr :.space 16384 kernel_stack :.align 4096 pagemapL4 :.space 4096 pagedirPT :
//32-bit user data .space 4096
.word 0xFFFF
.word 0x0000
.byte 0x00
.byte 0xF2
.byte 0xCF
.byte 00
//64-bit kernel code
.word 0xFFFF
.word 0x0000
.byte 0x00
.byte 0x9B
.byte 0xAF
.byte 0x00
//64-bit kernel code
.word 0xFFFF
.word 0x0000
.byte 0x00
.byte 0x93
.byte 0xCF
.byte 00
//64-bit user code
.word 0xFFFF
.word 0x0000
.byte 0x00
.byte 0xFB
.byte 0xAF
.byte 0x00
//64-bit user data
.word 0xFFFF
.word 0x0000
.byte 0x00
.byte 0xF3
.byte 0xCF
.byte 00
pmfill:
.int pagedirPT + 0x7
.int 0
.section .bss
mb_ptr:
.space 16384
kernel_stack:
.align 4096
pagemapL4:
.space 4096
pagedirPT:
.space 4096