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...
|
// Try to find the pointer... apparently it's 16byte-aligned...
|
||||||
|
|
||||||
u32 Address = 0;
|
u64 Address = 0;
|
||||||
for (u32 Search = 0x000E0000; Search <= 0x000FFFFF; Search += 4)
|
for (u64 Search = 0x000E0000; Search <= 0x000FFFFF; Search += 4)
|
||||||
{
|
{
|
||||||
if (kmemcmp((u8 *)Search, (u8 *)szMagic, 8) == 0)
|
if (kmemcmp((u8 *)Search, (u8 *)szMagic, 8) == 0)
|
||||||
{
|
{
|
|
@ -3,15 +3,15 @@
|
||||||
#include "Tier0/cpp.h"
|
#include "Tier0/cpp.h"
|
||||||
#include "Tier0/kstdio.h"
|
#include "Tier0/kstdio.h"
|
||||||
|
|
||||||
extern u32 g_start_ctors;
|
extern u64 g_start_ctors;
|
||||||
extern u32 g_end_ctors;
|
extern u64 g_end_ctors;
|
||||||
void CKernelStart(void);
|
void CKernelStart(void);
|
||||||
|
|
||||||
void cpp_call_ctors(void)
|
void cpp_call_ctors(void)
|
||||||
{
|
{
|
||||||
u32 Number = ((void *)&g_end_ctors - (void *)&g_start_ctors) / 4;
|
u32 Number = ((void *)&g_end_ctors - (void *)&g_start_ctors) / 4;
|
||||||
kprintf("[i] Calling %i constructors before jumping to Tier1..\n", Number);
|
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)) ();
|
((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)
|
void exceptions_page_fault_isr(T_ISR_REGISTERS_ERR Registers)
|
||||||
{
|
{
|
||||||
u32 FaultAddress;
|
u64 FaultAddress;
|
||||||
__asm__ volatile("mov %%cr2, %0" : "=r" (FaultAddress));
|
__asm__ volatile("mov %%cr2, %0" : "=r" (FaultAddress));
|
||||||
|
|
||||||
u8 Present = !(Registers.Error & 0x01);
|
u8 Present = !(Registers.Error & 0x01);
|
|
@ -34,7 +34,7 @@ void gdt_entry_create_null(u8 Index)
|
||||||
void gdt_create_flat(void)
|
void gdt_create_flat(void)
|
||||||
{
|
{
|
||||||
g_gdt_ptr.Size = sizeof(T_GDT_ENTRY) * 6 - 1;
|
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_null(0);
|
||||||
gdt_entry_create(1, 0, 0xFFFFFFFF, GDT_RING0, GDT_EXECUTABLE, GDT_RW);
|
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--;
|
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)
|
if ((End - Start) % (1024 * 4) != 0)
|
||||||
NumPages++;
|
NumPages++;
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ T_HEAP *heap_create(u32 Start, u32 End, u32 Max)
|
||||||
NumPages, (End - Start) / 0x100000);
|
NumPages, (End - Start) / 0x100000);
|
||||||
for (int i = 0; i < NumPages; i++)
|
for (int i = 0; i < NumPages; i++)
|
||||||
{
|
{
|
||||||
u32 Page = physmem_allocate_page();
|
u64 Page = physmem_allocate_page();
|
||||||
u32 Physical = physmem_page_to_physical(Page);
|
u64 Physical = physmem_page_to_physical(Page);
|
||||||
paging_map_kernel_page(Start + i * 1024 * 4, Physical);
|
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;
|
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)
|
while (Iterator < Heap->Index.Size)
|
||||||
{
|
{
|
||||||
T_HEAP_HEADER *Header = heap_index_get(&Heap->Index, Iterator);
|
T_HEAP_HEADER *Header = heap_index_get(&Heap->Index, Iterator);
|
||||||
if (Aligned > 0)
|
if (Aligned > 0)
|
||||||
{
|
{
|
||||||
u32 Location = (u32)Header;
|
u64 Location = (u64)Header;
|
||||||
u32 Offset = 0;
|
u64 Offset = 0;
|
||||||
|
|
||||||
if (((Location + sizeof(T_HEAP_HEADER)) & 0xFFFFF000) != 0)
|
if (((Location + sizeof(T_HEAP_HEADER)) & 0xFFFFF000) != 0)
|
||||||
Offset = 0x1000 - (Location + sizeof(T_HEAP_HEADER)) % 0x1000;
|
Offset = 0x1000 - (Location + sizeof(T_HEAP_HEADER)) % 0x1000;
|
||||||
|
|
||||||
u32 HoleSize = (u32)Header->Size - Offset;
|
u32 HoleSize = (u64)Header->Size - Offset;
|
||||||
|
|
||||||
if (HoleSize >= Size)
|
if (HoleSize >= Size)
|
||||||
break;
|
break;
|
||||||
|
@ -126,23 +126,23 @@ s32 _heap_find_smallest_hole(T_HEAP *Heap, u32 Size, u8 Aligned)
|
||||||
return Iterator;
|
return Iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _heap_expand(T_HEAP *Heap, u32 Size)
|
void _heap_expand(T_HEAP *Heap, u64 Size)
|
||||||
{
|
{
|
||||||
u16 NumPages = Size / 0x1000;
|
u16 NumPages = Size / 0x1000;
|
||||||
if (Size % 0x1000 != 0)
|
if (Size % 0x1000 != 0)
|
||||||
NumPages++;
|
NumPages++;
|
||||||
|
|
||||||
for (u32 i = 0; i < NumPages; i++)
|
for (u64 i = 0; i < NumPages; i++)
|
||||||
{
|
{
|
||||||
u32 Page = physmem_allocate_page();
|
u64 Page = physmem_allocate_page();
|
||||||
u32 Physical = physmem_page_to_physical(Page);
|
u64 Physical = physmem_page_to_physical(Page);
|
||||||
paging_map_kernel_page(Heap->End + i * 0x1000, Physical);
|
paging_map_kernel_page(Heap->End + i * 0x1000, Physical);
|
||||||
}
|
}
|
||||||
|
|
||||||
Heap->End = Heap->Start + NumPages * 0x1000;
|
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)
|
if (Size & 0x1000)
|
||||||
{
|
{
|
||||||
|
@ -153,15 +153,15 @@ u32 _heap_contract(T_HEAP *Heap, u32 Size)
|
||||||
if (Size < HEAP_MIN_SIZE)
|
if (Size < HEAP_MIN_SIZE)
|
||||||
Size = HEAP_MIN_SIZE;
|
Size = HEAP_MIN_SIZE;
|
||||||
|
|
||||||
u32 OldSize = Heap->End - Heap->Start;
|
u64 OldSize = Heap->End - Heap->Start;
|
||||||
u32 NumberToDelete = (OldSize - Size) / 0x1000;
|
u64 NumberToDelete = (OldSize - Size) / 0x1000;
|
||||||
|
|
||||||
for (int i = 0; i < NumberToDelete; i++)
|
for (int i = 0; i < NumberToDelete; i++)
|
||||||
{
|
{
|
||||||
u32 Virtual = Heap->End + i * 0x1000;
|
u64 Virtual = Heap->End + i * 0x1000;
|
||||||
u32 Physical;
|
u64 Physical;
|
||||||
paging_get_physical(Virtual, &Physical);
|
paging_get_physical(Virtual, &Physical);
|
||||||
u32 Page = Physical / 0x1000;
|
u64 Page = Physical / 0x1000;
|
||||||
physmem_free_page(Page);
|
physmem_free_page(Page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,35 +170,35 @@ u32 _heap_contract(T_HEAP *Heap, u32 Size)
|
||||||
return (Heap->End - Heap->Start);
|
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);
|
void *Address = heap_alloc(Heap, Size, Aligned);
|
||||||
|
|
||||||
if (Physical != 0)
|
if (Physical != 0)
|
||||||
paging_get_physical((u32)Address, Physical);
|
paging_get_physical((u64)Address, Physical);
|
||||||
|
|
||||||
return Address;
|
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);
|
u64 RealSize = Size + sizeof(T_HEAP_HEADER) + sizeof(T_HEAP_FOOTER);
|
||||||
s32 Iterator = _heap_find_smallest_hole(Heap, RealSize, Aligned);
|
s64 Iterator = _heap_find_smallest_hole(Heap, RealSize, Aligned);
|
||||||
|
|
||||||
if (Iterator == -1)
|
if (Iterator == -1)
|
||||||
{
|
{
|
||||||
u32 OldSize = Heap->End - Heap->Start;
|
u64 OldSize = Heap->End - Heap->Start;
|
||||||
u32 OldEnd = Heap->End;
|
u64 OldEnd = Heap->End;
|
||||||
_heap_expand(Heap, OldSize + RealSize);
|
_heap_expand(Heap, OldSize + RealSize);
|
||||||
u32 NewSize = Heap->End - Heap->Start;
|
u64 NewSize = Heap->End - Heap->Start;
|
||||||
|
|
||||||
Iterator = 0;
|
Iterator = 0;
|
||||||
u32 Last = 0;
|
u64 Last = 0;
|
||||||
s32 LastIndex = -1;
|
s64 LastIndex = -1;
|
||||||
|
|
||||||
while (Iterator < Heap->Index.Size)
|
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)
|
if (Location > Last)
|
||||||
{
|
{
|
||||||
Last = Location;
|
Last = Location;
|
||||||
|
@ -226,7 +226,7 @@ void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned)
|
||||||
T_HEAP_HEADER *Header = (T_HEAP_HEADER *)Last;
|
T_HEAP_HEADER *Header = (T_HEAP_HEADER *)Last;
|
||||||
Header->Size += NewSize - OldSize;
|
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));
|
+ Header->Size - sizeof(T_HEAP_FOOTER));
|
||||||
Footer->Header = Header;
|
Footer->Header = Header;
|
||||||
Footer->Magic = HEAP_FOOTER_MAGIC;
|
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,
|
T_HEAP_HEADER *Header = (T_HEAP_HEADER*)heap_index_get(&Heap->Index,
|
||||||
Iterator);
|
Iterator);
|
||||||
u32 HoleStart = (u32)Header;
|
u64 HoleStart = (u64)Header;
|
||||||
u32 HoleSize = Header->Size;
|
u64 HoleSize = Header->Size;
|
||||||
|
|
||||||
if (HoleSize - RealSize < sizeof(T_HEAP_HEADER) + sizeof(T_HEAP_FOOTER))
|
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)
|
if (Aligned && HoleStart & 0xFFFFF000)
|
||||||
{
|
{
|
||||||
u32 NewLocation = HoleStart + 0x1000 - (HoleStart & 0xFFF)
|
u64 NewLocation = HoleStart + 0x1000 - (HoleStart & 0xFFF)
|
||||||
- sizeof(T_HEAP_HEADER);
|
- sizeof(T_HEAP_HEADER);
|
||||||
Header->Size = 0x1000 - (HoleStart & 0xFFF) - sizeof(T_HEAP_HEADER);
|
Header->Size = 0x1000 - (HoleStart & 0xFFF) - sizeof(T_HEAP_HEADER);
|
||||||
Header->Magic = HEAP_HEADER_MAGIC;
|
Header->Magic = HEAP_HEADER_MAGIC;
|
||||||
|
@ -283,10 +283,10 @@ void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned)
|
||||||
NewHoleHeader->Size = HoleSize - RealSize;
|
NewHoleHeader->Size = HoleSize - RealSize;
|
||||||
NewHoleHeader->Hole = 1;
|
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));
|
+ NewHoleHeader->Size - sizeof(T_HEAP_FOOTER));
|
||||||
|
|
||||||
if ((u32)NewHoleFooter < Heap->End)
|
if ((u64)NewHoleFooter < Heap->End)
|
||||||
{
|
{
|
||||||
NewHoleFooter->Magic = HEAP_FOOTER_MAGIC;
|
NewHoleFooter->Magic = HEAP_FOOTER_MAGIC;
|
||||||
NewHoleFooter->Header = NewHoleHeader;
|
NewHoleFooter->Header = NewHoleHeader;
|
||||||
|
@ -295,15 +295,15 @@ void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned)
|
||||||
heap_index_insert(&Heap->Index, (void*)NewHoleHeader);
|
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)
|
void heap_free(T_HEAP *Heap, void *Data)
|
||||||
{
|
{
|
||||||
if (Data == 0) return;
|
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));
|
- 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));
|
- sizeof(T_HEAP_FOOTER));
|
||||||
|
|
||||||
if (Header->Magic != HEAP_HEADER_MAGIC)
|
if (Header->Magic != HEAP_HEADER_MAGIC)
|
||||||
|
@ -314,27 +314,27 @@ void heap_free(T_HEAP *Heap, void *Data)
|
||||||
|
|
||||||
u8 ShouldAdd = 1;
|
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));
|
- sizeof(T_HEAP_FOOTER));
|
||||||
if (FooterLeft->Magic == HEAP_FOOTER_MAGIC && FooterLeft->Header->Hole)
|
if (FooterLeft->Magic == HEAP_FOOTER_MAGIC && FooterLeft->Header->Hole)
|
||||||
{
|
{
|
||||||
u32 OurSize = Header->Size;
|
u64 OurSize = Header->Size;
|
||||||
Header = FooterLeft->Header;
|
Header = FooterLeft->Header;
|
||||||
Footer->Header = Header;
|
Footer->Header = Header;
|
||||||
Header->Size += OurSize;
|
Header->Size += OurSize;
|
||||||
ShouldAdd = 0;
|
ShouldAdd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
T_HEAP_HEADER *HeaderRight = (T_HEAP_HEADER *)((u32)Footer
|
T_HEAP_HEADER *HeaderRight = (T_HEAP_HEADER *)((u64)Footer
|
||||||
+ sizeof(T_HEAP_FOOTER));
|
+ sizeof(T_HEAP_FOOTER));
|
||||||
if (HeaderRight->Magic == HEAP_HEADER_MAGIC && HeaderRight->Hole)
|
if (HeaderRight->Magic == HEAP_HEADER_MAGIC && HeaderRight->Hole)
|
||||||
{
|
{
|
||||||
Header->Size += HeaderRight->Size;
|
Header->Size += HeaderRight->Size;
|
||||||
Footer = (T_HEAP_FOOTER *)((u32)HeaderRight + HeaderRight->Size
|
Footer = (T_HEAP_FOOTER *)((u64)HeaderRight + HeaderRight->Size
|
||||||
- sizeof(T_HEAP_FOOTER));
|
- sizeof(T_HEAP_FOOTER));
|
||||||
Footer->Header = Header;
|
Footer->Header = Header;
|
||||||
|
|
||||||
u32 Iterator = 0;
|
u64 Iterator = 0;
|
||||||
while (Iterator < Heap->Index.Size &&
|
while (Iterator < Heap->Index.Size &&
|
||||||
heap_index_get(&Heap->Index, Iterator) != (void *)HeaderRight)
|
heap_index_get(&Heap->Index, Iterator) != (void *)HeaderRight)
|
||||||
Iterator++;
|
Iterator++;
|
||||||
|
@ -343,22 +343,22 @@ void heap_free(T_HEAP *Heap, void *Data)
|
||||||
heap_index_remove(&Heap->Index, Iterator);
|
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;
|
u64 OldSize = Heap->End - Heap->Start;
|
||||||
u32 NewSize = _heap_contract(Heap, (u32)Header - Heap->Start);
|
u64 NewSize = _heap_contract(Heap, (u64)Header - Heap->Start);
|
||||||
|
|
||||||
if (Header->Size > (OldSize - NewSize))
|
if (Header->Size > (OldSize - NewSize))
|
||||||
{
|
{
|
||||||
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));
|
- sizeof(T_HEAP_FOOTER));
|
||||||
Footer->Magic = HEAP_FOOTER_MAGIC;
|
Footer->Magic = HEAP_FOOTER_MAGIC;
|
||||||
Footer->Header = Header;
|
Footer->Header = Header;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u32 Iterator = 0;
|
u64 Iterator = 0;
|
||||||
while (Iterator < Heap->Index.Size &&
|
while (Iterator < Heap->Index.Size &&
|
||||||
heap_index_get(&Heap->Index, Iterator) != (void *)Header)
|
heap_index_get(&Heap->Index, Iterator) != (void *)Header)
|
||||||
Iterator++;
|
Iterator++;
|
||||||
|
@ -381,12 +381,12 @@ void heap_init_simple(void)
|
||||||
HEAP_START + 0x0FFFF000);
|
HEAP_START + 0x0FFFF000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *kmalloc(u32 Size)
|
void *kmalloc(u64 Size)
|
||||||
{
|
{
|
||||||
return heap_alloc(g_heap, Size, 0);
|
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);
|
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
|
SHELL:=/bin/bash
|
||||||
ENV:=/usr/xdev/bin
|
ENV:=/usr/xdev/bin
|
||||||
TARGET:=i586-elf
|
TARGET:=x86_64-elf
|
||||||
CC:=$(ENV)/$(TARGET)-gcc
|
CC:=$(ENV)/$(TARGET)-gcc
|
||||||
CX:=$(ENV)/$(TARGET)-g++
|
CX:=$(ENV)/$(TARGET)-g++
|
||||||
AS:=nasm
|
AS:=nasm
|
||||||
LD:=$(ENV)/$(TARGET)-ld
|
LD:=$(ENV)/$(TARGET)-ld
|
||||||
|
|
||||||
# -O2 sets -foptimize-sibling-calls which breaks code...
|
# -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
|
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
|
obj/src/%.nao : src/%.asm
|
||||||
@echo "[i] Assembling $*.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
|
obj/src/%.o : src/%.c
|
||||||
@echo "[i] Compiling $*.c ..."
|
@echo "[i] Compiling $*.c ..."
|
||||||
|
@if [ -e obj/src/$*.o ] ; then rm obj/src/$*.o ; fi
|
||||||
@mkdir -p obj/src/$*.o
|
@mkdir -p obj/src/$*.o
|
||||||
@rmdir obj/src/$*.o
|
@rmdir obj/src/$*.o
|
||||||
@$(CC) $(CFLAGS) -c src/$*.c -o 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
|
@qemu -kernel kernel.bin -S -gdb tcp::1234
|
||||||
|
|
||||||
emulate-nohdd: kernel.bin
|
emulate-nohdd: kernel.bin
|
||||||
|
@echo "[i] Building loader..."
|
||||||
|
@pushd ../Loader > /dev/null && $(MAKE) -f Makefile loader.bin && popd > /dev/null
|
||||||
@echo "[i] Starting QEMU..."
|
@echo "[i] Starting QEMU..."
|
||||||
@qemu -kernel kernel.bin
|
@qemu-system-x86_64 -kernel ../Loader/loader.bin -initrd kernel.bin
|
||||||
|
|
||||||
emulate: hdd.img
|
emulate: hdd.img
|
||||||
@echo "[i] Starting QEmu..."
|
@echo "[i] Starting QEmu..."
|
|
@ -15,7 +15,7 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 Magic;
|
u32 Magic;
|
||||||
u8 Hole;
|
u8 Hole;
|
||||||
u32 Size;
|
u64 Size;
|
||||||
} T_HEAP_HEADER;
|
} T_HEAP_HEADER;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -25,8 +25,8 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void **Array;
|
void **Array;
|
||||||
u32 Size;
|
u64 Size;
|
||||||
u32 MaxSize;
|
u64 MaxSize;
|
||||||
} T_HEAP_INDEX;
|
} T_HEAP_INDEX;
|
||||||
|
|
||||||
T_HEAP_INDEX heap_index_initialize(void *Address, u32 MaxSize);
|
T_HEAP_INDEX heap_index_initialize(void *Address, u32 MaxSize);
|
||||||
|
@ -35,19 +35,19 @@ u8 heap_index_smaller(void *A, void *B);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
T_HEAP_INDEX Index;
|
T_HEAP_INDEX Index;
|
||||||
u32 Start;
|
u64 Start;
|
||||||
u32 End;
|
u64 End;
|
||||||
u32 Max;
|
u64 Max;
|
||||||
} T_HEAP;
|
} T_HEAP;
|
||||||
|
|
||||||
T_HEAP *heap_create(u32 Start, u32 End, u32 Max);
|
T_HEAP *heap_create(u64 Start, u64 End, u64 Max);
|
||||||
void *heap_alloc(T_HEAP *Heap, u32 Size, u8 Aligned);
|
void *heap_alloc(T_HEAP *Heap, u64 Size, u8 Aligned);
|
||||||
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 heap_free(T_HEAP *Heap, void *Address);
|
void heap_free(T_HEAP *Heap, void *Address);
|
||||||
|
|
||||||
void heap_init_simple(void);
|
void heap_init_simple(void);
|
||||||
void *kmalloc(u32 Size);
|
void *kmalloc(u64 Size);
|
||||||
void *kmalloc_p(u32 Size, u8 Aligned, u32 *Physical);
|
void *kmalloc_p(u64 Size, u8 Aligned, u64 *Physical);
|
||||||
void kfree(void *Data);
|
void kfree(void *Data);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -39,14 +39,14 @@ typedef enum E_INTERRUPTS_CHIP T_INTERRUPTS_CHIP;
|
||||||
struct S_ISR_STUB {
|
struct S_ISR_STUB {
|
||||||
u16 Code1;
|
u16 Code1;
|
||||||
u8 Code2;
|
u8 Code2;
|
||||||
u32 Handler;
|
u64 Handler;
|
||||||
u32 Code3;
|
u32 Code3;
|
||||||
u8 Code4;
|
u8 Code4;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
typedef struct S_ISR_STUB T_ISR_STUB;
|
typedef struct S_ISR_STUB T_ISR_STUB;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
u64 edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||||
u32 Error;
|
u32 Error;
|
||||||
u32 eip, cs, eflags, useresp, ss;
|
u32 eip, cs, eflags, useresp, ss;
|
||||||
} T_ISR_REGISTERS_ERR;
|
} T_ISR_REGISTERS_ERR;
|
|
@ -19,6 +19,7 @@ void kputi(s32 Number);
|
||||||
void kprintf(const s8 *Format, ...);
|
void kprintf(const s8 *Format, ...);
|
||||||
void kdump(u8 *bData, u32 Length);
|
void kdump(u8 *bData, u32 Length);
|
||||||
void kprint_hex(u32 Number);
|
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);
|
s32 kmemcmp(u8 *MemA, u8 *MemB, u32 Length);
|
||||||
|
|
||||||
#endif
|
#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;
|
} T_PAGING_DIRECTORY;
|
||||||
|
|
||||||
void paging_init_simple(void);
|
void paging_init_simple(void);
|
||||||
u8 paging_get_physical(u32 Virtual, u32 *Physical);
|
u8 paging_get_physical(u64 Virtual, u64 *Physical);
|
||||||
u8 paging_get_physical_ex(u32 Virtual, u32 *Physical,
|
u8 paging_get_physical_ex(u64 Virtual, u64 *Physical,
|
||||||
T_PAGING_DIRECTORY *Directory);
|
T_PAGING_DIRECTORY *Directory);
|
||||||
void paging_map_kernel_page(u32 Virtual, u32 Physical);
|
void paging_map_kernel_page(u64 Virtual, u64 Physical);
|
||||||
void paging_map_kernel_table(u32 Virtual, u32 Physical);
|
void paging_map_kernel_table(u64 Virtual, u64 Physical);
|
||||||
void paging_map_page(u32 Virtual, u32 Physical, T_PAGING_DIRECTORY *Directory,
|
void paging_map_page(u64 Virtual, u64 Physical, T_PAGING_DIRECTORY *Directory,
|
||||||
u8 User, u8 RW);
|
u8 User, u8 RW);
|
||||||
void paging_use_directory(T_PAGING_DIRECTORY *Directory);
|
void paging_use_directory(T_PAGING_DIRECTORY *Directory);
|
||||||
T_PAGING_DIRECTORY *paging_get_directory(void);
|
T_PAGING_DIRECTORY *paging_get_directory(void);
|
|
@ -8,6 +8,7 @@ typedef unsigned int u32;
|
||||||
typedef unsigned short u16;
|
typedef unsigned short u16;
|
||||||
typedef unsigned char u8;
|
typedef unsigned char u8;
|
||||||
|
|
||||||
|
typedef long long s64;
|
||||||
typedef int s32;
|
typedef int s32;
|
||||||
typedef short s16;
|
typedef short s16;
|
||||||
typedef char s8;
|
typedef char s8;
|
|
@ -1,6 +1,6 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "Tier0/kstdio.h"
|
#include "Tier0/kstdio.h"
|
||||||
#include "Tier0/gdt.h"
|
/*#include "Tier0/gdt.h"
|
||||||
#include "Tier0/paging.h"
|
#include "Tier0/paging.h"
|
||||||
#include "Tier0/acpi.h"
|
#include "Tier0/acpi.h"
|
||||||
#include "Tier0/interrupts.h"
|
#include "Tier0/interrupts.h"
|
||||||
|
@ -13,31 +13,24 @@
|
||||||
#include "Tier0/cpp.h"
|
#include "Tier0/cpp.h"
|
||||||
#include "Tier0/exceptions.h"
|
#include "Tier0/exceptions.h"
|
||||||
#include "Tier0/panic.h"
|
#include "Tier0/panic.h"
|
||||||
#include "Tier0/prng.h"
|
#include "Tier0/prng.h"*/
|
||||||
|
|
||||||
void interrupts_irq_sample(void);
|
// Real kernel entry point, called from loader
|
||||||
|
void kmain(u32 current_line, u32 cursor_x, u32 cursor_y)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
kstdio_init();
|
kstdio_init();
|
||||||
kclear();
|
kstdio_set_globals(current_line, cursor_x, cursor_y);
|
||||||
kprintf(" _ \n"
|
//kclear();
|
||||||
|
kprintf("\n _ \n"
|
||||||
" ___ _ _ ___ _ _ _____| |_ ___ ___ \n"
|
" ___ _ _ ___ _ _ _____| |_ ___ ___ \n"
|
||||||
" | _| | | _| | | | . | -_| _|\n"
|
" | _| | | _| | | | . | -_| _|\n"
|
||||||
" |___|___|___|___|_|_|_|___|___|_| \n\n");
|
" |___|___|___|___|_|_|_|___|___|_| \n\n");
|
||||||
kprintf("[i] Welcome to Cucumber!\n\n");
|
kprintf("[i] Welcome to Cucumber (x86-64)!\n");
|
||||||
|
//kprintf("%x %x %x\n", current_line, cursor_x, cursor_y);
|
||||||
if (Magic != 0x2BADB002)
|
|
||||||
|
for (;;) {}
|
||||||
|
|
||||||
|
/*if (Magic != 0x2BADB002)
|
||||||
{
|
{
|
||||||
kprintf("[e] Fatal! Boot via incompatible bootloader.\n");
|
kprintf("[e] Fatal! Boot via incompatible bootloader.\n");
|
||||||
return;
|
return;
|
||||||
|
@ -84,8 +77,6 @@ void kmain(void *MultibootHeader, u32 Magic)
|
||||||
for (u32 Rl = 0; Rl < R; Rl++)
|
for (u32 Rl = 0; Rl < R; Rl++)
|
||||||
{
|
{
|
||||||
krand();
|
krand();
|
||||||
/*kseed(Rl);
|
|
||||||
krand();*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's create a new kernel stack
|
// 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));
|
__asm__ volatile("mov %0, %%esp" : : "r" (0xA0000000 + 4095));
|
||||||
|
|
||||||
// This automagically creates a new usable stack frame
|
// 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");
|
kprintf("[i] Now using real stack...\n");
|
||||||
cpp_call_ctors();
|
cpp_call_ctors();
|
||||||
cpp_start_ckernel();
|
cpp_start_ckernel();
|
||||||
kprintf("[i] Returned from Tier1, sleeping forever.\n");
|
kprintf("[i] Returned from Tier1, sleeping forever.\n");
|
||||||
LOOPFOREVER;
|
LOOPFOREVER;
|
||||||
}
|
}*/
|
|
@ -1,7 +1,7 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "Tier0/kstdio.h"
|
#include "Tier0/kstdio.h"
|
||||||
#include "Tier0/kstdlib.h"
|
#include "Tier0/kstdlib.h"
|
||||||
#include "Tier0/semaphore.h"
|
//#include "Tier0/semaphore.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define va_start(v,l) __builtin_va_start(v,l)
|
#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_current_line = 0;
|
||||||
u8 g_kstdio_cur_x = 0, g_kstdio_cur_y = 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)
|
void kstdio_init(void)
|
||||||
{
|
{
|
||||||
semaphore_init(&ScreenWriteLock);
|
//semaphore_init(&ScreenWriteLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void koutb(u16 Port, u8 Data)
|
void koutb(u16 Port, u8 Data)
|
||||||
|
@ -124,9 +133,9 @@ void kscroll_up(void)
|
||||||
if (g_kstdio_cur_y >= 25)
|
if (g_kstdio_cur_y >= 25)
|
||||||
{
|
{
|
||||||
Temp = g_kstdio_cur_y - 25 + 1;
|
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;
|
g_kstdio_cur_y = 25 - 1;
|
||||||
}
|
}
|
||||||
//semaphore_release(&ScreenWriteLock);
|
//semaphore_release(&ScreenWriteLock);
|
||||||
|
@ -199,8 +208,8 @@ void kdump(u8 *bData, u32 Length)
|
||||||
|
|
||||||
void kputch(s8 Character)
|
void kputch(s8 Character)
|
||||||
{
|
{
|
||||||
semaphore_acquire(&ScreenWriteLock);
|
//semaphore_acquire(&ScreenWriteLock);
|
||||||
volatile u8 *VideoMemory = (u8 *)0xC00B8000;
|
volatile u8 *VideoMemory = (u8 *)VIDEO_MEMORY;
|
||||||
u16 Offset = (g_kstdio_cur_y * 80 + g_kstdio_cur_x) << 1;
|
u16 Offset = (g_kstdio_cur_y * 80 + g_kstdio_cur_x) << 1;
|
||||||
|
|
||||||
if (Character == '\n')
|
if (Character == '\n')
|
||||||
|
@ -214,7 +223,7 @@ void kputch(s8 Character)
|
||||||
else
|
else
|
||||||
kmove_cursor(g_kstdio_cur_x + 1, g_kstdio_cur_y);
|
kmove_cursor(g_kstdio_cur_x + 1, g_kstdio_cur_y);
|
||||||
}
|
}
|
||||||
semaphore_release(&ScreenWriteLock);
|
//semaphore_release(&ScreenWriteLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kputs(const s8 *szString)
|
void kputs(const s8 *szString)
|
||||||
|
@ -233,7 +242,7 @@ void kprint(const s8 *szString)
|
||||||
|
|
||||||
void kclear(void)
|
void kclear(void)
|
||||||
{
|
{
|
||||||
volatile u8 *VideoMemory = (u8 *)0xC00B8000;
|
volatile u8 *VideoMemory = (u8 *)VIDEO_MEMORY;
|
||||||
u32 Size = (80 * 25 ) << 1;
|
u32 Size = (80 * 25 ) << 1;
|
||||||
for (u32 i = 0; i < Size; i += 2)
|
for (u32 i = 0; i < Size; i += 2)
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "Tier0/kstdlib.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* Destination8 = (u8*)Destination;
|
||||||
u8* Source8 = (u8*)Source;
|
u8* Source8 = (u8*)Source;
|
||||||
|
@ -13,7 +13,7 @@ void *kmemcpy(void* Destination, const void *Source, u32 Count)
|
||||||
return Destination;
|
return Destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *kmemset(void *Destination, u8 Value, u32 Count)
|
void *kmemset(void *Destination, u8 Value, u64 Count)
|
||||||
{
|
{
|
||||||
u8 *us = (u8 *)Destination;
|
u8 *us = (u8 *)Destination;
|
||||||
while (Count-- != 0)
|
while (Count-- != 0)
|
||||||
|
@ -21,7 +21,7 @@ void *kmemset(void *Destination, u8 Value, u32 Count)
|
||||||
return Destination;
|
return Destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *kmemsetw(void *Destination, u16 Value, u32 Count)
|
void *kmemsetw(void *Destination, u16 Value, u64 Count)
|
||||||
{
|
{
|
||||||
u16 *us = (u16 *)Destination;
|
u16 *us = (u16 *)Destination;
|
||||||
while (Count-- != 0)
|
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