Compare commits
1 Commits
feature/pa
...
feature/st
| Author | SHA1 | Date | |
|---|---|---|---|
| f037adcebd |
25
boot/boot.S
25
boot/boot.S
@@ -19,7 +19,7 @@ forced to be within the first 8 KiB of the kernel file.
|
|||||||
.long CHECKSUM
|
.long CHECKSUM
|
||||||
|
|
||||||
#.include "gdt.S"
|
#.include "gdt.S"
|
||||||
.section .data.boot
|
.section .data
|
||||||
gdt:
|
gdt:
|
||||||
.quad 0x0000000000000000
|
.quad 0x0000000000000000
|
||||||
.quad 0x00CF9A000000FFFF
|
.quad 0x00CF9A000000FFFF
|
||||||
@@ -42,7 +42,7 @@ System V ABI standard and de-facto extensions. The compiler will assume the
|
|||||||
stack is properly aligned and failure to align the stack will result in
|
stack is properly aligned and failure to align the stack will result in
|
||||||
undefined behavior.
|
undefined behavior.
|
||||||
*/
|
*/
|
||||||
.section .bss.boot
|
.section .bss
|
||||||
.align 16
|
.align 16
|
||||||
stack_bottom:
|
stack_bottom:
|
||||||
.skip 16384 # 16 KiB
|
.skip 16384 # 16 KiB
|
||||||
@@ -53,7 +53,7 @@ The linker script specifies _start as the entry point to the kernel and the
|
|||||||
bootloader will jump to this position once the kernel has been loaded. It
|
bootloader will jump to this position once the kernel has been loaded. It
|
||||||
doesn't make sense to return from this function as the bootloader is gone.
|
doesn't make sense to return from this function as the bootloader is gone.
|
||||||
*/
|
*/
|
||||||
.section .text.boot
|
.section .text
|
||||||
.global _start
|
.global _start
|
||||||
.type _start, @function
|
.type _start, @function
|
||||||
_start:
|
_start:
|
||||||
@@ -103,25 +103,6 @@ _start:
|
|||||||
|
|
||||||
continue_boot:
|
continue_boot:
|
||||||
sti
|
sti
|
||||||
|
|
||||||
// setting up paging
|
|
||||||
// id map first 4MB using PSE. With
|
|
||||||
movl $135, kernel_page_directory - 0xC0000000
|
|
||||||
movl $135, kernel_page_directory - 0xC0000000 + 3072
|
|
||||||
// load into cr3
|
|
||||||
movl $kernel_page_directory - 0xC0000000, %eax
|
|
||||||
movl %eax, %cr3
|
|
||||||
// enable PSE TODO validate if PSE is actually supported
|
|
||||||
movl %cr4, %eax
|
|
||||||
orl $0x10, %eax
|
|
||||||
movl %eax, %cr4
|
|
||||||
// enable paging
|
|
||||||
movl %cr0, %eax
|
|
||||||
orl $0x80000000, %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
nop
|
|
||||||
pushl 0
|
|
||||||
popl %eax
|
|
||||||
/*
|
/*
|
||||||
Enter the high-level kernel. The ABI requires the stack is 16-byte
|
Enter the high-level kernel. The ABI requires the stack is 16-byte
|
||||||
aligned at the time of the call instruction (which afterwards pushes
|
aligned at the time of the call instruction (which afterwards pushes
|
||||||
|
|||||||
21
include/endian.h
Normal file
21
include/endian.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 14-5-22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEW_KERNEL_ENDIAN_H
|
||||||
|
#define NEW_KERNEL_ENDIAN_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
#define leu16_to_native(x) x
|
||||||
|
#define leu32_to_native(x) x
|
||||||
|
#else
|
||||||
|
#define leu16_to_native(x) ((x) >> 8 | (x) << 8)
|
||||||
|
#define leu32_to_native(x) (((x)>>24)&0xff) | \
|
||||||
|
(((x)<<8)&0xff0000) | \
|
||||||
|
(((x)>>8)&0xff00) | \
|
||||||
|
(((x)<<24)&0xff000000)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //NEW_KERNEL_ENDIAN_H
|
||||||
@@ -14,7 +14,8 @@
|
|||||||
#define PCI_CLASS_BRIDGE 0x06
|
#define PCI_CLASS_BRIDGE 0x06
|
||||||
|
|
||||||
// class MASS STORAGE 0x01
|
// class MASS STORAGE 0x01
|
||||||
#define PCI_SUB_CLASS_IDE 0x01
|
#define PCI_SUB_CLASS_MASS_SCSI 0x00
|
||||||
|
#define PCI_SUB_CLASS_MASS_IDE 0x01
|
||||||
|
|
||||||
// class BRIDGE 0x06
|
// class BRIDGE 0x06
|
||||||
#define PCI_SUB_CLASS_PCI_PCI_BRIDGE_4 0x04
|
#define PCI_SUB_CLASS_PCI_PCI_BRIDGE_4 0x04
|
||||||
|
|||||||
18
include/myke/drivers/pci/virtio.h
Normal file
18
include/myke/drivers/pci/virtio.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 14-5-22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEW_KERNEL_VIRTIO_H
|
||||||
|
#define NEW_KERNEL_VIRTIO_H
|
||||||
|
|
||||||
|
#define PCI_VENDOR_VIRTIO 0x1af4
|
||||||
|
|
||||||
|
#define PCI_DEVICE_VIRTIO_NETWORK 0x1000
|
||||||
|
#define PCI_DEVICE_VIRTIO_BLOCK 0x1001
|
||||||
|
#define PCI_DEVICE_VIRTIO_BALLOON 0x1002
|
||||||
|
#define PCI_DEVICE_VIRTIO_CONSOLE 0x1003
|
||||||
|
#define PCI_DEVICE_VIRTIO_SCSI 0x1004
|
||||||
|
#define PCI_DEVICE_VIRTIO_ENTROPY 0x1005
|
||||||
|
#define PCI_DEVICE_VIRTIO_9P 0x1009
|
||||||
|
|
||||||
|
#endif //NEW_KERNEL_VIRTIO_H
|
||||||
@@ -5,39 +5,4 @@
|
|||||||
#ifndef NEW_KERNEL_PAGING_H
|
#ifndef NEW_KERNEL_PAGING_H
|
||||||
#define NEW_KERNEL_PAGING_H
|
#define NEW_KERNEL_PAGING_H
|
||||||
|
|
||||||
#define PAGING_MASK_4K 0xFFFFF000
|
|
||||||
#define PAGING_MASK_4M 0xFFC00000
|
|
||||||
|
|
||||||
#define DIRECTORY_PRESENT_BIT (0)
|
|
||||||
#define DIRECTORY_RW_BIT (1)
|
|
||||||
#define DIRECTORY_US_BIT (2)
|
|
||||||
#define DIRECTORY_WT_BIT (3)
|
|
||||||
#define DIRECTORY_CACHE_BIT (4)
|
|
||||||
#define DIRECTORY_ACCESSED_BIT (5)
|
|
||||||
#define DIRECTORY_PAGE_SIZE_BIT (7)
|
|
||||||
|
|
||||||
#define DIRECTORY_ADDR_MASK 0xFFFFF000
|
|
||||||
#define DIRECTORY_PRESENT_MASK (1 << DIRECTORY_PRESENT_BIT)
|
|
||||||
#define DIRECTORY_RW_MASK (1 << DIRECTORY_RW_BIT)
|
|
||||||
#define DIRECTORY_US_MASK (1 << DIRECTORY_US_BIT)
|
|
||||||
#define DIRECTORY_WT_MASK (1 << DIRECTORY_WT_BIT)
|
|
||||||
#define DIRECTORY_CACHE_MASK (1 << DIRECTORY_CACHE_BIT)
|
|
||||||
#define DIRECTORY_ACCESSED_MASK (1 << DIRECTORY_ACCESSED_BIT)
|
|
||||||
#define DIRECTORY_PAGE_SIZE_MASK (1 << DIRECTORY_PAGE_SIZE_BIT)
|
|
||||||
|
|
||||||
#define DIRECTORY_SIZE 1024
|
|
||||||
|
|
||||||
#define PAGING_MODE_4M (1 << 0)
|
|
||||||
#define PAGING_MODE_RW (1 << 1)
|
|
||||||
#define PAGING_MODE_US (1 << 2)
|
|
||||||
|
|
||||||
#define PAGING_RESULT_OK 0
|
|
||||||
#define PAGING_RESULT_INUSE 1
|
|
||||||
#define PAGING_RESULT_ALIGN 2
|
|
||||||
#define PAGING_RESULT_ERR 99
|
|
||||||
|
|
||||||
typedef uint32_t page_directory_entry;
|
|
||||||
|
|
||||||
typedef uint32_t page_table_entry;
|
|
||||||
|
|
||||||
#endif //NEW_KERNEL_PAGING_H
|
#endif //NEW_KERNEL_PAGING_H
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by rick on 17-10-21.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef NEW_KERNEL_VMM_H
|
|
||||||
#define NEW_KERNEL_VMM_H
|
|
||||||
|
|
||||||
void vmm_init(multiboot_info_t *multiboot_info);
|
|
||||||
|
|
||||||
#endif //NEW_KERNEL_VMM_H
|
|
||||||
103
include/virtio_queue.h
Normal file
103
include/virtio_queue.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#ifndef VIRTQUEUE_H
|
||||||
|
#define VIRTQUEUE_H
|
||||||
|
/*
|
||||||
|
* Virtual I/O Device (VIRTIO) Version 1.2
|
||||||
|
* Committee Specification Draft 01
|
||||||
|
* 09 May 2022
|
||||||
|
* Copyright (c) OASIS Open 2022. All Rights Reserved.
|
||||||
|
* Source: http://docs.oasis-open.org/virtio/virtio/v1.2/csd01/listings/
|
||||||
|
* Latest stage of narrative specification: http://docs.oasis-open.org/virtio/virtio/v1.2/virtio-v1.2.html
|
||||||
|
* TC IPR Statement: https://github.com/oasis-tcs/virtio-admin/blob/master/IPR.md
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An interface for efficient virtio implementation.
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* This marks a buffer as continuing via the next field. */
|
||||||
|
#define VIRTQ_DESC_F_NEXT 1
|
||||||
|
/* This marks a buffer as write-only (otherwise read-only). */
|
||||||
|
#define VIRTQ_DESC_F_WRITE 2
|
||||||
|
/* This means the buffer contains a list of buffer descriptors. */
|
||||||
|
#define VIRTQ_DESC_F_INDIRECT 4
|
||||||
|
|
||||||
|
/* The device uses this in used->flags to advise the driver: don't kick me
|
||||||
|
* when you add a buffer. It's unreliable, so it's simply an
|
||||||
|
* optimization. */
|
||||||
|
#define VIRTQ_USED_F_NO_NOTIFY 1
|
||||||
|
/* The driver uses this in avail->flags to advise the device: don't
|
||||||
|
* interrupt me when you consume a buffer. It's unreliable, so it's
|
||||||
|
* simply an optimization. */
|
||||||
|
#define VIRTQ_AVAIL_F_NO_INTERRUPT 1
|
||||||
|
|
||||||
|
/* Support for indirect descriptors */
|
||||||
|
#define VIRTIO_F_INDIRECT_DESC 28
|
||||||
|
|
||||||
|
/* Support for avail_event and used_event fields */
|
||||||
|
#define VIRTIO_F_EVENT_IDX 29
|
||||||
|
|
||||||
|
/* Arbitrary descriptor layouts. */
|
||||||
|
#define VIRTIO_F_ANY_LAYOUT 27
|
||||||
|
|
||||||
|
/* Virtqueue descriptors: 16 bytes.
|
||||||
|
* These can chain together via "next". */
|
||||||
|
struct virtq_desc {
|
||||||
|
/* Address (guest-physical). */
|
||||||
|
le64 addr;
|
||||||
|
/* Length. */
|
||||||
|
le32 len;
|
||||||
|
/* The flags as indicated above. */
|
||||||
|
le16 flags;
|
||||||
|
/* We chain unused descriptors via this, too */
|
||||||
|
le16 next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct virtq_avail {
|
||||||
|
le16 flags;
|
||||||
|
le16 idx;
|
||||||
|
le16 ring[];
|
||||||
|
/* Only if VIRTIO_F_EVENT_IDX: le16 used_event; */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* le32 is used here for ids for padding reasons. */
|
||||||
|
struct virtq_used_elem {
|
||||||
|
/* Index of start of used descriptor chain. */
|
||||||
|
le32 id;
|
||||||
|
/* Total length of the descriptor chain which was written to. */
|
||||||
|
le32 len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct virtq_used {
|
||||||
|
le16 flags;
|
||||||
|
le16 idx;
|
||||||
|
struct virtq_used_elem ring[];
|
||||||
|
/* Only if VIRTIO_F_EVENT_IDX: le16 avail_event; */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct virtq {
|
||||||
|
unsigned int num;
|
||||||
|
|
||||||
|
struct virtq_desc *desc;
|
||||||
|
struct virtq_avail *avail;
|
||||||
|
struct virtq_used *used;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int virtq_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old_idx)
|
||||||
|
{
|
||||||
|
return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get location of event indices (only with VIRTIO_F_EVENT_IDX) */
|
||||||
|
static inline le16 *virtq_used_event(struct virtq *vq)
|
||||||
|
{
|
||||||
|
/* For backwards compat, used event index is at *end* of avail ring. */
|
||||||
|
return &vq->avail->ring[vq->num];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline le16 *virtq_avail_event(struct virtq *vq)
|
||||||
|
{
|
||||||
|
/* For backwards compat, avail event index is at *end* of used ring. */
|
||||||
|
return (le16 *)&vq->used->ring[vq->num];
|
||||||
|
}
|
||||||
|
#endif /* VIRTQUEUE_H */
|
||||||
@@ -421,7 +421,7 @@ void ide_register_block_devices() {
|
|||||||
|
|
||||||
uint8_t att_used ide_pci_validate(const pci_device *device) {
|
uint8_t att_used ide_pci_validate(const pci_device *device) {
|
||||||
if (device->class != PCI_CLASS_MASS_STORAGE
|
if (device->class != PCI_CLASS_MASS_STORAGE
|
||||||
|| device->subclass != PCI_SUB_CLASS_IDE
|
|| device->subclass != PCI_SUB_CLASS_MASS_IDE
|
||||||
|| (device->programInterface != 0x8A && device->programInterface != 0x80)) {
|
|| (device->programInterface != 0x8A && device->programInterface != 0x80)) {
|
||||||
return PCI_VALIDATE_FAIL;
|
return PCI_VALIDATE_FAIL;
|
||||||
}
|
}
|
||||||
@@ -686,7 +686,7 @@ PCI_DRIVER(900) = {
|
|||||||
.validatable = true,
|
.validatable = true,
|
||||||
.initialisable = true,
|
.initialisable = true,
|
||||||
.match.class = PCI_CLASS_MASS_STORAGE,
|
.match.class = PCI_CLASS_MASS_STORAGE,
|
||||||
.match.subclass = PCI_SUB_CLASS_IDE,
|
.match.subclass = PCI_SUB_CLASS_MASS_IDE,
|
||||||
.mask.class = true,
|
.mask.class = true,
|
||||||
.mask.subclass = true,
|
.mask.subclass = true,
|
||||||
.validate = ide_pci_validate,
|
.validate = ide_pci_validate,
|
||||||
|
|||||||
46
kernel/drivers/pci/virtio/virtio-lock.c
Normal file
46
kernel/drivers/pci/virtio/virtio-lock.c
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 14-5-22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <endian.h>
|
||||||
|
|
||||||
|
#include <myke/drivers/pci/pci.h>
|
||||||
|
#include <myke/drivers/pci/virtio.h>
|
||||||
|
|
||||||
|
uint8_t att_used virtio_pci_block_validate(const pci_device *pci_device) {
|
||||||
|
uint32_t capacity_l = pci_config_read_double_word(pci_device->bus, pci_device->slot, pci_device->func, 0x14);
|
||||||
|
uint32_t capacity_h = pci_config_read_double_word(pci_device->bus, pci_device->slot, pci_device->func, 0x18);
|
||||||
|
uint32_t segment_size_max = pci_config_read_double_word(pci_device->bus, pci_device->slot, pci_device->func, 0x1c);
|
||||||
|
uint32_t segment_count_max = pci_config_read_double_word(pci_device->bus, pci_device->slot, pci_device->func, 0x20);
|
||||||
|
uint16_t cylinder_count = pci_config_read_word(pci_device->bus, pci_device->slot, pci_device->func, 0x24);
|
||||||
|
uint8_t head_count = pci_config_read_byte(pci_device->bus, pci_device->slot, pci_device->func, 0x26);
|
||||||
|
uint8_t sector_count = pci_config_read_byte(pci_device->bus, pci_device->slot, pci_device->func, 0x27);
|
||||||
|
uint32_t block_length = pci_config_read_double_word(pci_device->bus, pci_device->slot, pci_device->func, 0x28);
|
||||||
|
|
||||||
|
capacity_l = leu32_to_native(capacity_l);
|
||||||
|
capacity_h = leu32_to_native(capacity_h);
|
||||||
|
uint64_t capacity = ((uint64_t) capacity_h) >> 32 | capacity_l;
|
||||||
|
|
||||||
|
return PCI_VALIDATE_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t att_used virtio_pci_block_initialize(pci_device *pci_device) {
|
||||||
|
return PCI_INIT_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PCI_DRIVER(900) = {
|
||||||
|
.name = "pci-virtio-block",
|
||||||
|
.description = "Para-virtualized Block Device",
|
||||||
|
.validatable = true,
|
||||||
|
.initialisable = true,
|
||||||
|
.match.class = PCI_CLASS_MASS_STORAGE,
|
||||||
|
.match.subclass = PCI_SUB_CLASS_MASS_SCSI,
|
||||||
|
.match.vendor = PCI_VENDOR_VIRTIO,
|
||||||
|
.match.device = PCI_DEVICE_VIRTIO_BLOCK,
|
||||||
|
.mask.class = true,
|
||||||
|
.mask.subclass = true,
|
||||||
|
.mask.vendor = true,
|
||||||
|
.mask.device = true,
|
||||||
|
.validate = virtio_pci_block_validate,
|
||||||
|
.initialize = virtio_pci_block_initialize,
|
||||||
|
};
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
#include <myke/libk/kprint.h>
|
#include <myke/libk/kprint.h>
|
||||||
#include <myke/libk/libk.h>
|
#include <myke/libk/libk.h>
|
||||||
#include <myke/libk/syscall.h>
|
#include <myke/libk/syscall.h>
|
||||||
#include <myke/mem/vmm.h>
|
#include <myke/mem/mem.h>
|
||||||
#include <myke/util/init.h>
|
#include <myke/util/init.h>
|
||||||
#include <myke/tasks/task.h>
|
#include <myke/tasks/task.h>
|
||||||
|
|
||||||
@@ -21,6 +21,15 @@ const int version_major = 0,
|
|||||||
version_minor = 0,
|
version_minor = 0,
|
||||||
version_patch = 1;
|
version_patch = 1;
|
||||||
|
|
||||||
|
void init_mmap(multiboot_info_t *multiboot_info) {
|
||||||
|
if (multiboot_info->flags & (1 << 6)) {
|
||||||
|
mmap_init_multiboot((struct multiboot_mmap_entry *) multiboot_info->mmap_addr,
|
||||||
|
multiboot_info->mmap_length / sizeof(struct multiboot_mmap_entry));
|
||||||
|
} else {
|
||||||
|
k_panics("mmap invalid!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void init_pci_system() {
|
void init_pci_system() {
|
||||||
pci_scan();
|
pci_scan();
|
||||||
pci_init_drivers();
|
pci_init_drivers();
|
||||||
@@ -29,9 +38,6 @@ void init_pci_system() {
|
|||||||
void att_noreturn att_used kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) {
|
void att_noreturn att_used kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) {
|
||||||
// early init
|
// early init
|
||||||
isr_install();
|
isr_install();
|
||||||
// initialize memory management
|
|
||||||
vmm_init(multiboot_info);
|
|
||||||
|
|
||||||
// initialize early modules (kprint etc.)
|
// initialize early modules (kprint etc.)
|
||||||
init_execute_all(INIT_STAGE_EARLY_BOOT_0);
|
init_execute_all(INIT_STAGE_EARLY_BOOT_0);
|
||||||
|
|
||||||
@@ -42,6 +48,8 @@ void att_noreturn att_used kmain(multiboot_info_t *multiboot_info, uint32_t mb_n
|
|||||||
|
|
||||||
store_bootloader_info(multiboot_info);
|
store_bootloader_info(multiboot_info);
|
||||||
|
|
||||||
|
// initialize memory management
|
||||||
|
init_mmap(multiboot_info);
|
||||||
// safe multiboot info for later use
|
// safe multiboot info for later use
|
||||||
debug_store_info(multiboot_info);
|
debug_store_info(multiboot_info);
|
||||||
|
|
||||||
|
|||||||
@@ -2,80 +2,58 @@
|
|||||||
// Created by rick on 21-02-21.
|
// Created by rick on 21-02-21.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <attributes.h>
|
#include <attributes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <myke/mem/paging.h>
|
#include <myke/mem/paging.h>
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#define PAGING_DIR_INDEX(virt) ((virt) >> 22)
|
#define TABLE_ADDR_MASK 0xFFFFF000
|
||||||
#define PAGING_TABLE_INDEX(virt) ((virt) >> 12 & 0x03FF)
|
#define DIRECTORY_SIZE 1024
|
||||||
|
|
||||||
#define KERNEL_OFFSET 0xC0000000
|
const uint32_t x = TABLE_ADDR_MASK;
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
bool present: 1;
|
||||||
|
bool read_write: 1;
|
||||||
|
bool user_mode: 1;
|
||||||
|
bool write_through: 1;
|
||||||
|
bool cache_disabled: 1;
|
||||||
|
bool accessed: 1;
|
||||||
|
char ignored: 1;
|
||||||
|
bool page_size: 1;
|
||||||
|
bool global: 1; // ignored
|
||||||
|
uint8_t avail: 3;
|
||||||
|
} att_packed;
|
||||||
|
uint32_t addr;
|
||||||
|
};
|
||||||
|
} att_packed page_directory_entry;
|
||||||
|
|
||||||
// One page table, only 4M
|
typedef struct {
|
||||||
#define PAGING_STATE_EARLY 0
|
union {
|
||||||
#define PAGING_STATE_FULL 60
|
struct {
|
||||||
|
bool present: 1;
|
||||||
|
bool read_write: 1;
|
||||||
|
bool user_supervisor: 1;
|
||||||
|
bool write_through: 1;
|
||||||
|
bool cache_disabled: 1;
|
||||||
|
bool accessed: 1;
|
||||||
|
bool dirty: 1;
|
||||||
|
char ignored: 1;
|
||||||
|
bool global: 1;
|
||||||
|
uint8_t available: 3;
|
||||||
|
} att_packed;
|
||||||
|
uint32_t addr;
|
||||||
|
};
|
||||||
|
} att_packed page_table_entry;
|
||||||
|
|
||||||
page_directory_entry att_aligned(4096) kernel_page_directory[DIRECTORY_SIZE] = {0};
|
page_directory_entry page_directory[DIRECTORY_SIZE] att_aligned(4096);
|
||||||
|
|
||||||
int paging_state = PAGING_STATE_EARLY;
|
void page_pre_init() {
|
||||||
|
for (int i = 0; i < DIRECTORY_SIZE; ++i) {
|
||||||
void paging_load_directory(uintptr_t physical_address) {
|
page_directory[i].read_write = true;
|
||||||
asm volatile("mov %%eax, %%cr3" : : "a" (physical_address));
|
page_directory[i].user_mode = false;
|
||||||
}
|
page_directory[i].present = false;
|
||||||
|
|
||||||
uintptr_t paging_get_current_directory_physical() {
|
|
||||||
uintptr_t directory_address;
|
|
||||||
asm volatile("mov %%cr3, %%eax" : "=a" (directory_address));
|
|
||||||
return directory_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
page_directory_entry *paging_get_current() {
|
|
||||||
return kernel_page_directory;
|
|
||||||
}
|
|
||||||
|
|
||||||
int paging_map_4m(uintptr_t physical_address, uintptr_t virtual_address, int count, int mode) {
|
|
||||||
if (virtual_address & ~PAGING_MASK_4M || physical_address & PAGING_MASK_4M) {
|
|
||||||
// address not 4M aligned
|
|
||||||
return PAGING_RESULT_ALIGN;
|
|
||||||
}
|
}
|
||||||
page_directory_entry *dir = paging_get_current();
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
page_directory_entry current_val = dir[PAGING_DIR_INDEX(virtual_address) + i];
|
|
||||||
if (current_val & DIRECTORY_PRESENT_MASK) {
|
|
||||||
return PAGING_RESULT_INUSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
page_directory_entry mask = DIRECTORY_PAGE_SIZE_MASK;
|
|
||||||
if (mode & PAGING_MODE_RW) {
|
|
||||||
mask |= DIRECTORY_RW_MASK;
|
|
||||||
}
|
|
||||||
if (mode & PAGING_MODE_US) {
|
|
||||||
mask |= DIRECTORY_US_MASK;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
dir[PAGING_DIR_INDEX(virtual_address) + i] = physical_address & mask;
|
|
||||||
}
|
|
||||||
paging_load_directory((uintptr_t) dir);
|
|
||||||
return PAGING_RESULT_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int paging_map_memory(uintptr_t physical_address, uintptr_t virtual_address, int count, int mode) {
|
|
||||||
if (mode & PAGING_MODE_4M) {
|
|
||||||
return paging_map_4m(physical_address, virtual_address, count, mode);
|
|
||||||
}
|
|
||||||
if (paging_state < PAGING_STATE_FULL) {
|
|
||||||
// can't allocate 4K pages yet
|
|
||||||
if ((virtual_address & ~PAGING_MASK_4M) != (physical_address & ~PAGING_MASK_4M)) {
|
|
||||||
return PAGING_RESULT_ERR; // not in same pos in 4M page
|
|
||||||
}
|
|
||||||
int table_index = PAGING_TABLE_INDEX(virtual_address);
|
|
||||||
int pages = DIV_ROUND_UP(table_index + count, 1024);
|
|
||||||
return paging_map_4m(physical_address & PAGING_MASK_4M,
|
|
||||||
virtual_address & PAGING_MASK_4M,
|
|
||||||
pages,
|
|
||||||
mode | PAGING_MODE_4M);
|
|
||||||
}
|
|
||||||
return PAGING_RESULT_ERR;
|
|
||||||
}
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by rick on 17-10-21.
|
|
||||||
//
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <myke/libk/libk.h>
|
|
||||||
#include <myke/mem/mem.h>
|
|
||||||
#include <myke/mem/vmm.h>
|
|
||||||
|
|
||||||
void vmm_init(multiboot_info_t *multiboot_info) {
|
|
||||||
if (!(multiboot_info->flags & MULTIBOOT_INFO_MEM_MAP)) {
|
|
||||||
k_panics("No MMAP info available");
|
|
||||||
}
|
|
||||||
mmap_init_multiboot((struct multiboot_mmap_entry *) multiboot_info->mmap_addr,
|
|
||||||
multiboot_info->mmap_length / sizeof(struct multiboot_mmap_entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
void* vmm_map_physical(uintptr_t physical) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void* vmm_unmap_physical(uintptr_t physical) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void* vmm_unmap_virtual(uintptr_t virtual) {
|
|
||||||
}
|
|
||||||
@@ -37,6 +37,10 @@ while [[ "$#" -gt 0 ]]; do
|
|||||||
ARGS="${ARGS} -drive id=disk1,file=$2,if=none -device ahci,id=ahci -device ide-drive,drive=disk1,bus=ahci.0"
|
ARGS="${ARGS} -drive id=disk1,file=$2,if=none -device ahci,id=ahci -device ide-drive,drive=disk1,bus=ahci.0"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--virtio)
|
||||||
|
ARGS="$ARGS -drive id=disk1,file=$2,if=virtio"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
-m | --max-cpu)
|
-m | --max-cpu)
|
||||||
ARGS="${ARGS} -cpu max"
|
ARGS="${ARGS} -cpu max"
|
||||||
shift
|
shift
|
||||||
|
|||||||
114
linker.ld
114
linker.ld
@@ -6,76 +6,66 @@ ENTRY(_start)
|
|||||||
kernel image. */
|
kernel image. */
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
|
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
|
||||||
loaded at by the bootloader. */
|
loaded at by the bootloader. */
|
||||||
. = 1M;
|
. = 1M;
|
||||||
_kernel_start = .;
|
_kernel_start = .;
|
||||||
.data.boot ALIGN(4K) : {
|
|
||||||
*(.multiboot)
|
|
||||||
*(.data.boot)
|
|
||||||
}
|
|
||||||
.text.boot ALIGN(4K) : {
|
|
||||||
*(.text.boot)
|
|
||||||
}
|
|
||||||
.bss.boot ALIGN(4K) : {
|
|
||||||
*(.bss.boot)
|
|
||||||
}
|
|
||||||
|
|
||||||
. += 0xC0000000;
|
/* First put the multiboot header, as it is required to be put very early
|
||||||
/* First put the multiboot header, as it is required to be put very early
|
early in the image or the bootloader won't recognize the file format.
|
||||||
early in the image or the bootloader won't recognize the file format.
|
Next we'll put the .text section. */
|
||||||
Next we'll put the .text section. */
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
.text ALIGN(4K) : AT(ADDR(.text)-0xC0000000)
|
{
|
||||||
{
|
*(.multiboot)
|
||||||
*(.text)
|
*(.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read-only data. */
|
/* Read-only data. */
|
||||||
.rodata ALIGN(4K) : AT(ADDR(.rodata)-0xC0000000)
|
.rodata BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
*(.rodata)
|
*(.rodata)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read-write data (initialized) */
|
/* Read-write data (initialized) */
|
||||||
.data ALIGN(4K) : AT(ADDR(.data)-0xC0000000)
|
.data BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
*(.data)
|
*(.data)
|
||||||
|
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
__start_pci_driver = .;
|
__start_pci_driver = .;
|
||||||
*(SORT(.pci_driver.*))
|
*(SORT(.pci_driver.*))
|
||||||
__stop_pci_driver = .;
|
__stop_pci_driver = .;
|
||||||
|
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
__start_block_dev_driver = .;
|
__start_block_dev_driver = .;
|
||||||
*(SORT(.block_dev_driver.*))
|
*(SORT(.block_dev_driver.*))
|
||||||
__stop_block_dev_driver = .;
|
__stop_block_dev_driver = .;
|
||||||
|
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
__start_vfs_driver = .;
|
__start_vfs_driver = .;
|
||||||
*(SORT(.vfs_driver.*))
|
*(SORT(.vfs_driver.*))
|
||||||
__stop_vfs_driver = .;
|
__stop_vfs_driver = .;
|
||||||
|
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
__start_init = .;
|
__start_init = .;
|
||||||
*(SORT(.init.*))
|
*(SORT(.init.*))
|
||||||
__stop_init = .;
|
__stop_init = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read-write data (uninitialized) and stack */
|
/* Read-write data (uninitialized) and stack */
|
||||||
.bss ALIGN(4K) : AT(ADDR(.bss)-0xC0000000)
|
.bss BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
*(.bss)
|
*(.bss)
|
||||||
}
|
}
|
||||||
_kernel_end = . - 0xC0000000;
|
_kernel_end = .;
|
||||||
|
|
||||||
/DISCARD/ : {
|
/DISCARD/ : {
|
||||||
*(.eh_frame);
|
*(.eh_frame);
|
||||||
*(.comment);
|
*(.comment);
|
||||||
*(.note.gnu.build-id);
|
*(.note.gnu.build-id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The compiler may produce other sections, by default it will put them in
|
/* The compiler may produce other sections, by default it will put them in
|
||||||
a segment with the same name. Simply add stuff here as needed. */
|
a segment with the same name. Simply add stuff here as needed. */
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user