basic 64 bit loading
parent
164ea30d44
commit
1dba384739
|
@ -10,8 +10,8 @@ u32 acpi_find_rsdp(void)
|
|||
|
||||
// Try to find the pointer... apparently it's 16byte-aligned...
|
||||
|
||||
u32 Address = 0;
|
||||
for (u32 Search = 0x000E0000; Search <= 0x000FFFFF; Search += 4)
|
||||
u64 Address = 0;
|
||||
for (u64 Search = 0x000E0000; Search <= 0x000FFFFF; Search += 4)
|
||||
{
|
||||
if (kmemcmp((u8 *)Search, (u8 *)szMagic, 8) == 0)
|
||||
{
|
|
@ -3,15 +3,15 @@
|
|||
#include "Tier0/cpp.h"
|
||||
#include "Tier0/kstdio.h"
|
||||
|
||||
extern u32 g_start_ctors;
|
||||
extern u32 g_end_ctors;
|
||||
extern u64 g_start_ctors;
|
||||
extern u64 g_end_ctors;
|
||||
void CKernelStart(void);
|
||||
|
||||
void cpp_call_ctors(void)
|
||||
{
|
||||
u32 Number = ((void *)&g_end_ctors - (void *)&g_start_ctors) / 4;
|
||||
kprintf("[i] Calling %i constructors before jumping to Tier1..\n", Number);
|
||||
for(u32 *C = (u32*)&g_start_ctors; C < (u32*)&g_end_ctors; ++C)
|
||||
for(u64 *C = (u64*)&g_start_ctors; C < (u64*)&g_end_ctors; ++C)
|
||||
{
|
||||
((void (*) (void)) (*C)) ();
|
||||
}
|
|
@ -30,7 +30,7 @@ void exceptions_division_by_zero_isr(T_ISR_REGISTERS Registers)
|
|||
|
||||
void exceptions_page_fault_isr(T_ISR_REGISTERS_ERR Registers)
|
||||
{
|
||||
u32 FaultAddress;
|
||||
u64 FaultAddress;
|
||||
__asm__ volatile("mov %%cr2, %0" : "=r" (FaultAddress));
|
||||
|
||||
u8 Present = !(Registers.Error & 0x01);
|
|
@ -34,7 +34,7 @@ void gdt_entry_create_null(u8 Index)
|
|||
void gdt_create_flat(void)
|
||||
{
|
||||
g_gdt_ptr.Size = sizeof(T_GDT_ENTRY) * 6 - 1;
|
||||
g_gdt_ptr.Address = (u32)&g_gdt_entries;
|
||||
g_gdt_ptr.Address = (u64)&g_gdt_entries;
|
||||
|
||||
gdt_entry_create_null(0);
|
||||
gdt_entry_create(1, 0, 0xFFFFFFFF, GDT_RING0, GDT_EXECUTABLE, GDT_RW);
|
|
@ -60,9 +60,9 @@ void heap_index_remove(T_HEAP_INDEX *Index, u32 Position)
|
|||
Index->Size--;
|
||||
}
|
||||
|
||||
T_HEAP *heap_create(u32 Start, u32 End, u32 Max)
|
||||
T_HEAP *heap_create(u64 Start, u64 End, u64 Max)
|
||||
{
|
||||
u32 NumPages = (End - Start ) / (1024 * 4);
|
||||
u64 NumPages = (End - Start ) / (1024 * 4);
|
||||
if ((End - Start) % (1024 * 4) != 0)
|
||||
NumPages++;
|
||||
|
||||
|
@ -70,8 +70,8 @@ T_HEAP *heap_create(u32 Start, u32 End, u32 Max)
|
|||
NumPages, (End - Start) / 0x100000);
|
||||
for (int i = 0; i < NumPages; i++)
|
||||
{
|
||||
u32 Page = physmem_allocate_page();
|
||||
u32 Physical = physmem_page_to_physical(Page);
|
||||
u64 Page = physmem_allocate_page();
|
||||
u64 Physical = physmem_page_to_physical(Page);
|
||||
paging_map_kernel_page(Start + i * 1024 * 4, Physical);
|
||||
}
|
||||
|
||||
|
@ -96,21 +96,21 @@ T_HEAP *heap_create(u32 Start, u32 End, u32 Max)
|
|||
return Heap;
|
||||
}
|
||||
|
||||
s32 _heap_find_smallest_hole(T_HEAP *Heap, u32 Size, u8 Aligned)
|
||||
s32 _heap_find_smallest_hole(T_HEAP *Heap, u64 Size, u8 Aligned)
|
||||
{
|
||||
u32 Iterator = 0;
|
||||
u64 Iterator = 0;
|
||||
while (Iterator < Heap->Index.Size)
|
||||
{
|
||||
T_HEAP_HEADER *Header = heap_index_get(&Heap->Index, Iterator);
|
||||
if (Aligned > 0)
|
||||
{
|
||||
u32 Location = (u32)Header;
|
||||
u32 Offset = 0;
|
||||
u64 Location = (u64)Header;
|
||||
u64 Offset = 0;
|
||||
|
||||
if (((Location + sizeof(T_HEAP_HEADER)) & 0xFFFFF000) != 0)
|
||||
Offset = 0x1000 - (Location + sizeof(T_HEAP_HEADER)) % 0x1000;
|
||||
|
||||
u32 HoleSize = (u32)Header->Size - Offset;
|
||||
u32 HoleSize = (u64)Header->Size - Offset;
|
||||
|
||||
if (HoleSize >= Size)
|
||||
break;
|
||||
|
@ -126,23 +126,23 @@ s32 _heap_find_smallest_hole(T_HEAP *Heap, u32 Size, u8 Aligned)
|
|||
return Iterator;
|
||||
}
|
||||
|
||||
void _heap_expand(T_HEAP *Heap, u32 Size)
|
||||
void _heap_expand(T_HEAP *Heap, u64 Size)
|
||||
{
|
||||
u16 NumPages = Size / 0x1000;
|
||||
if (Size % 0x1000 != 0)
|
||||
NumPages++;
|
||||
|
||||
for (u32 i = 0; i < NumPages; i++)
|
||||
for (u64 i = 0; i < NumPages; i++)
|
||||
{
|
||||
u32 Page = physmem_allocate_page();
|
||||
u32 Physical = physmem_page_to_physical(Page);
|
||||
u64 Page = physmem_allocate_page();
|
||||
u64 Physical = physmem_page_to_physical(Page);
|
||||
paging_map_kernel_page(Heap->End + i * 0x1000, Physical);
|
||||
}
|
||||
|
||||
Heap->End = Heap->Start + NumPages * 0x1000;
|
||||
}
|
||||
|
||||
u32 _heap_contract(T_HEAP *Heap, u32 Size)
|
||||
u32 _heap_contract(T_HEAP *Heap, u64 Size)
|
||||
{
|
||||
if (Size & 0x1000)
|
||||
{
|
||||
|
@ -153,15 +153,15 @@ u32 _heap_contract(T_HEAP *Heap, u32 Size)
|
|||
if (Size < HEAP_MIN_SIZE)
|
||||
Size = HEAP_MIN_SIZE;
|
||||
|
||||
u32 OldSize = Heap->End - Heap->Start;
|
||||
u32 NumberToDelete = (OldSize - Size) / 0x1000;
|
||||
u64 OldSize = Heap->End - Heap->Start;
|
||||
u64 NumberToDelete = (OldSize - Size) / 0x1000;
|
||||
|
||||
for (int i = 0; i < NumberToDelete; i++)
|
||||
{
|
||||
u32 Virtual = Heap->End + i * 0x1000;
|
||||
u32 Physical;
|
||||
u64 Virtual = Heap->End + i * 0x1000;
|
||||
u64 Physical;
|
||||
paging_get_physical(Virtual, &Physical);
|
||||
u32 Page = Physical / 0x1000;
|
||||
u64 Page = Physical / 0x1000;
|
||||
physmem_free_page(Page);
|
||||
}
|
||||
|
||||
|
@ -170,35 +170,35 @@ u32 _heap_contract(T_HEAP *Heap, u32 Size)
|
|||
return (Heap->End - Heap->Start);
|
||||
}
|
||||
|
||||
void *heap_alloc_p(T_HEAP *Heap, u32 Size, u8 Aligned, u32 *Physical)
|
||||
void *heap_alloc_p(T_HEAP *Heap, u64 Size, u8 Aligned, u64 *Physical)
|
||||
{
|
||||
void *Address = heap_alloc(Heap, Size, Aligned);
|
||||
|
||||
if (Physical != 0)
|
||||
paging_get_physical((u32)Address, Physical);
|
||||
paging_get_physical((u64)Address, Physical);
|
||||
|
||||
return Address;
|
||||
}
|
||||
|
||||
void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned)
|
||||
void *heap_alloc(T_HEAP *Heap, u64 Size, u8 Aligned)
|
||||
{
|
||||
u32 RealSize = Size + sizeof(T_HEAP_HEADER) + sizeof(T_HEAP_FOOTER);
|
||||
s32 Iterator = _heap_find_smallest_hole(Heap, RealSize, Aligned);
|
||||
u64 RealSize = Size + sizeof(T_HEAP_HEADER) + sizeof(T_HEAP_FOOTER);
|
||||
s64 Iterator = _heap_find_smallest_hole(Heap, RealSize, Aligned);
|
||||
|
||||
if (Iterator == -1)
|
||||
{
|
||||
u32 OldSize = Heap->End - Heap->Start;
|
||||
u32 OldEnd = Heap->End;
|
||||
u64 OldSize = Heap->End - Heap->Start;
|
||||
u64 OldEnd = Heap->End;
|
||||
_heap_expand(Heap, OldSize + RealSize);
|
||||
u32 NewSize = Heap->End - Heap->Start;
|
||||
u64 NewSize = Heap->End - Heap->Start;
|
||||
|
||||
Iterator = 0;
|
||||
u32 Last = 0;
|
||||
s32 LastIndex = -1;
|
||||
u64 Last = 0;
|
||||
s64 LastIndex = -1;
|
||||
|
||||
while (Iterator < Heap->Index.Size)
|
||||
{
|
||||
u32 Location = (u32)heap_index_get(&Heap->Index, Iterator);
|
||||
u64 Location = (u64)heap_index_get(&Heap->Index, Iterator);
|
||||
if (Location > Last)
|
||||
{
|
||||
Last = Location;
|
||||
|
@ -226,7 +226,7 @@ void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned)
|
|||
T_HEAP_HEADER *Header = (T_HEAP_HEADER *)Last;
|
||||
Header->Size += NewSize - OldSize;
|
||||
|
||||
T_HEAP_FOOTER *Footer = (T_HEAP_FOOTER *)((u32)Header
|
||||
T_HEAP_FOOTER *Footer = (T_HEAP_FOOTER *)((u64)Header
|
||||
+ Header->Size - sizeof(T_HEAP_FOOTER));
|
||||
Footer->Header = Header;
|
||||
Footer->Magic = HEAP_FOOTER_MAGIC;
|
||||
|
@ -237,8 +237,8 @@ void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned)
|
|||
|
||||
T_HEAP_HEADER *Header = (T_HEAP_HEADER*)heap_index_get(&Heap->Index,
|
||||
Iterator);
|
||||
u32 HoleStart = (u32)Header;
|
||||
u32 HoleSize = Header->Size;
|
||||
u64 HoleStart = (u64)Header;
|
||||
u64 HoleSize = Header->Size;
|
||||
|
||||
if (HoleSize - RealSize < sizeof(T_HEAP_HEADER) + sizeof(T_HEAP_FOOTER))
|
||||
{
|
||||
|
@ -248,7 +248,7 @@ void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned)
|
|||
|
||||
if (Aligned && HoleStart & 0xFFFFF000)
|
||||
{
|
||||
u32 NewLocation = HoleStart + 0x1000 - (HoleStart & 0xFFF)
|
||||
u64 NewLocation = HoleStart + 0x1000 - (HoleStart & 0xFFF)
|
||||
- sizeof(T_HEAP_HEADER);
|
||||
Header->Size = 0x1000 - (HoleStart & 0xFFF) - sizeof(T_HEAP_HEADER);
|
||||
Header->Magic = HEAP_HEADER_MAGIC;
|
||||
|
@ -283,10 +283,10 @@ void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned)
|
|||
NewHoleHeader->Size = HoleSize - RealSize;
|
||||
NewHoleHeader->Hole = 1;
|
||||
|
||||
T_HEAP_FOOTER *NewHoleFooter = (T_HEAP_FOOTER*)((u32)NewHoleHeader
|
||||
T_HEAP_FOOTER *NewHoleFooter = (T_HEAP_FOOTER*)((u64)NewHoleHeader
|
||||
+ NewHoleHeader->Size - sizeof(T_HEAP_FOOTER));
|
||||
|
||||
if ((u32)NewHoleFooter < Heap->End)
|
||||
if ((u64)NewHoleFooter < Heap->End)
|
||||
{
|
||||
NewHoleFooter->Magic = HEAP_FOOTER_MAGIC;
|
||||
NewHoleFooter->Header = NewHoleHeader;
|
||||
|
@ -295,15 +295,15 @@ void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned)
|
|||
heap_index_insert(&Heap->Index, (void*)NewHoleHeader);
|
||||
}
|
||||
|
||||
return (void *)((u32)BlockHeader + sizeof(T_HEAP_HEADER));
|
||||
return (void *)((u64)BlockHeader + sizeof(T_HEAP_HEADER));
|
||||
}
|
||||
|
||||
void heap_free(T_HEAP *Heap, void *Data)
|
||||
{
|
||||
if (Data == 0) return;
|
||||
T_HEAP_HEADER *Header = (T_HEAP_HEADER *)((u32)Data
|
||||
T_HEAP_HEADER *Header = (T_HEAP_HEADER *)((u64)Data
|
||||
- sizeof(T_HEAP_HEADER));
|
||||
T_HEAP_FOOTER *Footer = (T_HEAP_FOOTER *)((u32)Header + Header->Size
|
||||
T_HEAP_FOOTER *Footer = (T_HEAP_FOOTER *)((u64)Header + Header->Size
|
||||
- sizeof(T_HEAP_FOOTER));
|
||||
|
||||
if (Header->Magic != HEAP_HEADER_MAGIC)
|
||||
|
@ -314,27 +314,27 @@ void heap_free(T_HEAP *Heap, void *Data)
|
|||
|
||||
u8 ShouldAdd = 1;
|
||||
|
||||
T_HEAP_FOOTER *FooterLeft = (T_HEAP_FOOTER *)((u32)Data
|
||||
T_HEAP_FOOTER *FooterLeft = (T_HEAP_FOOTER *)((u64)Data
|
||||
- sizeof(T_HEAP_FOOTER));
|
||||
if (FooterLeft->Magic == HEAP_FOOTER_MAGIC && FooterLeft->Header->Hole)
|
||||
{
|
||||
u32 OurSize = Header->Size;
|
||||
u64 OurSize = Header->Size;
|
||||
Header = FooterLeft->Header;
|
||||
Footer->Header = Header;
|
||||
Header->Size += OurSize;
|
||||
ShouldAdd = 0;
|
||||
}
|
||||
|
||||
T_HEAP_HEADER *HeaderRight = (T_HEAP_HEADER *)((u32)Footer
|
||||
T_HEAP_HEADER *HeaderRight = (T_HEAP_HEADER *)((u64)Footer
|
||||
+ sizeof(T_HEAP_FOOTER));
|
||||
if (HeaderRight->Magic == HEAP_HEADER_MAGIC && HeaderRight->Hole)
|
||||
{
|
||||
Header->Size += HeaderRight->Size;
|
||||
Footer = (T_HEAP_FOOTER *)((u32)HeaderRight + HeaderRight->Size
|
||||
Footer = (T_HEAP_FOOTER *)((u64)HeaderRight + HeaderRight->Size
|
||||
- sizeof(T_HEAP_FOOTER));
|
||||
Footer->Header = Header;
|
||||
|
||||
u32 Iterator = 0;
|
||||
u64 Iterator = 0;
|
||||
while (Iterator < Heap->Index.Size &&
|
||||
heap_index_get(&Heap->Index, Iterator) != (void *)HeaderRight)
|
||||
Iterator++;
|
||||
|
@ -343,22 +343,22 @@ void heap_free(T_HEAP *Heap, void *Data)
|
|||
heap_index_remove(&Heap->Index, Iterator);
|
||||
}
|
||||
|
||||
if ((u32)Footer + sizeof(T_HEAP_FOOTER) == Heap->End)
|
||||
if ((u64)Footer + sizeof(T_HEAP_FOOTER) == Heap->End)
|
||||
{
|
||||
u32 OldSize = Heap->End - Heap->Start;
|
||||
u32 NewSize = _heap_contract(Heap, (u32)Header - Heap->Start);
|
||||
u64 OldSize = Heap->End - Heap->Start;
|
||||
u64 NewSize = _heap_contract(Heap, (u64)Header - Heap->Start);
|
||||
|
||||
if (Header->Size > (OldSize - NewSize))
|
||||
{
|
||||
Header->Size -= (OldSize - NewSize);
|
||||
Footer = (T_HEAP_FOOTER *)((u32)Header + Header->Size
|
||||
Footer = (T_HEAP_FOOTER *)((u64)Header + Header->Size
|
||||
- sizeof(T_HEAP_FOOTER));
|
||||
Footer->Magic = HEAP_FOOTER_MAGIC;
|
||||
Footer->Header = Header;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 Iterator = 0;
|
||||
u64 Iterator = 0;
|
||||
while (Iterator < Heap->Index.Size &&
|
||||
heap_index_get(&Heap->Index, Iterator) != (void *)Header)
|
||||
Iterator++;
|
||||
|
@ -381,12 +381,12 @@ void heap_init_simple(void)
|
|||
HEAP_START + 0x0FFFF000);
|
||||
}
|
||||
|
||||
void *kmalloc(u32 Size)
|
||||
void *kmalloc(u64 Size)
|
||||
{
|
||||
return heap_alloc(g_heap, Size, 0);
|
||||
}
|
||||
|
||||
void *kmalloc_p(u32 Size, u8 Aligned, u32 *Physical)
|
||||
void *kmalloc_p(u64 Size, u8 Aligned, u64 *Physical)
|
||||
{
|
||||
return heap_alloc_p(g_heap, Size, Aligned, Physical);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
# I hate GNU Make
|
||||
#
|
||||
# Seriously.
|
||||
#
|
||||
# Fuck M4. I do this because it's probably the most portable way, and I don't
|
||||
# want to write Yet Another Compile System because fuck that shit. I could
|
||||
# use cmake but I don't know whether it is flexible enough. It probably is
|
||||
# but whatever. I wrote this piece of shit below, let's just keep it that
|
||||
# way. There are better way to do the hthings I do below, but who gives a
|
||||
# shit.
|
||||
|
||||
default: emulate-nohdd
|
||||
|
||||
SHELL:=/bin/bash
|
||||
ENV:=/usr/xdev/bin
|
||||
TARGET:=i586-elf
|
||||
CC:=$(ENV)/$(TARGET)-gcc
|
||||
AS:=nasm
|
||||
LD:=$(ENV)/$(TARGET)-ld
|
||||
|
||||
# -O2 sets -foptimize-sibling-calls which breaks code...
|
||||
CFLAGS:=-Wall -Werror -nostdlib -nostartfiles -nodefaultlibs -std=c99 -g
|
||||
CFLAGS+=-I ./include -Wno-packed-bitfield-compat -O2 -fno-optimize-sibling-calls
|
||||
CFLAGS+= -fno-builtin
|
||||
LFLAGS:=-nostdlib -nostartfiles -nodefaultlibs
|
||||
|
||||
.PHONY: all clean loader.bin emulate hdd.img
|
||||
|
||||
obj/src/%.nao : src/%.asm
|
||||
@echo "[i] Assembling $*.asm..."
|
||||
@$(AS) -f elf -o obj/src/$*.nao src/$*.asm
|
||||
|
||||
obj/src/%.o : src/%.c
|
||||
@echo "[i] Compiling $*.c ..."
|
||||
@if [ -e obj/src/$*.o ] ; then rm obj/src/$*.o ; fi
|
||||
@mkdir -p obj/src/$*.o
|
||||
@rmdir obj/src/$*.o
|
||||
@$(CC) $(CFLAGS) -c src/$*.c -o obj/src/$*.o
|
||||
|
||||
SRC := $(shell find src -mindepth 1 -maxdepth 3 -name "*.c")
|
||||
SRC += $(shell find src -mindepth 1 -maxdepth 3 -name "*.asm")
|
||||
OBJ := $(patsubst %.c,%.o,$(SRC))
|
||||
OBJ := $(patsubst %.asm,%.nao,$(OBJ))
|
||||
OBJ_ALL := $(foreach i, $(OBJ), obj/$(i))
|
||||
Loader: $(OBJ_ALL)
|
||||
|
||||
loader.bin: Loader
|
||||
@echo "[i] Linking loader.bin..."
|
||||
@$(LD) -T src/loader.ld -o loader.bin $(OBJ_ALL)
|
||||
|
||||
emulate-nohdd-debug: loader.bin
|
||||
@echo "[i] Starting GDB..."
|
||||
@gnome-terminal -x /bin/bash -c "gdb"
|
||||
@echo "[i] Starting QEmu..."
|
||||
@qemu -kernel loader.bin -S -gdb tcp::1234
|
||||
|
||||
emulate-nohdd: loader.bin
|
||||
@echo "[i] Starting QEMU..."
|
||||
@qemu -kernel loader.bin
|
||||
|
||||
clean:
|
||||
@rm -Rf obj
|
||||
@if [ -e loader.bin ] ; then rm loader.bin ; fi
|
||||
@if [ -e hdd_temp.img ] ; then rm hdd_temp.img ; fi
|
||||
@if [ -e hdd.img ] ; then rm hdd.img; fi
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,432 @@
|
|||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
typedef char s8;
|
||||
|
||||
u8 stdio_current_line = 0;
|
||||
u8 stdio_cur_x = 0, stdio_cur_y = 0;
|
||||
|
||||
void outb(u16 Port, u8 Data)
|
||||
{
|
||||
__asm__ volatile("outb %1, %0" :: "dN" (Port), "a" (Data));
|
||||
}
|
||||
|
||||
void *memcpy(void* Destination, const void *Source, u32 Count)
|
||||
{
|
||||
u8* Destination8 = (u8*)Destination;
|
||||
u8* Source8 = (u8*)Source;
|
||||
|
||||
while (Count--)
|
||||
{
|
||||
*Destination8++ = *Source8++;
|
||||
}
|
||||
return Destination;
|
||||
}
|
||||
|
||||
void *memset(void *Destination, u8 Value, u32 Count)
|
||||
{
|
||||
u8 *us = (u8 *)Destination;
|
||||
while (Count-- != 0)
|
||||
*us++ = Value;
|
||||
return Destination;
|
||||
}
|
||||
|
||||
void *memsetw(void *Destination, u16 Value, u32 Count)
|
||||
{
|
||||
u16 *us = (u16 *)Destination;
|
||||
while (Count-- != 0)
|
||||
*us++ = Value;
|
||||
return Destination;
|
||||
}
|
||||
|
||||
|
||||
void scroll_up(void)
|
||||
{
|
||||
//semaphore_acquire(&ScreenWriteLock);
|
||||
u16 Blank = 0x20 | (0x0F << 8);
|
||||
u16 Temp;
|
||||
|
||||
if (stdio_cur_y >= 25)
|
||||
{
|
||||
Temp = stdio_cur_y - 25 + 1;
|
||||
memcpy((void*)0xB8000, (void*)(0xB8000 + Temp * 80 * 2), (25 - Temp) * 80 * 2);
|
||||
|
||||
memsetw((void*)(0xB8000 + (25 - Temp) * 160), Blank, 160);
|
||||
stdio_cur_y = 25 - 1;
|
||||
}
|
||||
//semaphore_release(&ScreenWriteLock);
|
||||
}
|
||||
|
||||
void move_cursor(u8 X, u8 Y)
|
||||
{
|
||||
stdio_cur_x = X;
|
||||
stdio_cur_y = Y;
|
||||
|
||||
//wraparound
|
||||
if (stdio_cur_x >= 80)
|
||||
{
|
||||
stdio_cur_y += stdio_cur_y / 80;
|
||||
stdio_cur_x = 0;
|
||||
}
|
||||
|
||||
//wrapup
|
||||
scroll_up();
|
||||
|
||||
if (Y > 24)
|
||||
Y = 24;
|
||||
|
||||
u16 Position = Y * 80 + X;
|
||||
|
||||
outb(0x3D4, 0x0F);
|
||||
outb(0x3D5, (u8)(Position & 0xFF));
|
||||
|
||||
outb(0x3D4, 0x0E);
|
||||
outb(0x3D5, (u8)(Position >> 8 & 0xFF));
|
||||
}
|
||||
|
||||
void putch(s8 Character)
|
||||
{
|
||||
volatile u8 *VideoMemory = (u8 *)0xB8000;
|
||||
u16 Offset = (stdio_cur_y * 80 + stdio_cur_x) << 1;
|
||||
|
||||
if (Character == '\n')
|
||||
move_cursor(0, stdio_cur_y + 1);
|
||||
else
|
||||
{
|
||||
VideoMemory[Offset] = Character;
|
||||
VideoMemory[Offset+1] = 0x0F;
|
||||
if (stdio_cur_x + 1 >= 80)
|
||||
move_cursor(0, stdio_cur_y + 1);
|
||||
else
|
||||
move_cursor(stdio_cur_x + 1, stdio_cur_y);
|
||||
}
|
||||
}
|
||||
|
||||
void puts(const s8 *szString)
|
||||
{
|
||||
while (*szString != 0)
|
||||
{
|
||||
putch(*szString);
|
||||
szString++;
|
||||
}
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
volatile u8 *VideoMemory = (u8 *)0xB8000;
|
||||
u32 Size = (80 * 25 ) << 1;
|
||||
for (u32 i = 0; i < Size; i += 2)
|
||||
{
|
||||
VideoMemory[i] = 0;
|
||||
VideoMemory[i+1] = 0xF;
|
||||
}
|
||||
move_cursor(0, 0);
|
||||
}
|
||||
|
||||
void dump_nibble(u8 Nibble)
|
||||
{
|
||||
if (Nibble < 10)
|
||||
putch(Nibble + 48);
|
||||
else
|
||||
putch(Nibble + 55);
|
||||
}
|
||||
|
||||
void print_hex(u64 Number)
|
||||
{
|
||||
for (s8 i = 7; i >= 0; i--)
|
||||
{
|
||||
u8 Byte = (Number >> (i << 3)) & 0xFF; //switch i bytes to the right and mask as byte
|
||||
dump_nibble((Byte >> 4) & 0x0F); //high nibble
|
||||
dump_nibble(Byte & 0x0F); //low nibble
|
||||
}
|
||||
}
|
||||
|
||||
struct elf_ident {
|
||||
u32 Magic; // \x7FELF
|
||||
u8 Class;
|
||||
u8 Data;
|
||||
u8 Version;
|
||||
u8 Padding[9];
|
||||
};
|
||||
|
||||
struct elf_header {
|
||||
struct elf_ident Identification;
|
||||
u16 Type;
|
||||
u16 Machine;
|
||||
u32 Version;
|
||||
u64 Entry;
|
||||
u64 ProgramHeaderOffset;
|
||||
u64 SectionHeaderOffset;
|
||||
u32 Flags;
|
||||
u16 HeaderSize;
|
||||
u16 ProgramHeaderEntrySize;
|
||||
u16 NumProgramHeaderEntries;
|
||||
u16 SectionHeaderEntrySize;
|
||||
u16 NumSectionHeaderEntries;
|
||||
u16 SectionEntryStrings;
|
||||
};
|
||||
|
||||
struct elf_section_header {
|
||||
u32 Name;
|
||||
u32 Type;
|
||||
u64 Flags;
|
||||
u64 Address;
|
||||
u64 Offset;
|
||||
u64 Size;
|
||||
u32 Link;
|
||||
u32 Info;
|
||||
u64 Alignment;
|
||||
u64 FixedSize;
|
||||
};
|
||||
|
||||
static inline void cpuid(u32 code, u32 *a, u32 *d) {
|
||||
__asm__ volatile("cpuid":"=a"(*a),"=d"(*d):"0"(code):"ecx","ebx");
|
||||
}
|
||||
|
||||
|
||||
// A simple PAE paging structure so we can jump into 64-bit.
|
||||
// This will be replaced later on by the kernel code.
|
||||
|
||||
u64 pml4[512] __attribute__((aligned(0x1000)));
|
||||
u64 page_dir_ptr_tab_low[512] __attribute__((aligned(0x1000)));
|
||||
u64 page_dir_low[512] __attribute__((aligned(0x1000)));
|
||||
u64 page_tab_low[512] __attribute__((aligned(0x1000)));
|
||||
|
||||
u64 page_dir_ptr_tab_high[512] __attribute__((aligned(0x1000)));
|
||||
u64 page_dir_high[512] __attribute__((aligned(0x1000)));
|
||||
u64 page_tab_high[512] __attribute__((aligned(0x1000)));
|
||||
|
||||
#define GET_PML4_ENTRY(x) (((u64)x >> 39) & 0x1FF)
|
||||
#define GET_PDP_ENTRY(x) (((u64)x >> 30) & 0x1FF)
|
||||
#define GET_DIR_ENTRY(x) (((u64)x >> 21) & 0x1FF)
|
||||
#define GET_TAB_ENTRY(x) (((u64)x >> 12) & 0x1FF)
|
||||
#define GET_OFFSET(x) (x & 0xFFF)
|
||||
|
||||
void create_ia32e_paging(u64 KernelPhysicalStart, u64 KernelVirtualStart, u64 KernelSize)
|
||||
{
|
||||
puts("Clearing paging structures...\n");
|
||||
|
||||
for (u16 i = 0; i < 512; i++)
|
||||
{
|
||||
pml4[i] = 0;
|
||||
page_dir_ptr_tab_low[i] = 0;
|
||||
page_dir_low[i] = 0;
|
||||
page_tab_low[i] = 0;
|
||||
page_dir_ptr_tab_high[i] = 0;
|
||||
page_dir_high[i] = 0;
|
||||
page_tab_high[i] = 0;
|
||||
}
|
||||
|
||||
puts("Setting up identity paging for first 2MiB...\n");
|
||||
pml4[GET_PML4_ENTRY(0)] = (u32)page_dir_ptr_tab_low | 3;
|
||||
page_dir_ptr_tab_low[GET_PDP_ENTRY(0)] = (u32)page_dir_low | 3;
|
||||
page_dir_low[GET_DIR_ENTRY(0)] = (u32)page_tab_low | 3;
|
||||
|
||||
u64 Address = 0;
|
||||
for (u16 i = 0; i < 512; i++)
|
||||
{
|
||||
page_tab_low[i] = Address | 3;
|
||||
Address += 0x1000;
|
||||
}
|
||||
|
||||
puts("Setting up paging for the kernel...\n");
|
||||
u16 NumPages = KernelSize / 0x1000;
|
||||
puts(" (0x");
|
||||
print_hex(NumPages);
|
||||
puts(" pages)\n");
|
||||
|
||||
if (GET_PML4_ENTRY(KernelVirtualStart) != 0)
|
||||
{
|
||||
// We're NOT mapping the same PML4 entry as for identity mapping...
|
||||
puts("Different PML4...\n");
|
||||
pml4[GET_PML4_ENTRY(KernelVirtualStart)] = (u32)page_dir_ptr_tab_high | 3;
|
||||
page_dir_ptr_tab_high[GET_PDP_ENTRY(KernelVirtualStart)] = (u32)page_dir_high | 3;
|
||||
page_dir_high[GET_PDP_ENTRY(KernelVirtualStart)] = (u32)page_tab_high | 3;
|
||||
}
|
||||
else if (GET_PDP_ENTRY(KernelVirtualStart) != 0)
|
||||
{
|
||||
// We're NOT mapping the same page directory pointer table entry as for identity paging...
|
||||
puts("Different PDPT... (");
|
||||
print_hex(GET_PDP_ENTRY(KernelVirtualStart));
|
||||
puts(")\n");
|
||||
page_dir_ptr_tab_low[GET_PDP_ENTRY(KernelVirtualStart)] = (u32)page_dir_high | 3;
|
||||
page_dir_high[GET_DIR_ENTRY(KernelVirtualStart)] = (u32)page_tab_high | 3;
|
||||
}
|
||||
else if (GET_DIR_ENTRY(KernelVirtualStart) != 0)
|
||||
{
|
||||
// We're NOT mapping the same page directory entry as for identity paging...
|
||||
puts("Different DIR...\n");
|
||||
page_dir_low[GET_DIR_ENTRY(KernelVirtualStart)] = (u32)page_tab_high | 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
puts("Error: kernel overlaps 2MiB identity paging!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Address = KernelPhysicalStart;
|
||||
for (u16 i = GET_TAB_ENTRY(KernelVirtualStart); i < GET_TAB_ENTRY(KernelVirtualStart) + NumPages; i++)
|
||||
{
|
||||
page_tab_high[i] = Address | 3;
|
||||
print_hex(KernelVirtualStart + i * 0x1000);
|
||||
puts(" -> ");
|
||||
print_hex(Address);
|
||||
puts("\n");
|
||||
Address += 0x1000;
|
||||
}
|
||||
}
|
||||
|
||||
u32 load(void *Multiboot, unsigned int Magic)
|
||||
{
|
||||
clear();
|
||||
puts("Cucumber x86-64 loader...\n");
|
||||
|
||||
|
||||
if (Magic != 0x2BADB002)
|
||||
{
|
||||
puts("Error: not booted via Multiboot!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 CPUID_A, CPUID_D;
|
||||
cpuid(0x80000001, &CPUID_A, &CPUID_D);
|
||||
|
||||
u8 SupportFor64 = (CPUID_D & (1 << 29)) > 0;
|
||||
|
||||
if (!SupportFor64)
|
||||
{
|
||||
puts("Error: You CPU does not support long mode!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 Flags = *((u32*)Multiboot);
|
||||
|
||||
u8 ModulesPresent = (Flags & (1 << 3)) > 0;
|
||||
|
||||
if (!ModulesPresent)
|
||||
{
|
||||
puts("Error: no 64-bit kernel loaded!\n");
|
||||
puts(" (did you forget the module line in GRUB?)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 ModulesCount = *((u32*)Multiboot + 5);
|
||||
u32 ModulesAddress = *((u32*)Multiboot + 6);
|
||||
|
||||
if (ModulesCount != 1)
|
||||
{
|
||||
puts("Error: just one module is enough. Don't load a ton of them.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
puts("Kernel is @");
|
||||
print_hex(ModulesAddress);
|
||||
puts(".\n");
|
||||
|
||||
struct elf_header *Header = *((struct elf_header **)ModulesAddress);
|
||||
if (Header->Identification.Magic != 0x464C457F)
|
||||
{
|
||||
puts("Error: Module is not an ELF file!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Header->Identification.Class != 2)
|
||||
{
|
||||
puts("Error: Module is not a 64-bit ELF file!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!Header->Entry)
|
||||
{
|
||||
puts("Error: Kernel does not have entry point!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
puts("Entry point @");
|
||||
print_hex(Header->Entry);
|
||||
puts(".\n");
|
||||
|
||||
if (Header->SectionHeaderEntrySize != sizeof(struct elf_section_header))
|
||||
{
|
||||
puts("Error: Weird section header entry size!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct elf_section_header *Sections = (struct elf_section_header *)((u32)Header + (u32)Header->SectionHeaderOffset);
|
||||
struct elf_section_header *StringSection = &Sections[Header->SectionEntryStrings];
|
||||
|
||||
//u32 *Strings = (u32*)(ModulesAddress + (u32)StringSection->Offset);
|
||||
|
||||
puts("0x");
|
||||
print_hex(Header->NumSectionHeaderEntries);
|
||||
puts(" ELF sections.\n");
|
||||
|
||||
u64 ContinuityTest = 0;
|
||||
u64 StartPhysical = 0;
|
||||
u64 StartVirtual = 0;
|
||||
u64 Size = 0;
|
||||
|
||||
for (u16 i = 0; i < Header->NumSectionHeaderEntries; i++)
|
||||
{
|
||||
s8* Name = (s8*)((u32)Header + (u32)StringSection->Offset + (u32)Sections[i].Name);
|
||||
u64 PhysicalAddress = (u32)Header + Sections[i].Offset;
|
||||
u64 VirtualAddress = Sections[i].Address;
|
||||
|
||||
if (VirtualAddress)
|
||||
{
|
||||
if (!StartVirtual)
|
||||
StartVirtual = VirtualAddress;
|
||||
|
||||
if (!StartPhysical)
|
||||
StartPhysical = PhysicalAddress;
|
||||
|
||||
if (ContinuityTest && VirtualAddress != ContinuityTest)
|
||||
{
|
||||
puts("Error: kernel is not continuous!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ContinuityTest = VirtualAddress + Sections[i].Size;
|
||||
Size += Sections[i].Size;
|
||||
|
||||
puts("-> Section ");
|
||||
puts(Name);
|
||||
puts(", 0x");
|
||||
print_hex(PhysicalAddress);
|
||||
puts(" will be located at 0x");
|
||||
print_hex(VirtualAddress);
|
||||
puts(".\n");
|
||||
}
|
||||
}
|
||||
|
||||
puts("\nPaging setup:\n 0x");
|
||||
print_hex(StartVirtual);
|
||||
puts(" => 0x");
|
||||
print_hex(StartPhysical);
|
||||
puts("\n (0x");
|
||||
print_hex(Size);
|
||||
puts(" bytes)\n");
|
||||
|
||||
create_ia32e_paging(StartPhysical, StartVirtual, Size);
|
||||
__asm__ volatile ("movl %cr4, %eax; bts $5, %eax; movl %eax, %cr4");
|
||||
__asm__ volatile ("movl %%eax, %%cr3" :: "a" (pml4));
|
||||
puts("CR3 is now pointing to PML4 (0x");
|
||||
print_hex((u32)pml4);
|
||||
puts(")\n");
|
||||
|
||||
puts("Here it goes, enabling long mode...\n");
|
||||
|
||||
__asm__ volatile( "movl $0xc0000080, %%ecx;\n"
|
||||
"rdmsr;\n"
|
||||
"orl $0x100, %%eax;\n"
|
||||
"wrmsr;\n"
|
||||
"movl %%cr0, %%ebx;\n"
|
||||
"bts $31, %%ebx;\n"
|
||||
"movl %%ebx, %%cr0;":::"eax","ebx","ecx");
|
||||
|
||||
puts("Now in 32-bit compability mode, jumping to the kernel...\n");
|
||||
|
||||
return (u32)Header->Entry;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
OUTPUT_FORMAT("elf32-i386")
|
||||
ENTRY(_loader)
|
||||
|
||||
Offset = 0x00100000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = Offset;
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
. = ALIGN(0x1000);
|
||||
}
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data*)
|
||||
*(.gnu.linkonce.d*)
|
||||
*(.rodata*)
|
||||
*(.gnu.linkonce.r*)
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
*(COMMON*)
|
||||
*(.bss*)
|
||||
. = ALIGN(0x1000);
|
||||
}
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.comment)
|
||||
*(.eh_frame)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
extern load
|
||||
extern puts
|
||||
extern stdio_current_line
|
||||
extern stdio_cur_x
|
||||
extern stdio_cur_y
|
||||
global _loader
|
||||
|
||||
; Multiboot-related constants
|
||||
MODULEALIGN equ 1 << 0
|
||||
MEMINFO equ 1 << 1
|
||||
FLAGS equ MODULEALIGN | MEMINFO
|
||||
MAGIC equ 0x1BADB002
|
||||
CHECKSUM equ -(MAGIC + FLAGS)
|
||||
|
||||
; Other constants
|
||||
STACKSIZE equ 0x1000
|
||||
|
||||
; #############################################################################
|
||||
; ############################## text segment #################################
|
||||
; #############################################################################
|
||||
|
||||
section .text
|
||||
align 4
|
||||
|
||||
; Multiboot header
|
||||
MultiBootHeader:
|
||||
dd MAGIC
|
||||
dd FLAGS
|
||||
dd CHECKSUM
|
||||
|
||||
; GDTR
|
||||
GDTR:
|
||||
dw 5*8-1
|
||||
dd GDT
|
||||
dd 0
|
||||
|
||||
; GDT
|
||||
GDT:
|
||||
dw 0,0,0,0 ; null desciptor (0x00)
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x00 ; 32-bit code segment (0x08)
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x00 ; 32-bit data segment (0x10)
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10011010b, 10101111b, 0x00 ; 64-bit code segment (0x18)
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10010010b, 10101111b, 0x00 ; 64-bit data segment (0x20)
|
||||
|
||||
str_back_in_asm:
|
||||
db "Back in assembler!", 0
|
||||
|
||||
; Actual entry point
|
||||
_loader:
|
||||
mov esp, stack+STACKSIZE
|
||||
push eax
|
||||
push ebx
|
||||
|
||||
lgdt [GDTR]
|
||||
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
jmp 0x08:_loader_gdt
|
||||
|
||||
_loader_gdt:
|
||||
call load
|
||||
|
||||
mov ebx, eax
|
||||
|
||||
mov ax, 0x20
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
; Did we get an entry point address?
|
||||
test ebx, ebx
|
||||
jz hang
|
||||
|
||||
movzx edi, byte [stdio_current_line]
|
||||
movzx esi, byte [stdio_cur_x]
|
||||
movzx edx, byte [stdio_cur_y]
|
||||
|
||||
; 64-bit, here we come!
|
||||
call 0x18:0xFF000000
|
||||
|
||||
hang:
|
||||
hlt
|
||||
jmp hang
|
||||
|
||||
; #############################################################################
|
||||
; ############################### bss segment #################################
|
||||
; #############################################################################
|
||||
|
||||
section .bss
|
||||
align 4
|
||||
|
||||
; here be 4k stack
|
||||
stack:
|
||||
resb STACKSIZE
|
|
@ -1,10 +0,0 @@
|
|||
#ifndef __KSTDLIB_H__
|
||||
#define __KSTDLIB_H__
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void *kmemcpy(void* Destination, const void *Source, u32 Count);
|
||||
void *kmemset(void *Destination, u8 Value, u32 Count);
|
||||
void *kmemsetw(void *Destination, u16 Value, u32 Count);
|
||||
|
||||
#endif
|
|
@ -13,14 +13,14 @@ default: emulate-nohdd
|
|||
|
||||
SHELL:=/bin/bash
|
||||
ENV:=/usr/xdev/bin
|
||||
TARGET:=i586-elf
|
||||
TARGET:=x86_64-elf
|
||||
CC:=$(ENV)/$(TARGET)-gcc
|
||||
CX:=$(ENV)/$(TARGET)-g++
|
||||
AS:=nasm
|
||||
LD:=$(ENV)/$(TARGET)-ld
|
||||
|
||||
# -O2 sets -foptimize-sibling-calls which breaks code...
|
||||
CFLAGS:=-Wall -Werror -nostdlib -nostartfiles -nodefaultlibs -std=c99 -g
|
||||
CFLAGS:=-m64 -mcmodel=large -Wall -Werror -nostdlib -nostartfiles -nodefaultlibs -std=c99 -g
|
||||
CFLAGS+=-I ./include -Wno-packed-bitfield-compat -O2 -fno-optimize-sibling-calls
|
||||
|
||||
|
||||
|
@ -33,10 +33,11 @@ LFLAGS:=-nostdlib -nostartfiles -nodefaultlibs
|
|||
|
||||
obj/src/%.nao : src/%.asm
|
||||
@echo "[i] Assembling $*.asm..."
|
||||
@$(AS) -f elf -o obj/src/$*.nao src/$*.asm
|
||||
@$(AS) -f elf64 -o obj/src/$*.nao src/$*.asm
|
||||
|
||||
obj/src/%.o : src/%.c
|
||||
@echo "[i] Compiling $*.c ..."
|
||||
@if [ -e obj/src/$*.o ] ; then rm obj/src/$*.o ; fi
|
||||
@mkdir -p obj/src/$*.o
|
||||
@rmdir obj/src/$*.o
|
||||
@$(CC) $(CFLAGS) -c src/$*.c -o obj/src/$*.o
|
||||
|
@ -84,8 +85,10 @@ emulate-nohdd-debug: kernel.bin
|
|||
@qemu -kernel kernel.bin -S -gdb tcp::1234
|
||||
|
||||
emulate-nohdd: kernel.bin
|
||||
@echo "[i] Building loader..."
|
||||
@pushd ../Loader > /dev/null && $(MAKE) -f Makefile loader.bin && popd > /dev/null
|
||||
@echo "[i] Starting QEMU..."
|
||||
@qemu -kernel kernel.bin
|
||||
@qemu-system-x86_64 -kernel ../Loader/loader.bin -initrd kernel.bin
|
||||
|
||||
emulate: hdd.img
|
||||
@echo "[i] Starting QEmu..."
|
|
@ -15,7 +15,7 @@
|
|||
typedef struct {
|
||||
u32 Magic;
|
||||
u8 Hole;
|
||||
u32 Size;
|
||||
u64 Size;
|
||||
} T_HEAP_HEADER;
|
||||
|
||||
typedef struct {
|
||||
|
@ -25,8 +25,8 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
void **Array;
|
||||
u32 Size;
|
||||
u32 MaxSize;
|
||||
u64 Size;
|
||||
u64 MaxSize;
|
||||
} T_HEAP_INDEX;
|
||||
|
||||
T_HEAP_INDEX heap_index_initialize(void *Address, u32 MaxSize);
|
||||
|
@ -35,19 +35,19 @@ u8 heap_index_smaller(void *A, void *B);
|
|||
|
||||
typedef struct {
|
||||
T_HEAP_INDEX Index;
|
||||
u32 Start;
|
||||
u32 End;
|
||||
u32 Max;
|
||||
u64 Start;
|
||||
u64 End;
|
||||
u64 Max;
|
||||
} T_HEAP;
|
||||
|
||||
T_HEAP *heap_create(u32 Start, u32 End, u32 Max);
|
||||
void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned);
|
||||
void *heap_alloc_p(T_HEAP *Heap, u32 Size, u8 Aligned, u32 *Physical);
|
||||
T_HEAP *heap_create(u64 Start, u64 End, u64 Max);
|
||||
void *heap_alloc(T_HEAP *Heap, u64 Size, u8 Aligned);
|
||||
void *heap_alloc_p(T_HEAP *Heap, u64 Size, u8 Aligned, u64 *Physical);
|
||||
void heap_free(T_HEAP *Heap, void *Address);
|
||||
|
||||
void heap_init_simple(void);
|
||||
void *kmalloc(u32 Size);
|
||||
void *kmalloc_p(u32 Size, u8 Aligned, u32 *Physical);
|
||||
void *kmalloc(u64 Size);
|
||||
void *kmalloc_p(u64 Size, u8 Aligned, u64 *Physical);
|
||||
void kfree(void *Data);
|
||||
|
||||
#endif
|
|
@ -39,14 +39,14 @@ typedef enum E_INTERRUPTS_CHIP T_INTERRUPTS_CHIP;
|
|||
struct S_ISR_STUB {
|
||||
u16 Code1;
|
||||
u8 Code2;
|
||||
u32 Handler;
|
||||
u64 Handler;
|
||||
u32 Code3;
|
||||
u8 Code4;
|
||||
} __attribute__ ((packed));
|
||||
typedef struct S_ISR_STUB T_ISR_STUB;
|
||||
|
||||
typedef struct {
|
||||
u32 edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||
u64 edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||
u32 Error;
|
||||
u32 eip, cs, eflags, useresp, ss;
|
||||
} T_ISR_REGISTERS_ERR;
|
|
@ -19,6 +19,7 @@ void kputi(s32 Number);
|
|||
void kprintf(const s8 *Format, ...);
|
||||
void kdump(u8 *bData, u32 Length);
|
||||
void kprint_hex(u32 Number);
|
||||
void kstdio_set_globals(u8 line, u8 cur_x, u8 cur_y);
|
||||
s32 kmemcmp(u8 *MemA, u8 *MemB, u32 Length);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __KSTDLIB_H__
|
||||
#define __KSTDLIB_H__
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void *kmemcpy(void* Destination, const void *Source, u64 Count);
|
||||
void *kmemset(void *Destination, u8 Value, u64 Count);
|
||||
void *kmemsetw(void *Destination, u16 Value, u64 Count);
|
||||
|
||||
#endif
|
|
@ -25,12 +25,12 @@ typedef struct {
|
|||
} T_PAGING_DIRECTORY;
|
||||
|
||||
void paging_init_simple(void);
|
||||
u8 paging_get_physical(u32 Virtual, u32 *Physical);
|
||||
u8 paging_get_physical_ex(u32 Virtual, u32 *Physical,
|
||||
u8 paging_get_physical(u64 Virtual, u64 *Physical);
|
||||
u8 paging_get_physical_ex(u64 Virtual, u64 *Physical,
|
||||
T_PAGING_DIRECTORY *Directory);
|
||||
void paging_map_kernel_page(u32 Virtual, u32 Physical);
|
||||
void paging_map_kernel_table(u32 Virtual, u32 Physical);
|
||||
void paging_map_page(u32 Virtual, u32 Physical, T_PAGING_DIRECTORY *Directory,
|
||||
void paging_map_kernel_page(u64 Virtual, u64 Physical);
|
||||
void paging_map_kernel_table(u64 Virtual, u64 Physical);
|
||||
void paging_map_page(u64 Virtual, u64 Physical, T_PAGING_DIRECTORY *Directory,
|
||||
u8 User, u8 RW);
|
||||
void paging_use_directory(T_PAGING_DIRECTORY *Directory);
|
||||
T_PAGING_DIRECTORY *paging_get_directory(void);
|
|
@ -8,6 +8,7 @@ typedef unsigned int u32;
|
|||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
|
||||
typedef long long s64;
|
||||
typedef int s32;
|
||||
typedef short s16;
|
||||
typedef char s8;
|
|
@ -1,6 +1,6 @@
|
|||
#include "types.h"
|
||||
#include "Tier0/kstdio.h"
|
||||
#include "Tier0/gdt.h"
|
||||
/*#include "Tier0/gdt.h"
|
||||
#include "Tier0/paging.h"
|
||||
#include "Tier0/acpi.h"
|
||||
#include "Tier0/interrupts.h"
|
||||
|
@ -13,31 +13,24 @@
|
|||
#include "Tier0/cpp.h"
|
||||
#include "Tier0/exceptions.h"
|
||||
#include "Tier0/panic.h"
|
||||
#include "Tier0/prng.h"
|
||||
#include "Tier0/prng.h"*/
|
||||
|
||||
void interrupts_irq_sample(void);
|
||||
|
||||
// Just to see whether this stuff actually works
|
||||
void sample_interrupt_0x2A(void)
|
||||
{
|
||||
kprintf("[i] Hello from ISR for interrupt 0x2A!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
void kmain_newstack(void);
|
||||
|
||||
// Real kernel entry point, called from _start.asm
|
||||
void kmain(void *MultibootHeader, u32 Magic)
|
||||
// Real kernel entry point, called from loader
|
||||
void kmain(u32 current_line, u32 cursor_x, u32 cursor_y)
|
||||
{
|
||||
kstdio_init();
|
||||
kclear();
|
||||
kprintf(" _ \n"
|
||||
kstdio_set_globals(current_line, cursor_x, cursor_y);
|
||||
//kclear();
|
||||
kprintf("\n _ \n"
|
||||
" ___ _ _ ___ _ _ _____| |_ ___ ___ \n"
|
||||
" | _| | | _| | | | . | -_| _|\n"
|
||||
" |___|___|___|___|_|_|_|___|___|_| \n\n");
|
||||
kprintf("[i] Welcome to Cucumber!\n\n");
|
||||
|
||||
if (Magic != 0x2BADB002)
|
||||
kprintf("[i] Welcome to Cucumber (x86-64)!\n");
|
||||
//kprintf("%x %x %x\n", current_line, cursor_x, cursor_y);
|
||||
|
||||
for (;;) {}
|
||||
|
||||
/*if (Magic != 0x2BADB002)
|
||||
{
|
||||
kprintf("[e] Fatal! Boot via incompatible bootloader.\n");
|
||||
return;
|
||||
|
@ -84,8 +77,6 @@ void kmain(void *MultibootHeader, u32 Magic)
|
|||
for (u32 Rl = 0; Rl < R; Rl++)
|
||||
{
|
||||
krand();
|
||||
/*kseed(Rl);
|
||||
krand();*/
|
||||
}
|
||||
|
||||
// Let's create a new kernel stack
|
||||
|
@ -96,14 +87,14 @@ void kmain(void *MultibootHeader, u32 Magic)
|
|||
__asm__ volatile("mov %0, %%esp" : : "r" (0xA0000000 + 4095));
|
||||
|
||||
// This automagically creates a new usable stack frame
|
||||
kmain_newstack();
|
||||
kmain_newstack();*/
|
||||
}
|
||||
|
||||
void kmain_newstack(void)
|
||||
/*void kmain_newstack(void)
|
||||
{
|
||||
kprintf("[i] Now using real stack...\n");
|
||||
cpp_call_ctors();
|
||||
cpp_start_ckernel();
|
||||
kprintf("[i] Returned from Tier1, sleeping forever.\n");
|
||||
LOOPFOREVER;
|
||||
}
|
||||
}*/
|
|
@ -1,7 +1,7 @@
|
|||
#include "types.h"
|
||||
#include "Tier0/kstdio.h"
|
||||
#include "Tier0/kstdlib.h"
|
||||
#include "Tier0/semaphore.h"
|
||||
//#include "Tier0/semaphore.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#define va_start(v,l) __builtin_va_start(v,l)
|
||||
|
@ -13,11 +13,20 @@ typedef __builtin_va_list va_list;
|
|||
u8 g_kstdio_current_line = 0;
|
||||
u8 g_kstdio_cur_x = 0, g_kstdio_cur_y = 0;
|
||||
|
||||
T_SEMAPHORE ScreenWriteLock;
|
||||
//T_SEMAPHORE ScreenWriteLock;
|
||||
|
||||
#define VIDEO_MEMORY ((u64)0xB8000)
|
||||
|
||||
void kstdio_set_globals(u8 line, u8 cur_x, u8 cur_y)
|
||||
{
|
||||
g_kstdio_current_line = line;
|
||||
g_kstdio_cur_x = cur_x;
|
||||
g_kstdio_cur_y = cur_y;
|
||||
}
|
||||
|
||||
void kstdio_init(void)
|
||||
{
|
||||
semaphore_init(&ScreenWriteLock);
|
||||
//semaphore_init(&ScreenWriteLock);
|
||||
}
|
||||
|
||||
void koutb(u16 Port, u8 Data)
|
||||
|
@ -124,9 +133,9 @@ void kscroll_up(void)
|
|||
if (g_kstdio_cur_y >= 25)
|
||||
{
|
||||
Temp = g_kstdio_cur_y - 25 + 1;
|
||||
kmemcpy((void*)0xC00B8000, (void*)(0xC00B8000 + Temp * 80 * 2), (25 - Temp) * 80 * 2);
|
||||
kmemcpy((void*)VIDEO_MEMORY, (void*)(VIDEO_MEMORY + Temp * 80 * 2), (25 - Temp) * 80 * 2);
|
||||
|
||||
kmemsetw((void*)(0xC00B8000 + (25 - Temp) * 160), Blank, 160);
|
||||
kmemsetw((void*)(VIDEO_MEMORY + (25 - Temp) * 160), Blank, 160);
|
||||
g_kstdio_cur_y = 25 - 1;
|
||||
}
|
||||
//semaphore_release(&ScreenWriteLock);
|
||||
|
@ -199,8 +208,8 @@ void kdump(u8 *bData, u32 Length)
|
|||
|
||||
void kputch(s8 Character)
|
||||
{
|
||||
semaphore_acquire(&ScreenWriteLock);
|
||||
volatile u8 *VideoMemory = (u8 *)0xC00B8000;
|
||||
//semaphore_acquire(&ScreenWriteLock);
|
||||
volatile u8 *VideoMemory = (u8 *)VIDEO_MEMORY;
|
||||
u16 Offset = (g_kstdio_cur_y * 80 + g_kstdio_cur_x) << 1;
|
||||
|
||||
if (Character == '\n')
|
||||
|
@ -214,7 +223,7 @@ void kputch(s8 Character)
|
|||
else
|
||||
kmove_cursor(g_kstdio_cur_x + 1, g_kstdio_cur_y);
|
||||
}
|
||||
semaphore_release(&ScreenWriteLock);
|
||||
//semaphore_release(&ScreenWriteLock);
|
||||
}
|
||||
|
||||
void kputs(const s8 *szString)
|
||||
|
@ -233,7 +242,7 @@ void kprint(const s8 *szString)
|
|||
|
||||
void kclear(void)
|
||||
{
|
||||
volatile u8 *VideoMemory = (u8 *)0xC00B8000;
|
||||
volatile u8 *VideoMemory = (u8 *)VIDEO_MEMORY;
|
||||
u32 Size = (80 * 25 ) << 1;
|
||||
for (u32 i = 0; i < Size; i += 2)
|
||||
{
|
|
@ -1,7 +1,7 @@
|
|||
#include "types.h"
|
||||
#include "Tier0/kstdlib.h"
|
||||
|
||||
void *kmemcpy(void* Destination, const void *Source, u32 Count)
|
||||
void *kmemcpy(void* Destination, const void *Source, u64 Count)
|
||||
{
|
||||
u8* Destination8 = (u8*)Destination;
|
||||
u8* Source8 = (u8*)Source;
|
||||
|
@ -13,7 +13,7 @@ void *kmemcpy(void* Destination, const void *Source, u32 Count)
|
|||
return Destination;
|
||||
}
|
||||
|
||||
void *kmemset(void *Destination, u8 Value, u32 Count)
|
||||
void *kmemset(void *Destination, u8 Value, u64 Count)
|
||||
{
|
||||
u8 *us = (u8 *)Destination;
|
||||
while (Count-- != 0)
|
||||
|
@ -21,7 +21,7 @@ void *kmemset(void *Destination, u8 Value, u32 Count)
|
|||
return Destination;
|
||||
}
|
||||
|
||||
void *kmemsetw(void *Destination, u16 Value, u32 Count)
|
||||
void *kmemsetw(void *Destination, u16 Value, u64 Count)
|
||||
{
|
||||
u16 *us = (u16 *)Destination;
|
||||
while (Count-- != 0)
|
|
@ -0,0 +1,46 @@
|
|||
OUTPUT_FORMAT(elf64-x86-64)
|
||||
ENTRY(kmain)
|
||||
|
||||
KERNEL_VMA = 0x00000000FF000000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = KERNEL_VMA;
|
||||
|
||||
.text : AT(ADDR(.text) - KERNEL_VMA)
|
||||
{
|
||||
_code = .;
|
||||
*(.text)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
.data : AT(ADDR(.data) - KERNEL_VMA)
|
||||
{
|
||||
_data = .;
|
||||
*(.data)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
.ehframe : AT(ADDR(.ehframe) - KERNEL_VMA)
|
||||
{
|
||||
_ehframe = .;
|
||||
*(.ehframe)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
.bss : AT(ADDR(.bss) - KERNEL_VMA)
|
||||
{
|
||||
_bss = .;
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.comment)
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
OUTPUT_FORMAT("elf32-i386")
|
||||
ENTRY(_start)
|
||||
|
||||
Offset = 0x00100000;
|
||||
LMA = 0x00000000;
|
||||
VMA = 0xC0000000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = Offset;
|
||||
|
||||
g_setup_gdt_ptr = g_gdt_ptr - VMA;
|
||||
g_setup_gdt_entries = g_gdt_entries - VMA;
|
||||
|
||||
.setup LMA + Offset : AT(LMA + Offset)
|
||||
{
|
||||
*(.setup)
|
||||
. = ALIGN(0x1000);
|
||||
}
|
||||
|
||||
. += VMA;
|
||||
|
||||
.text : AT(g_section_code)
|
||||
{
|
||||
g_section_code = . - VMA;
|
||||
*(.text*)
|
||||
*(.gnu.linkonce.t*)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
g_start_ctors = .;
|
||||
*(.ctors)
|
||||
g_end_ctors = .;
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
}
|
||||
|
||||
.data : AT(g_section_data)
|
||||
{
|
||||
g_section_data = . - VMA;
|
||||
*(.data*)
|
||||
*(.gnu.linkonce.d*)
|
||||
*(.rodata*)
|
||||
*(.gnu.linkonce.r*)
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
}
|
||||
|
||||
.bss : AT(g_section_bss)
|
||||
{
|
||||
g_section_bss = . - VMA;
|
||||
*(COMMON*)
|
||||
*(.bss*)
|
||||
. = ALIGN(0x1000);
|
||||
}
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.comment)
|
||||
*(.eh_frame)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue