Compare commits
No commits in common. "be3efb0b9213f82a0b0d4ddf67993f42878e2109" and "31aa157201822d2ecd439fd2b5f6350b58fdff14" have entirely different histories.
be3efb0b92
...
31aa157201
|
@ -4,7 +4,6 @@
|
||||||
#include <kernel/LockGuard.h>
|
#include <kernel/LockGuard.h>
|
||||||
#include <kernel/Memory/kmalloc.h>
|
#include <kernel/Memory/kmalloc.h>
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
#include <kernel/multiboot2.h>
|
|
||||||
|
|
||||||
extern uint8_t g_kernel_start[];
|
extern uint8_t g_kernel_start[];
|
||||||
extern uint8_t g_kernel_end[];
|
extern uint8_t g_kernel_end[];
|
||||||
|
@ -139,16 +138,6 @@ namespace Kernel
|
||||||
// Map (0 -> phys_kernel_end) to (KERNEL_OFFSET -> virt_kernel_end)
|
// Map (0 -> phys_kernel_end) to (KERNEL_OFFSET -> virt_kernel_end)
|
||||||
map_range_at(0, KERNEL_OFFSET, (uintptr_t)g_kernel_end - KERNEL_OFFSET, Flags::ReadWrite | Flags::Present);
|
map_range_at(0, KERNEL_OFFSET, (uintptr_t)g_kernel_end - KERNEL_OFFSET, Flags::ReadWrite | Flags::Present);
|
||||||
|
|
||||||
// Map multiboot info
|
|
||||||
vaddr_t multiboot_data_start = (vaddr_t)g_multiboot2_info & PAGE_ADDR_MASK;
|
|
||||||
vaddr_t multiboot_data_end = (vaddr_t)g_multiboot2_info + g_multiboot2_info->total_size;
|
|
||||||
map_range_at(
|
|
||||||
V2P(multiboot_data_start),
|
|
||||||
multiboot_data_start,
|
|
||||||
multiboot_data_end - multiboot_data_start,
|
|
||||||
Flags::ReadWrite | Flags::Present
|
|
||||||
);
|
|
||||||
|
|
||||||
// Map executable kernel memory as executable
|
// Map executable kernel memory as executable
|
||||||
map_range_at(
|
map_range_at(
|
||||||
V2P(g_kernel_execute_start),
|
V2P(g_kernel_execute_start),
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
# Declare constants for the multiboot header
|
||||||
|
.set ALIGN, 1<<0 # align loaded modules on page boundaries
|
||||||
|
.set MEMINFO, 1<<1 # provide memory map
|
||||||
|
.set VIDEOINFO, 1<<2 # provide video info
|
||||||
|
.set MB_FLAGS, ALIGN | MEMINFO | VIDEOINFO # this is the Multiboot 'flag' field
|
||||||
|
.set MB_MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
|
||||||
|
.set MB_CHECKSUM, -(MB_MAGIC + MB_FLAGS) #checksum of above, to prove we are multiboot
|
||||||
|
|
||||||
.set PG_PRESENT, 1<<0
|
.set PG_PRESENT, 1<<0
|
||||||
.set PG_READ_WRITE, 1<<1
|
.set PG_READ_WRITE, 1<<1
|
||||||
.set PG_PAGE_SIZE, 1<<7
|
.set PG_PAGE_SIZE, 1<<7
|
||||||
|
@ -7,37 +15,19 @@
|
||||||
|
|
||||||
.code32
|
.code32
|
||||||
|
|
||||||
# multiboot2 header
|
# Multiboot header
|
||||||
.section .multiboot, "aw"
|
.section .multiboot, "aw"
|
||||||
multiboot2_start:
|
.align 4
|
||||||
.align 8
|
.long MB_MAGIC
|
||||||
.long 0xE85250D6
|
.long MB_FLAGS
|
||||||
|
.long MB_CHECKSUM
|
||||||
|
.skip 20
|
||||||
|
|
||||||
.long 0
|
.long 0
|
||||||
.long multiboot2_end - multiboot2_start
|
.long 800
|
||||||
.long -(0xE85250D6 + (multiboot2_end - multiboot2_start))
|
.long 600
|
||||||
|
|
||||||
# framebuffer tag
|
|
||||||
.align 8
|
|
||||||
.short 5
|
|
||||||
.short 0
|
|
||||||
.long 20
|
|
||||||
.long 1920
|
|
||||||
.long 1080
|
|
||||||
.long 32
|
.long 32
|
||||||
|
|
||||||
# legacy start
|
|
||||||
.align 8
|
|
||||||
.short 3
|
|
||||||
.short 0
|
|
||||||
.long 12
|
|
||||||
.long V2P(_start)
|
|
||||||
|
|
||||||
.align 8
|
|
||||||
.short 0
|
|
||||||
.short 0
|
|
||||||
.long 8
|
|
||||||
multiboot2_end:
|
|
||||||
|
|
||||||
.section .bss, "aw", @nobits
|
.section .bss, "aw", @nobits
|
||||||
# Create stack
|
# Create stack
|
||||||
.global g_boot_stack_bottom
|
.global g_boot_stack_bottom
|
||||||
|
@ -50,11 +40,11 @@ multiboot2_end:
|
||||||
g_kernel_cmdline:
|
g_kernel_cmdline:
|
||||||
.skip 4096
|
.skip 4096
|
||||||
|
|
||||||
.global g_multiboot2_info
|
.global g_multiboot_info
|
||||||
g_multiboot2_info:
|
g_multiboot_info:
|
||||||
.skip 8
|
.skip 8
|
||||||
.global g_multiboot2_magic
|
.global g_multiboot_magic
|
||||||
g_multiboot2_magic:
|
g_multiboot_magic:
|
||||||
.skip 8
|
.skip 8
|
||||||
|
|
||||||
.section .data
|
.section .data
|
||||||
|
@ -129,6 +119,19 @@ check_requirements:
|
||||||
.exit:
|
.exit:
|
||||||
jmp system_halt
|
jmp system_halt
|
||||||
|
|
||||||
|
copy_kernel_commandline:
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
|
movl V2P(g_multiboot_info), %esi
|
||||||
|
addl $16, %esi
|
||||||
|
movl (%esi), %esi
|
||||||
|
movl $1024, %ecx
|
||||||
|
movl $V2P(g_kernel_cmdline), %edi
|
||||||
|
rep movsl
|
||||||
|
popl %edi
|
||||||
|
popl %esi
|
||||||
|
ret
|
||||||
|
|
||||||
enable_sse:
|
enable_sse:
|
||||||
movl %cr0, %eax
|
movl %cr0, %eax
|
||||||
andw $0xFFFB, %ax
|
andw $0xFFFB, %ax
|
||||||
|
@ -167,9 +170,10 @@ initialize_paging:
|
||||||
_start:
|
_start:
|
||||||
# Initialize stack and multiboot info
|
# Initialize stack and multiboot info
|
||||||
movl $V2P(g_boot_stack_top), %esp
|
movl $V2P(g_boot_stack_top), %esp
|
||||||
movl %eax, V2P(g_multiboot2_magic)
|
movl %eax, V2P(g_multiboot_magic)
|
||||||
movl %ebx, V2P(g_multiboot2_info)
|
movl %ebx, V2P(g_multiboot_info)
|
||||||
|
|
||||||
|
call copy_kernel_commandline
|
||||||
call check_requirements
|
call check_requirements
|
||||||
call enable_sse
|
call enable_sse
|
||||||
|
|
||||||
|
@ -197,7 +201,7 @@ long_mode:
|
||||||
jmp *%rcx
|
jmp *%rcx
|
||||||
|
|
||||||
higher_half:
|
higher_half:
|
||||||
addq $KERNEL_OFFSET, g_multiboot2_info
|
addq $KERNEL_OFFSET, g_multiboot_info
|
||||||
|
|
||||||
# call global constuctors
|
# call global constuctors
|
||||||
call _init
|
call _init
|
||||||
|
|
|
@ -29,9 +29,8 @@ namespace Kernel::PCI
|
||||||
~BarRegion();
|
~BarRegion();
|
||||||
|
|
||||||
BarType type() const { return m_type; }
|
BarType type() const { return m_type; }
|
||||||
vaddr_t iobase() const { ASSERT(m_type == BarType::IO); return m_paddr; }
|
vaddr_t vaddr() const { return m_vaddr; }
|
||||||
vaddr_t vaddr() const { ASSERT(m_type == BarType::MEM); return m_vaddr; }
|
paddr_t paddr() const { return m_paddr; }
|
||||||
paddr_t paddr() const { ASSERT(m_type == BarType::MEM); return m_paddr; }
|
|
||||||
size_t size() const { return m_size; }
|
size_t size() const { return m_size; }
|
||||||
|
|
||||||
void write8(off_t, uint8_t);
|
void write8(off_t, uint8_t);
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define ATA_PROGIF_PRIMARY_NATIVE (1 << 0)
|
#define ATA_PROGIF_PRIMARY_NATIVE (1 << 0)
|
||||||
#define ATA_PROGIF_CAN_MODIFY_PRIMARY_NATIVE (1 << 1)
|
|
||||||
#define ATA_PROGIF_SECONDARY_NATIVE (1 << 2)
|
#define ATA_PROGIF_SECONDARY_NATIVE (1 << 2)
|
||||||
#define ATA_PROGIF_CAN_MODIFY_SECONDARY_NATIVE (1 << 3)
|
|
||||||
|
|
||||||
#define ATA_PORT_DATA 0x00
|
#define ATA_PORT_DATA 0x00
|
||||||
#define ATA_PORT_ERROR 0x00
|
#define ATA_PORT_ERROR 0x00
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace Kernel
|
||||||
uint64_t sector_count() const { return m_lba_count; }
|
uint64_t sector_count() const { return m_lba_count; }
|
||||||
|
|
||||||
BAN::StringView model() const { return m_model; }
|
BAN::StringView model() const { return m_model; }
|
||||||
BAN::StringView name() const { return m_name; }
|
BAN::StringView name() const;
|
||||||
|
|
||||||
virtual dev_t rdev() const override { return m_rdev; }
|
virtual dev_t rdev() const override { return m_rdev; }
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ namespace Kernel
|
||||||
uint32_t m_sector_words;
|
uint32_t m_sector_words;
|
||||||
uint64_t m_lba_count;
|
uint64_t m_lba_count;
|
||||||
char m_model[41];
|
char m_model[41];
|
||||||
char m_name[4] {};
|
|
||||||
|
|
||||||
const dev_t m_rdev;
|
const dev_t m_rdev;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MULTIBOOT_FLAGS_FRAMEBUFFER (1 << 12)
|
||||||
|
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS 1
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_TEXT 2
|
||||||
|
|
||||||
|
struct framebuffer_info_t
|
||||||
|
{
|
||||||
|
uint64_t addr;
|
||||||
|
uint32_t pitch;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint8_t bpp;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t color_info[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct multiboot_memory_map_t
|
||||||
|
{
|
||||||
|
uint32_t size;
|
||||||
|
uint64_t base_addr;
|
||||||
|
uint64_t length;
|
||||||
|
uint32_t type;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
// https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format
|
||||||
|
struct multiboot_info_t
|
||||||
|
{
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t mem_lower;
|
||||||
|
uint32_t mem_upper;
|
||||||
|
uint32_t boot_device;
|
||||||
|
uint32_t cmdline;
|
||||||
|
uint32_t mods_count;
|
||||||
|
uint32_t mods_addr;
|
||||||
|
uint32_t syms[4];
|
||||||
|
uint32_t mmap_length;
|
||||||
|
uint32_t mmap_addr;
|
||||||
|
uint32_t drives_length;
|
||||||
|
uint32_t drives_addr;
|
||||||
|
uint32_t config_table;
|
||||||
|
uint32_t boot_loader_name;
|
||||||
|
uint32_t apm_table;
|
||||||
|
uint32_t vbe_control_info;
|
||||||
|
uint32_t vbe_mode_info;
|
||||||
|
uint16_t vbe_mode;
|
||||||
|
uint16_t vbe_interface_seg;
|
||||||
|
uint16_t vbe_interface_off;
|
||||||
|
uint16_t vbe_interface_len;
|
||||||
|
framebuffer_info_t framebuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" multiboot_info_t* g_multiboot_info;
|
||||||
|
extern "C" uint32_t g_multiboot_magic;
|
|
@ -1,75 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
// https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Boot-information
|
|
||||||
|
|
||||||
#define MULTIBOOT2_TAG_END 0
|
|
||||||
#define MULTIBOOT2_TAG_CMDLINE 1
|
|
||||||
#define MULTIBOOT2_TAG_MMAP 6
|
|
||||||
#define MULTIBOOT2_TAG_FRAMEBUFFER 8
|
|
||||||
#define MULTIBOOT2_TAG_OLD_RSDP 14
|
|
||||||
#define MULTIBOOT2_TAG_NEW_RSDP 15
|
|
||||||
|
|
||||||
#define MULTIBOOT2_FRAMEBUFFER_TYPE_RGB 1
|
|
||||||
|
|
||||||
struct multiboot2_tag_t
|
|
||||||
{
|
|
||||||
uint32_t type;
|
|
||||||
uint32_t size;
|
|
||||||
multiboot2_tag_t* next() { return (multiboot2_tag_t*)((uintptr_t)this + ((size + 7) & ~7)); }
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct multiboot2_cmdline_tag_t : public multiboot2_tag_t
|
|
||||||
{
|
|
||||||
char cmdline[];
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct multiboot2_mmap_entry_t
|
|
||||||
{
|
|
||||||
uint64_t base_addr;
|
|
||||||
uint64_t length;
|
|
||||||
uint32_t type;
|
|
||||||
uint32_t reserved;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct multiboot2_mmap_tag_t : public multiboot2_tag_t
|
|
||||||
{
|
|
||||||
uint32_t entry_size;
|
|
||||||
uint32_t entry_version;
|
|
||||||
multiboot2_mmap_entry_t entries[];
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct multiboot2_framebuffer_tag_t : public multiboot2_tag_t
|
|
||||||
{
|
|
||||||
uint64_t framebuffer_addr;
|
|
||||||
uint32_t framebuffer_pitch;
|
|
||||||
uint32_t framebuffer_width;
|
|
||||||
uint32_t framebuffer_height;
|
|
||||||
uint8_t framebuffer_bpp;
|
|
||||||
uint8_t framebuffer_type;
|
|
||||||
uint8_t reserved;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct multiboot2_rsdp_tag_t : public multiboot2_tag_t
|
|
||||||
{
|
|
||||||
uint8_t data[];
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct multiboot2_info_t
|
|
||||||
{
|
|
||||||
uint32_t total_size;
|
|
||||||
uint32_t reserved;
|
|
||||||
multiboot2_tag_t tags[];
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
extern "C" multiboot2_info_t* g_multiboot2_info;
|
|
||||||
extern "C" uint32_t g_multiboot2_magic;
|
|
||||||
|
|
||||||
inline multiboot2_tag_t* multiboot2_find_tag(uint32_t type)
|
|
||||||
{
|
|
||||||
for (auto* tag = g_multiboot2_info->tags; tag->type != MULTIBOOT2_TAG_END; tag = tag->next())
|
|
||||||
if (tag->type == type)
|
|
||||||
return tag;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include <BAN/StringView.h>
|
#include <BAN/StringView.h>
|
||||||
#include <kernel/ACPI.h>
|
#include <kernel/ACPI.h>
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
#include <kernel/multiboot2.h>
|
|
||||||
|
|
||||||
#include <lai/core.h>
|
#include <lai/core.h>
|
||||||
|
|
||||||
|
@ -85,12 +84,6 @@ namespace Kernel
|
||||||
|
|
||||||
static const RSDP* locate_rsdp()
|
static const RSDP* locate_rsdp()
|
||||||
{
|
{
|
||||||
// Check the multiboot headers
|
|
||||||
if (auto* rsdp_new = (multiboot2_rsdp_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_NEW_RSDP))
|
|
||||||
return (const RSDP*)rsdp_new->data;
|
|
||||||
if (auto* rsdp_old = (multiboot2_rsdp_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_OLD_RSDP))
|
|
||||||
return (const RSDP*)rsdp_old->data;
|
|
||||||
|
|
||||||
// Look in main BIOS area below 1 MB
|
// Look in main BIOS area below 1 MB
|
||||||
for (uintptr_t addr = P2V(0x000E0000); addr < P2V(0x000FFFFF); addr += 16)
|
for (uintptr_t addr = P2V(0x000E0000); addr < P2V(0x000FFFFF); addr += 16)
|
||||||
if (is_rsdp(addr))
|
if (is_rsdp(addr))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <kernel/LockGuard.h>
|
#include <kernel/LockGuard.h>
|
||||||
#include <kernel/Memory/Heap.h>
|
#include <kernel/Memory/Heap.h>
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
#include <kernel/multiboot2.h>
|
#include <kernel/multiboot.h>
|
||||||
|
|
||||||
extern uint8_t g_kernel_end[];
|
extern uint8_t g_kernel_end[];
|
||||||
|
|
||||||
|
@ -26,23 +26,21 @@ namespace Kernel
|
||||||
|
|
||||||
void Heap::initialize_impl()
|
void Heap::initialize_impl()
|
||||||
{
|
{
|
||||||
auto* mmap_tag = (multiboot2_mmap_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_MMAP);
|
if (!(g_multiboot_info->flags & (1 << 6)))
|
||||||
if (mmap_tag == nullptr)
|
|
||||||
Kernel::panic("Bootloader did not provide a memory map");
|
Kernel::panic("Bootloader did not provide a memory map");
|
||||||
|
|
||||||
for (size_t offset = sizeof(*mmap_tag); offset < mmap_tag->size; offset += mmap_tag->entry_size)
|
for (size_t i = 0; i < g_multiboot_info->mmap_length;)
|
||||||
{
|
{
|
||||||
auto* mmap_entry = (multiboot2_mmap_entry_t*)((uintptr_t)mmap_tag + offset);
|
multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)P2V(g_multiboot_info->mmap_addr + i);
|
||||||
|
if (mmmt->type == 1)
|
||||||
if (mmap_entry->type == 1)
|
|
||||||
{
|
{
|
||||||
paddr_t start = mmap_entry->base_addr;
|
paddr_t start = mmmt->base_addr;
|
||||||
if (start < V2P(g_kernel_end))
|
if (start < V2P(g_kernel_end))
|
||||||
start = V2P(g_kernel_end);
|
start = V2P(g_kernel_end);
|
||||||
if (auto rem = start % PAGE_SIZE)
|
if (auto rem = start % PAGE_SIZE)
|
||||||
start += PAGE_SIZE - rem;
|
start += PAGE_SIZE - rem;
|
||||||
|
|
||||||
paddr_t end = mmap_entry->base_addr + mmap_entry->length;
|
paddr_t end = mmmt->base_addr + mmmt->length;
|
||||||
if (auto rem = end % PAGE_SIZE)
|
if (auto rem = end % PAGE_SIZE)
|
||||||
end -= rem;
|
end -= rem;
|
||||||
|
|
||||||
|
@ -50,6 +48,7 @@ namespace Kernel
|
||||||
if (end > start + PAGE_SIZE)
|
if (end > start + PAGE_SIZE)
|
||||||
MUST(m_physical_ranges.emplace_back(start, end - start));
|
MUST(m_physical_ranges.emplace_back(start, end - start));
|
||||||
}
|
}
|
||||||
|
i += mmmt->size + sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace Kernel::PCI
|
||||||
uint32_t temp = read_config_dword(bus, dev, func, offset & ~3);
|
uint32_t temp = read_config_dword(bus, dev, func, offset & ~3);
|
||||||
temp &= ~(0xFF << byte);
|
temp &= ~(0xFF << byte);
|
||||||
temp |= (uint32_t)value << byte;
|
temp |= (uint32_t)value << byte;
|
||||||
write_config_dword(bus, dev, func, offset & ~3, temp);
|
write_config_dword(bus, dev, func, offset, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t get_vendor_id(uint8_t bus, uint8_t dev, uint8_t func)
|
static uint16_t get_vendor_id(uint8_t bus, uint8_t dev, uint8_t func)
|
||||||
|
@ -252,13 +252,8 @@ namespace Kernel::PCI
|
||||||
device.func()
|
device.func()
|
||||||
);
|
);
|
||||||
dprintln(" type: {}", region->type() == BarType::IO ? "IO" : "MEM");
|
dprintln(" type: {}", region->type() == BarType::IO ? "IO" : "MEM");
|
||||||
if (region->type() == BarType::IO)
|
|
||||||
dprintln(" iobase {8H}", region->iobase());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dprintln(" paddr {}", (void*)region->paddr());
|
dprintln(" paddr {}", (void*)region->paddr());
|
||||||
dprintln(" vaddr {}", (void*)region->vaddr());
|
dprintln(" vaddr {}", (void*)region->vaddr());
|
||||||
}
|
|
||||||
dprintln(" size {}", region->size());
|
dprintln(" size {}", region->size());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -295,42 +290,42 @@ namespace Kernel::PCI
|
||||||
void BarRegion::write8(off_t reg, uint8_t val)
|
void BarRegion::write8(off_t reg, uint8_t val)
|
||||||
{
|
{
|
||||||
if (m_type == BarType::IO)
|
if (m_type == BarType::IO)
|
||||||
return IO::outb(m_paddr + reg, val);
|
return IO::outb(m_vaddr + reg, val);
|
||||||
MMIO::write8(m_vaddr + reg, val);
|
MMIO::write8(m_vaddr + reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BarRegion::write16(off_t reg, uint16_t val)
|
void BarRegion::write16(off_t reg, uint16_t val)
|
||||||
{
|
{
|
||||||
if (m_type == BarType::IO)
|
if (m_type == BarType::IO)
|
||||||
return IO::outw(m_paddr + reg, val);
|
return IO::outw(m_vaddr + reg, val);
|
||||||
MMIO::write16(m_vaddr + reg, val);
|
MMIO::write16(m_vaddr + reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BarRegion::write32(off_t reg, uint32_t val)
|
void BarRegion::write32(off_t reg, uint32_t val)
|
||||||
{
|
{
|
||||||
if (m_type == BarType::IO)
|
if (m_type == BarType::IO)
|
||||||
return IO::outl(m_paddr + reg, val);
|
return IO::outl(m_vaddr + reg, val);
|
||||||
MMIO::write32(m_vaddr + reg, val);
|
MMIO::write32(m_vaddr + reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t BarRegion::read8(off_t reg)
|
uint8_t BarRegion::read8(off_t reg)
|
||||||
{
|
{
|
||||||
if (m_type == BarType::IO)
|
if (m_type == BarType::IO)
|
||||||
return IO::inb(m_paddr + reg);
|
return IO::inb(m_vaddr + reg);
|
||||||
return MMIO::read8(m_vaddr + reg);
|
return MMIO::read8(m_vaddr + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t BarRegion::read16(off_t reg)
|
uint16_t BarRegion::read16(off_t reg)
|
||||||
{
|
{
|
||||||
if (m_type == BarType::IO)
|
if (m_type == BarType::IO)
|
||||||
return IO::inw(m_paddr + reg);
|
return IO::inw(m_vaddr + reg);
|
||||||
return MMIO::read16(m_vaddr + reg);
|
return MMIO::read16(m_vaddr + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t BarRegion::read32(off_t reg)
|
uint32_t BarRegion::read32(off_t reg)
|
||||||
{
|
{
|
||||||
if (m_type == BarType::IO)
|
if (m_type == BarType::IO)
|
||||||
return IO::inl(m_paddr + reg);
|
return IO::inl(m_vaddr + reg);
|
||||||
return MMIO::read32(m_vaddr + reg);
|
return MMIO::read32(m_vaddr + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,14 +73,6 @@ namespace Kernel
|
||||||
select_delay();
|
select_delay();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool identify_all_ones(BAN::Span<const uint16_t> identify_data)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < 256; i++)
|
|
||||||
if (identify_data[i] != 0xFFFF)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<ATABus::DeviceType> ATABus::identify(bool secondary, BAN::Span<uint16_t> buffer)
|
BAN::ErrorOr<ATABus::DeviceType> ATABus::identify(bool secondary, BAN::Span<uint16_t> buffer)
|
||||||
{
|
{
|
||||||
select_device(secondary);
|
select_device(secondary);
|
||||||
|
@ -125,9 +117,6 @@ namespace Kernel
|
||||||
ASSERT(buffer.size() >= 256);
|
ASSERT(buffer.size() >= 256);
|
||||||
read_buffer(ATA_PORT_DATA, buffer.data(), 256);
|
read_buffer(ATA_PORT_DATA, buffer.data(), 256);
|
||||||
|
|
||||||
if (identify_all_ones(buffer))
|
|
||||||
return BAN::Error::from_errno(ENODEV);
|
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,20 +41,6 @@ namespace Kernel
|
||||||
|
|
||||||
uint8_t prog_if = m_pci_device.read_byte(0x09);
|
uint8_t prog_if = m_pci_device.read_byte(0x09);
|
||||||
|
|
||||||
if ((prog_if & ATA_PROGIF_CAN_MODIFY_PRIMARY_NATIVE) && (prog_if & ATA_PROGIF_PRIMARY_NATIVE))
|
|
||||||
{
|
|
||||||
prog_if &= ~ATA_PROGIF_PRIMARY_NATIVE;
|
|
||||||
m_pci_device.write_byte(0x09, prog_if);
|
|
||||||
dprintln("enabling compatibility mode for bus 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((prog_if & ATA_PROGIF_CAN_MODIFY_SECONDARY_NATIVE) && (prog_if & ATA_PROGIF_SECONDARY_NATIVE))
|
|
||||||
{
|
|
||||||
prog_if &= ~ATA_PROGIF_SECONDARY_NATIVE;
|
|
||||||
m_pci_device.write_byte(0x09, prog_if);
|
|
||||||
dprintln("enabling compatibility mode for bus 2");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(prog_if & ATA_PROGIF_PRIMARY_NATIVE))
|
if (!(prog_if & ATA_PROGIF_PRIMARY_NATIVE))
|
||||||
{
|
{
|
||||||
auto bus_or_error = ATABus::create(0x1F0, 0x3F6, 14);
|
auto bus_or_error = ATABus::create(0x1F0, 0x3F6, 14);
|
||||||
|
@ -68,6 +54,7 @@ namespace Kernel
|
||||||
dprintln("unsupported IDE ATABus in native mode");
|
dprintln("unsupported IDE ATABus in native mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BUS 2
|
||||||
if (!(prog_if & ATA_PROGIF_SECONDARY_NATIVE))
|
if (!(prog_if & ATA_PROGIF_SECONDARY_NATIVE))
|
||||||
{
|
{
|
||||||
auto bus_or_error = ATABus::create(0x170, 0x376, 15);
|
auto bus_or_error = ATABus::create(0x170, 0x376, 15);
|
||||||
|
|
|
@ -23,10 +23,7 @@ namespace Kernel
|
||||||
|
|
||||||
detail::ATABaseDevice::ATABaseDevice()
|
detail::ATABaseDevice::ATABaseDevice()
|
||||||
: m_rdev(makedev(get_ata_dev_major(), get_ata_dev_minor()))
|
: m_rdev(makedev(get_ata_dev_major(), get_ata_dev_minor()))
|
||||||
{
|
{ }
|
||||||
strcpy(m_name, "sda");
|
|
||||||
m_name[2] += minor(m_rdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> detail::ATABaseDevice::initialize(BAN::Span<const uint16_t> identify_data)
|
BAN::ErrorOr<void> detail::ATABaseDevice::initialize(BAN::Span<const uint16_t> identify_data)
|
||||||
{
|
{
|
||||||
|
@ -71,7 +68,7 @@ namespace Kernel
|
||||||
while (model_len > 0 && m_model[model_len - 1] == ' ')
|
while (model_len > 0 && m_model[model_len - 1] == ' ')
|
||||||
model_len--;
|
model_len--;
|
||||||
|
|
||||||
dprintln("Initialized disk '{}' {} MiB", BAN::StringView(m_model, model_len), total_size() / 1024 / 1024);
|
dprintln("Initialized disk '{}' {} MB", BAN::StringView(m_model, model_len), total_size() / 1024 / 1024);
|
||||||
|
|
||||||
add_disk_cache();
|
add_disk_cache();
|
||||||
|
|
||||||
|
@ -102,6 +99,13 @@ namespace Kernel
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::StringView detail::ATABaseDevice::name() const
|
||||||
|
{
|
||||||
|
static char device_name[] = "sda";
|
||||||
|
device_name[2] += minor(m_rdev);
|
||||||
|
return device_name;
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::RefPtr<ATADevice>> ATADevice::create(BAN::RefPtr<ATABus> bus, ATABus::DeviceType type, bool is_secondary, BAN::Span<const uint16_t> identify_data)
|
BAN::ErrorOr<BAN::RefPtr<ATADevice>> ATADevice::create(BAN::RefPtr<ATABus> bus, ATABus::DeviceType type, bool is_secondary, BAN::Span<const uint16_t> identify_data)
|
||||||
{
|
{
|
||||||
auto* device_ptr = new ATADevice(bus, type, is_secondary);
|
auto* device_ptr = new ATADevice(bus, type, is_secondary);
|
||||||
|
|
|
@ -81,14 +81,7 @@ namespace Kernel
|
||||||
Process::create_kernel(
|
Process::create_kernel(
|
||||||
[](void*)
|
[](void*)
|
||||||
{
|
{
|
||||||
auto file_or_error = VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/input0"sv, O_RDONLY);
|
auto inode = MUST(VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/input0"sv, O_RDONLY)).inode;
|
||||||
if (file_or_error.is_error())
|
|
||||||
{
|
|
||||||
dprintln("no input device found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto inode = file_or_error.value().inode;
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
while (!TTY::current()->m_tty_ctrl.receive_input)
|
while (!TTY::current()->m_tty_ctrl.receive_input)
|
||||||
|
|
|
@ -1,54 +1,55 @@
|
||||||
#include <BAN/Errors.h>
|
#include <BAN/Errors.h>
|
||||||
#include <kernel/Debug.h>
|
#include <kernel/Debug.h>
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
#include <kernel/multiboot2.h>
|
#include <kernel/multiboot.h>
|
||||||
#include <kernel/Terminal/VesaTerminalDriver.h>
|
#include <kernel/Terminal/VesaTerminalDriver.h>
|
||||||
|
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
VesaTerminalDriver* VesaTerminalDriver::create()
|
VesaTerminalDriver* VesaTerminalDriver::create()
|
||||||
{
|
{
|
||||||
auto* framebuffer_tag = (multiboot2_framebuffer_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_FRAMEBUFFER);
|
if (!(g_multiboot_info->flags & MULTIBOOT_FLAGS_FRAMEBUFFER))
|
||||||
if (framebuffer_tag == nullptr)
|
|
||||||
{
|
{
|
||||||
dprintln("Bootloader did not provide framebuffer");
|
dprintln("Bootloader did not provide framebuffer");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (framebuffer_tag->framebuffer_type != MULTIBOOT2_FRAMEBUFFER_TYPE_RGB)
|
auto& framebuffer = g_multiboot_info->framebuffer;
|
||||||
|
|
||||||
|
if (framebuffer.type == MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS)
|
||||||
{
|
{
|
||||||
dprintln("unsupported framebuffer type {}", framebuffer_tag->framebuffer_type);
|
if (framebuffer.bpp != 24 && framebuffer.bpp != 32)
|
||||||
|
{
|
||||||
|
dprintln("Unsupported bpp {}", framebuffer.bpp);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
dprintln("Graphics Mode {}x{} ({} bpp)", framebuffer.width, framebuffer.height, framebuffer.bpp);
|
||||||
|
}
|
||||||
|
else if (framebuffer.type == MULTIBOOT_FRAMEBUFFER_TYPE_TEXT)
|
||||||
|
{
|
||||||
|
dprintln("Text Mode is currently not supported");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dprintln("Unknown framebuffer type {}", framebuffer.type);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (framebuffer_tag->framebuffer_bpp != 24 && framebuffer_tag->framebuffer_bpp != 32)
|
uint64_t first_page = framebuffer.addr / PAGE_SIZE;
|
||||||
{
|
uint64_t last_page = BAN::Math::div_round_up<uint64_t>(framebuffer.addr + framebuffer.pitch * framebuffer.height, PAGE_SIZE);
|
||||||
dprintln("Unsupported bpp {}", framebuffer_tag->framebuffer_bpp);
|
uint64_t needed_pages = last_page - first_page + 1;
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintln("Graphics Mode {}x{} ({} bpp)",
|
|
||||||
(uint32_t)framebuffer_tag->framebuffer_width,
|
|
||||||
(uint32_t)framebuffer_tag->framebuffer_height,
|
|
||||||
(uint8_t)framebuffer_tag->framebuffer_bpp
|
|
||||||
);
|
|
||||||
|
|
||||||
paddr_t paddr = framebuffer_tag->framebuffer_addr & PAGE_ADDR_MASK;
|
|
||||||
size_t needed_pages = range_page_count(
|
|
||||||
framebuffer_tag->framebuffer_addr,
|
|
||||||
framebuffer_tag->framebuffer_pitch * framebuffer_tag->framebuffer_height
|
|
||||||
);
|
|
||||||
|
|
||||||
vaddr_t vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET);
|
vaddr_t vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET);
|
||||||
ASSERT(vaddr);
|
ASSERT(vaddr);
|
||||||
|
|
||||||
PageTable::kernel().map_range_at(paddr, vaddr, needed_pages * PAGE_SIZE, PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present);
|
PageTable::kernel().map_range_at(framebuffer.addr, vaddr, needed_pages * PAGE_SIZE, PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present);
|
||||||
|
|
||||||
auto* driver = new VesaTerminalDriver(
|
auto* driver = new VesaTerminalDriver(
|
||||||
framebuffer_tag->framebuffer_width,
|
framebuffer.width,
|
||||||
framebuffer_tag->framebuffer_height,
|
framebuffer.height,
|
||||||
framebuffer_tag->framebuffer_pitch,
|
framebuffer.pitch,
|
||||||
framebuffer_tag->framebuffer_bpp,
|
framebuffer.bpp,
|
||||||
vaddr
|
vaddr
|
||||||
);
|
);
|
||||||
driver->set_cursor_position(0, 0);
|
driver->set_cursor_position(0, 0);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <kernel/Memory/Heap.h>
|
#include <kernel/Memory/Heap.h>
|
||||||
#include <kernel/Memory/kmalloc.h>
|
#include <kernel/Memory/kmalloc.h>
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
#include <kernel/multiboot2.h>
|
#include <kernel/multiboot.h>
|
||||||
#include <kernel/PCI.h>
|
#include <kernel/PCI.h>
|
||||||
#include <kernel/PIC.h>
|
#include <kernel/PIC.h>
|
||||||
#include <kernel/Process.h>
|
#include <kernel/Process.h>
|
||||||
|
@ -23,6 +23,8 @@
|
||||||
#include <kernel/Terminal/VesaTerminalDriver.h>
|
#include <kernel/Terminal/VesaTerminalDriver.h>
|
||||||
#include <kernel/Timer/Timer.h>
|
#include <kernel/Timer/Timer.h>
|
||||||
|
|
||||||
|
extern "C" const char g_kernel_cmdline[];
|
||||||
|
|
||||||
struct ParsedCommandLine
|
struct ParsedCommandLine
|
||||||
{
|
{
|
||||||
bool force_pic = false;
|
bool force_pic = false;
|
||||||
|
@ -33,12 +35,11 @@ struct ParsedCommandLine
|
||||||
|
|
||||||
static bool should_disable_serial()
|
static bool should_disable_serial()
|
||||||
{
|
{
|
||||||
auto* cmdline_tag = (multiboot2_cmdline_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_CMDLINE);
|
if (!(g_multiboot_info->flags & 0x02))
|
||||||
if (cmdline_tag == nullptr)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char* start = cmdline_tag->cmdline;
|
const char* start = g_kernel_cmdline;
|
||||||
const char* current = start;
|
const char* current = g_kernel_cmdline;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!*current || *current == ' ' || *current == '\t')
|
if (!*current || *current == ' ' || *current == '\t')
|
||||||
|
@ -59,11 +60,10 @@ static ParsedCommandLine cmdline;
|
||||||
|
|
||||||
static void parse_command_line()
|
static void parse_command_line()
|
||||||
{
|
{
|
||||||
auto* cmdline_tag = (multiboot2_cmdline_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_CMDLINE);
|
if (!(g_multiboot_info->flags & 0x02))
|
||||||
if (cmdline_tag == nullptr)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BAN::StringView full_command_line(cmdline_tag->cmdline);
|
BAN::StringView full_command_line(g_kernel_cmdline);
|
||||||
auto arguments = MUST(full_command_line.split(' '));
|
auto arguments = MUST(full_command_line.split(' '));
|
||||||
|
|
||||||
for (auto argument : arguments)
|
for (auto argument : arguments)
|
||||||
|
@ -98,7 +98,7 @@ extern "C" void kernel_main()
|
||||||
dprintln("Serial output initialized");
|
dprintln("Serial output initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_multiboot2_magic != 0x36d76289)
|
if (g_multiboot_magic != 0x2BADB002)
|
||||||
{
|
{
|
||||||
dprintln("Invalid multiboot magic number");
|
dprintln("Invalid multiboot magic number");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
menuentry "banan-os" {
|
menuentry "banan-os" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2
|
multiboot /boot/banan-os.kernel root=/dev/sda2
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (no serial)" {
|
menuentry "banan-os (no serial)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 noserial
|
multiboot /boot/banan-os.kernel root=/dev/sda2 noserial
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (only serial)" {
|
menuentry "banan-os (only serial)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 console=ttyS0
|
multiboot /boot/banan-os.kernel root=/dev/sda2 console=ttyS0
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (no apic)" {
|
menuentry "banan-os (no apic)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 noapic
|
multiboot /boot/banan-os.kernel root=/dev/sda2 noapic
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (no apic, no serial)" {
|
menuentry "banan-os (no apic, no serial)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 noapic noserial
|
multiboot /boot/banan-os.kernel root=/dev/sda2 noapic noserial
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (no apic, only serial)" {
|
menuentry "banan-os (no apic, only serial)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 noapic console=ttyS0
|
multiboot /boot/banan-os.kernel root=/dev/sda2 noapic console=ttyS0
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,25 @@ insmod part_gpt
|
||||||
set root=(hd0,gpt2)
|
set root=(hd0,gpt2)
|
||||||
|
|
||||||
menuentry "banan-os" {
|
menuentry "banan-os" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2
|
multiboot /boot/banan-os.kernel root=/dev/sda2
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (no serial)" {
|
menuentry "banan-os (no serial)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 noserial
|
multiboot /boot/banan-os.kernel root=/dev/sda2 noserial
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (only serial)" {
|
menuentry "banan-os (only serial)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 console=ttyS0
|
multiboot /boot/banan-os.kernel root=/dev/sda2 console=ttyS0
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (no apic)" {
|
menuentry "banan-os (no apic)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 noapic
|
multiboot /boot/banan-os.kernel root=/dev/sda2 noapic
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (no apic, no serial)" {
|
menuentry "banan-os (no apic, no serial)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 noapic noserial
|
multiboot /boot/banan-os.kernel root=/dev/sda2 noapic noserial
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "banan-os (no apic, only serial)" {
|
menuentry "banan-os (no apic, only serial)" {
|
||||||
multiboot2 /boot/banan-os.kernel root=/dev/sda2 noapic console=ttyS0
|
multiboot /boot/banan-os.kernel root=/dev/sda2 noapic console=ttyS0
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue