Merge into main the new state of the operating system/kernel #1
5
Makefile
5
Makefile
@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
|
|||||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
|
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
|
||||||
CFLAGS = -ffreestanding -O2 -Wall -Wextra
|
CFLAGS = -ffreestanding -O2 -Wall -Wextra
|
||||||
|
|
||||||
OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o
|
OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o
|
||||||
|
|
||||||
SRC_DIR = src
|
SRC_DIR = src
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
@ -79,3 +79,6 @@ $(BUILD_DIR)/idt.o:
|
|||||||
|
|
||||||
$(BUILD_DIR)/pic.o:
|
$(BUILD_DIR)/pic.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/arch/i386/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(CPP) -c $(SRC_DIR)/kernel/arch/i386/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
|
||||||
|
$(BUILD_DIR)/string.o:
|
||||||
|
$(CC) -c $(SRC_DIR)/libc/include/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "MMU.h"
|
#include "MMU.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -34,8 +35,13 @@ void MMU::enable(){
|
|||||||
enablePaging();
|
enablePaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
uint32_t MMU::readTableEntry(int entry){
|
void IdentityPaging(uint32_t *first_pte, vaddr from, int size)
|
||||||
return this->page_directory[entry];
|
{
|
||||||
|
from = from & 0xFFFFF000; // Discard the bits we don't want
|
||||||
|
for (; size > 0; from += 4096, first_pte++)
|
||||||
|
{
|
||||||
|
*first_pte = from | 1; // makr page present.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -1,13 +1,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern "C" void loadPageDirectory (long unsigned int* addr );
|
extern "C" void loadPageDirectory (uint32_t* addr );
|
||||||
extern "C" void enablePaging();
|
extern "C" void enablePaging();
|
||||||
|
typedef uintptr_t address_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define KB 1024
|
||||||
|
|
||||||
|
static const int MAX_PAGES = 1024 * KB; // 4GB , 4kB/page
|
||||||
|
static volatile address_t pmem_stack[MAX_PAGES];
|
||||||
|
static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation
|
||||||
|
|
||||||
|
|
||||||
|
struct page_directory_entry {};
|
||||||
|
struct page_table_entry{};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MMU {
|
class MMU {
|
||||||
public:
|
public:
|
||||||
void enable ();
|
void enable ();
|
||||||
uint32_t readTableEntry(int);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
||||||
|
@ -21,7 +21,6 @@ stack_bottom:
|
|||||||
stack_top:
|
stack_top:
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interupt handlers
|
* Interupt handlers
|
||||||
*/
|
*/
|
||||||
@ -469,7 +468,7 @@ loadPageDirectory:
|
|||||||
.type _start, @function
|
.type _start, @function
|
||||||
_start:
|
_start:
|
||||||
/*Setup the stack pointer to point to the beginning of our stack */
|
/*Setup the stack pointer to point to the beginning of our stack */
|
||||||
/* I believe its a hight address growing down to lower adress for the stack on x86*/
|
/* I believe its a high address growing down to lower adress for the stack on x86*/
|
||||||
mov $stack_top, %esp
|
mov $stack_top, %esp
|
||||||
|
|
||||||
/*Reset EFLAGS*/
|
/*Reset EFLAGS*/
|
||||||
@ -484,6 +483,7 @@ _start:
|
|||||||
|
|
||||||
call early_main
|
call early_main
|
||||||
cli
|
cli
|
||||||
|
|
||||||
load_gdt:
|
load_gdt:
|
||||||
lgdt gdt
|
lgdt gdt
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "gdtc.h"
|
#include "gdtc.h"
|
||||||
|
#include "../tty/kterm.h"
|
||||||
|
|
||||||
gdtEntry_t gdt[3];
|
gdtEntry_t gdt[3];
|
||||||
|
|
||||||
@ -18,8 +18,10 @@ void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setupGdt(){
|
void setupGdt(){
|
||||||
|
|
||||||
|
printf("setupGdt is called!");
|
||||||
gdtPointer.limit = (sizeof(gdtEntry_t) * 3) - 1;
|
gdtPointer.limit = (sizeof(gdtEntry_t) * 3) - 1;
|
||||||
gdtPointer.base = &gdt;
|
gdtPointer.base = &gdt;
|
||||||
|
|
||||||
gdtSetGate(0, 0, 0, 0, 0);
|
gdtSetGate(0, 0, 0, 0, 0);
|
||||||
gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
extern "c"{
|
extern "C"{
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t lLimit;
|
uint16_t lLimit;
|
||||||
|
@ -44,7 +44,7 @@ void irq_handler (registers regs) {
|
|||||||
// Keyboard interrupt !!
|
// Keyboard interrupt !!
|
||||||
|
|
||||||
int scan;
|
int scan;
|
||||||
register int i;
|
/*register*/int i;
|
||||||
|
|
||||||
// Read scancode
|
// Read scancode
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
extern "C"{
|
extern "C"{
|
||||||
#include "../tty/kterm.h"
|
#include "../tty/kterm.h"
|
||||||
}
|
}
|
||||||
#define AS_KERNEL() ( kterm_writestring("[KERNEL]:"))
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -6,10 +6,11 @@ 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_begin = .;
|
||||||
/* 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. */
|
||||||
@ -40,4 +41,7 @@ SECTIONS
|
|||||||
|
|
||||||
/* 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. */
|
||||||
|
|
||||||
|
kernel_end = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ void PIC_sendEOI (unsigned char irq);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint16_t __pic_get_irq_reg(int ocw3);
|
//static uint16_t __pic_get_irq_reg(int ocw3);
|
||||||
uint16_t pic_get_irr(void);
|
uint16_t pic_get_irr(void);
|
||||||
uint16_t pic_get_isr(void);
|
uint16_t pic_get_isr(void);
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "kterm.h"
|
#include "kterm.h"
|
||||||
|
|
||||||
static const size_t VGA_WIDTH = 80;
|
static const size_t VGA_WIDTH = 80;
|
||||||
static const size_t VGA_HEIGHT = 25;
|
static const size_t VGA_HEIGHT = 25;
|
||||||
|
|
||||||
@ -201,8 +202,10 @@ void printf ( const char *format, ...) {
|
|||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'd':
|
case 'd':
|
||||||
|
kterm_writestring("Not implemented!!");
|
||||||
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
itoa(buf, c, *((int *) arg++));
|
itoa(buf, c, *((int *) arg++));
|
||||||
|
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
#include "../vga/colors.h"
|
#include "../vga/colors.h"
|
||||||
#include "../../../io.h"
|
#include "../../../io.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "./../../../../libc/include/string.h"
|
||||||
|
|
||||||
void kterm_init();
|
void kterm_init();
|
||||||
|
|
||||||
/* Kernel terminal - Colour functions*/
|
/* Kernel terminal - Colour functions*/
|
||||||
@ -31,7 +35,7 @@ int get_cursor_y (uint16_t cursor_pos);
|
|||||||
|
|
||||||
void printf ( const char *format, ...);
|
void printf ( const char *format, ...);
|
||||||
|
|
||||||
static void itoa (char *buf, int base, int d);
|
//static void itoa (char *buf, int base, int d);
|
||||||
|
|
||||||
#define KernelTag "[Kernel]: "
|
#define KernelTag "[Kernel]: "
|
||||||
#define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
|
#define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
|
||||||
|
@ -33,7 +33,7 @@ void CheckMBT ( multiboot_info_t* mbt ){
|
|||||||
/* Are mods_* valid? */
|
/* Are mods_* valid? */
|
||||||
if(CHECK_FLAG ( mbi->flags, 3)){
|
if(CHECK_FLAG ( mbi->flags, 3)){
|
||||||
multiboot_module_t *mod;
|
multiboot_module_t *mod;
|
||||||
int i;
|
uint32_t i;
|
||||||
|
|
||||||
printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
|
printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <cpuid.h> // NOTE: Only available in GCC
|
#include <cpuid.h> // NOTE: Only available in GCC
|
||||||
|
// NOT currently usefull!
|
||||||
static int get_model(){
|
/* static int get_model(){
|
||||||
int ebx, unused;
|
int ebx, unused;
|
||||||
__cpuid(0, unused, ebx, unused, unused);
|
__cpuid(0, unused, ebx, unused, unused);
|
||||||
return ebx;
|
return ebx;
|
||||||
@ -14,3 +14,4 @@
|
|||||||
__get_cpuid(1, &eax, &unused, &unused, &edx);
|
__get_cpuid(1, &eax, &unused, &unused, &edx);
|
||||||
return edx & CPUID_FEAT_EDX_APIC;
|
return edx & CPUID_FEAT_EDX_APIC;
|
||||||
}
|
}
|
||||||
|
*/
|
17
src/kernel/disk.h
Normal file
17
src/kernel/disk.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Let's write an ATA PIO | ATA driver for now. Mostly to show that I can in theory interact with a
|
||||||
|
// storage device
|
||||||
|
|
||||||
|
// PRIMARY_ATA_BUS
|
||||||
|
// 0x1F0 through 0x1F7
|
||||||
|
|
||||||
|
// SECONDARY_ATA_BUS
|
||||||
|
// 0x170 through 0x177
|
||||||
|
|
||||||
|
#define DEVICE_CONTROL_REGISTER 0x3F6
|
||||||
|
#define DEVICE_CONTROL_ALTERNATE 0x376
|
||||||
|
|
||||||
|
|
||||||
|
// IRQ14 Primary bus interrupt
|
||||||
|
// IRQ15 Secondary bus interrupt
|
@ -1,19 +1,24 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
unsigned char inb_p(unsigned short ){
|
unsigned char inb_p(unsigned short ){
|
||||||
|
// TODO: implement me!
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned short inw(unsigned short ){
|
unsigned short inw(unsigned short ){
|
||||||
|
// TODO: implement me!
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned short inw_p(unsigned short ){
|
unsigned short inw_p(unsigned short ){
|
||||||
|
// TODO: implement me!
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned int inl(unsigned short ){
|
unsigned int inl(unsigned short ){
|
||||||
|
// TODO: implement me!
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned int inl_p(unsigned short ){
|
unsigned int inl_p(unsigned short ){
|
||||||
|
// TODO: implement me!
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,11 +23,20 @@ extern "C" {
|
|||||||
/* Are mmap_* valid? */
|
/* Are mmap_* valid? */
|
||||||
if (CHECK_FLAG(mbt->flags, 6)){
|
if (CHECK_FLAG(mbt->flags, 6)){
|
||||||
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
|
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
|
||||||
|
uint32_t memorySizeInBytes = 0;
|
||||||
|
uint32_t reservedMemoryInBytes = 0;
|
||||||
|
|
||||||
|
|
||||||
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
|
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
|
||||||
(unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
|
(unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
|
||||||
|
|
||||||
for (mmap; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
|
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
|
||||||
|
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
|
||||||
|
memorySizeInBytes += mmap->len;
|
||||||
|
} else {
|
||||||
|
reservedMemoryInBytes += mmap->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
printf(
|
printf(
|
||||||
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
|
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
|
||||||
@ -39,17 +48,31 @@ extern "C" {
|
|||||||
(unsigned) mmap->type);
|
(unsigned) mmap->type);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
uint32_t memorySizeInGiB = memorySizeInBytes / 1073741824;
|
||||||
|
|
||||||
|
printf("Available Memory: 0x%x bytes, 0x%x GiB\n", memorySizeInBytes, memorySizeInGiB );
|
||||||
|
printf("Reserved Memory: 0x%x bytes\n", reservedMemoryInBytes );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//int cpu_model = get_model();
|
||||||
|
//int local_apic = check_apic();
|
||||||
|
//printf( "CPU Model: %x, Local APIC: %D\n", cpu_model, local_apic);
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup Paging and memory Managment*/
|
||||||
|
//MMU MemoryManagementUnit = MMU();
|
||||||
|
//MemoryManagementUnit.enable(); // Warning: Causes triple page fault
|
||||||
|
//printf("Pages available: %9d\n", pmm_available());
|
||||||
|
|
||||||
/* Draw diagonal blue line */
|
/* Draw diagonal blue line */
|
||||||
if (CHECK_FLAG (mbi->flags, 12)){
|
if (CHECK_FLAG (mbt->flags, 12)){
|
||||||
printf("Can draw!");
|
printf("Can draw!");
|
||||||
}
|
}
|
||||||
|
|
||||||
int cpu_model = get_model();
|
//setupGdt();
|
||||||
int local_apic = check_apic();
|
|
||||||
printf( "CPU Model: %x, Local APIC: %D\n", cpu_model, local_apic);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,19 +80,12 @@ extern "C" {
|
|||||||
|
|
||||||
init_serial();
|
init_serial();
|
||||||
|
|
||||||
|
while (false){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (true){
|
|
||||||
//Read time indefinetely
|
//Read time indefinetely
|
||||||
read_rtc();
|
read_rtc();
|
||||||
printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second);
|
printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second);
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "../libc/include/string.h"
|
|
||||||
#include "arch/i386/tty/kterm.h"
|
#include "arch/i386/tty/kterm.h"
|
||||||
#include "pmm.h"
|
#include "pmm.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "../libc/include/string.h"
|
||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
#include "bootcheck.h"
|
#include "bootcheck.h"
|
||||||
#include "arch/i386/idt/idt.h"
|
#include "arch/i386/idt/idt.h"
|
||||||
|
108
src/kernel/pci.cpp
Normal file
108
src/kernel/pci.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include "pci.h"
|
||||||
|
|
||||||
|
uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset){
|
||||||
|
uint32_t address;
|
||||||
|
uint32_t lbus = (uint32_t) bus;
|
||||||
|
uint32_t lslot = (uint32_t) slot;
|
||||||
|
uint32_t lfunc = (uint32_t) func;
|
||||||
|
uint16_t tmp = 0;
|
||||||
|
|
||||||
|
/* Create configuration address as per Figure 1 */
|
||||||
|
address = (uint32_t) ((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) |((uint32_t) 0x80000000) );
|
||||||
|
/*write out the address */
|
||||||
|
outl(CONFIG_ADDRESS, address);
|
||||||
|
/* read in the data */
|
||||||
|
/* (offset & 2 ) * 8 ) = o will choosse the first word of the 32 bits register*/
|
||||||
|
tmp = (uint16_t)((inl(CONFIG_DATA)) >> ((offset & 2) * 8) & 0xFFFF);
|
||||||
|
return (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t CheckVendor (uint8_t bus, uint8_t slot) {
|
||||||
|
uint16_t vendor, device;
|
||||||
|
/*
|
||||||
|
Try and read the first configuration register. Since there ar no
|
||||||
|
vendors that == 0xFFFF, it must be a non-existent device.
|
||||||
|
*/
|
||||||
|
if((vendor = ConfigReadWord(bus, slot, 0,0)) != 0xFFFF) {
|
||||||
|
device = ConfigReadWord(bus, slot, 0,2);
|
||||||
|
// Possible read more config values ...
|
||||||
|
} return (vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkDevice (uint8_t bus, uint8_t device ) {
|
||||||
|
uint8_t function = 0;
|
||||||
|
|
||||||
|
uint16_t vendorID = CheckVendor(bus, device);
|
||||||
|
if (vendorID == 0xFFFF) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkFunction (bus, device, function );
|
||||||
|
headerType = getHeaderType(bus, device, function );
|
||||||
|
if( (headerType & 0x80) != 0) {
|
||||||
|
/* It is a multi-function device, so check remaining functions */
|
||||||
|
for (function = 1; function < 8; function++){
|
||||||
|
if (CheckVendor(bus, device)!= 0xFFFF){
|
||||||
|
checkFunction(bus, device, function );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkFunction (uint8_t bus, uint8_t device, uint8_t function ){
|
||||||
|
uint8_t baseClass;
|
||||||
|
uint8_t subClass;
|
||||||
|
uint8_t secondaryBus;
|
||||||
|
|
||||||
|
baseClass = getBaseClass(bus, device, function);
|
||||||
|
subClass = getSubClass (bus, device, function );
|
||||||
|
if ( (baseClass == 0x06) && (subClass == 0x04)){
|
||||||
|
secondaryBus = getSecondaryBus(bus,device, function);
|
||||||
|
checkBus(secondaryBus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Brute-force scan
|
||||||
|
void checkAllBuses (){
|
||||||
|
uint16_t bus;
|
||||||
|
uint8_t device;
|
||||||
|
|
||||||
|
for(bus = 0; bus < 256; bus++){
|
||||||
|
for(device = 0; device < 32; device++){
|
||||||
|
checkDevice(bus,device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursive scan
|
||||||
|
void checkBus (uint8_t bus){
|
||||||
|
uint8_t device;
|
||||||
|
|
||||||
|
for(device = 0; device < 32; device ++){
|
||||||
|
checkDevice(bus,device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkAllBuses(){
|
||||||
|
uint8_t function;
|
||||||
|
uint8_t bus;
|
||||||
|
|
||||||
|
headerType = getHeaderType(0,0,0);
|
||||||
|
if ( (headerType & 0x80) == 0 ){
|
||||||
|
/* Single PCI host controller */
|
||||||
|
checkBus(0);
|
||||||
|
} else{
|
||||||
|
/* Multiple PCI host controllers */
|
||||||
|
for (function = 0; function < 8; function++){
|
||||||
|
if( CheckVendor(0,0) != 0xFFFF) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bus = function;
|
||||||
|
checkBus(bus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
src/kernel/pci.h
Normal file
58
src/kernel/pci.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "io.h"
|
||||||
|
// Configuration Space Access Mechanism #1
|
||||||
|
#define CONFIG_ADDRESS 0xCF8 // Configuration adress that is to be accessed
|
||||||
|
#define CONFIG_DATA 0xCFC // Will do the actual configuration operation
|
||||||
|
|
||||||
|
/*
|
||||||
|
CONFIG_ADDRESS
|
||||||
|
|
||||||
|
32 bit register
|
||||||
|
|
||||||
|
bit 31 Enable bit (Should CONFIG_DATA be translatedc to configuration cycles)
|
||||||
|
bit 30 - 24 Reserved
|
||||||
|
bit 23 - 16 Bus Number (Choose a specific PCI BUS)
|
||||||
|
bit 15 - 11 Device Number (Selects specific device one the pci bus)
|
||||||
|
bit 10 - 8 Function Number (Selects a specific function in a device)
|
||||||
|
bit 7 - 0 Register Offset (Offset in the configuration space of 256 Bytes ) NOTE: lowest two bits will always be zero
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
PCI Device structure
|
||||||
|
|
||||||
|
Register offset bits 31-24 bits 23-16 bits 15-8 bits 7-0
|
||||||
|
00 00 Device ID <---- Vendor ID <-------
|
||||||
|
01 04 Status <---- Command <-------
|
||||||
|
02 08 Class code Sub class Prog IF Revision ID
|
||||||
|
03 0C BIST Header Type Ltncy Timer Cache line Size
|
||||||
|
04 10 Base address #0 (BAR0)
|
||||||
|
05 14 Base address #1 (BAR1)
|
||||||
|
06 18 Base address #2 (BAR2)
|
||||||
|
07 1C Base address #3 (BAR3)
|
||||||
|
08 20 Base address #4 (BAR4)
|
||||||
|
09 24 Base address #5 (BAR5)
|
||||||
|
0A 28 Cardbus CIS Pointer
|
||||||
|
0B 2C Subsystem ID <------ Subsystem Vendor ID <-------
|
||||||
|
0C 30 Expansion ROM base address
|
||||||
|
0D 34 Reserved <------- Capabilities Pointer <------
|
||||||
|
0E 38 Reserved <------- <-------- <--------
|
||||||
|
0F 3C Max ltncy Min Grant Interrupt PIN Interrupt Line
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
The idea for now is to support the minimal things necessary to find ATA supported drives
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Lets write some boiler plate configuration code
|
||||||
|
|
||||||
|
uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset);
|
||||||
|
|
||||||
|
uint16_t CheckVendor (uint8_t bus, uint8_t slot);
|
||||||
|
|
||||||
|
void checkDevice (uint8_t bus, uint8_t device );
|
1
src/kernel/pmm.cpp
Normal file
1
src/kernel/pmm.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "pmm.h"
|
125
src/kernel/pmm.h
Normal file
125
src/kernel/pmm.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
// Lets assume we have 2 gigabytes of memory
|
||||||
|
// NOTE: We should really detect how much memory we have
|
||||||
|
#define KiloByte 1024 // bytes
|
||||||
|
#define MegaByte 1048576 // bytes
|
||||||
|
#define GigaByte 1073741824 // bytes
|
||||||
|
#define MemorySize 2147483648 // bytes
|
||||||
|
|
||||||
|
const uint32_t bitmapSize = MemorySize / 8;
|
||||||
|
|
||||||
|
extern void *kernel_begin;
|
||||||
|
extern void *kernel_end;
|
||||||
|
struct __attribute__((packed)) PMSegment {
|
||||||
|
void* address;
|
||||||
|
uint32_t size;
|
||||||
|
PMSegment* Next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static PMSegment pmStart;
|
||||||
|
static uint32_t AvailablePhysicalMemory;
|
||||||
|
static uint32_t AllocatedMemorySize;
|
||||||
|
|
||||||
|
void initPhysicalMemoryManager(){
|
||||||
|
AvailablePhysicalMemory = MemorySize;
|
||||||
|
AllocatedMemorySize = 0;
|
||||||
|
|
||||||
|
// Map the kernel
|
||||||
|
PMSegment KernelSegment = PMSegment();
|
||||||
|
printf("end of kernel: 0x%x\n", &kernel_end);
|
||||||
|
printf("start of kernel: 0x%x\n", &kernel_begin);
|
||||||
|
printf("pointer to kernel: 0x%x\n", &KernelSegment);
|
||||||
|
|
||||||
|
pmStart = KernelSegment;
|
||||||
|
KernelSegment.address = kernel_begin;
|
||||||
|
KernelSegment.size = &kernel_end - &kernel_begin;
|
||||||
|
AllocatedMemorySize += KernelSegment.size;
|
||||||
|
KernelSegment.Next = 0;
|
||||||
|
|
||||||
|
// make sure We allocate space for ourselves
|
||||||
|
/*PMSegment start = PMSegment();
|
||||||
|
start.address = KernelSegment.address + KernelSegment.size ;
|
||||||
|
start.size = (MemorySize / sizeof(PMSegment) ) + sizeof (uint32_t) * 2;
|
||||||
|
*/
|
||||||
|
|
||||||
|
//KernelSegment.Next = &start;
|
||||||
|
//AllocatedMemorySize += start.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printMemorySegments()
|
||||||
|
{
|
||||||
|
printf("Memory Segments:\n");
|
||||||
|
printf( "Start Segment: [addr: 0x%x, size: 0x%x, Next: 0x%x]\n" ,pmStart.address, pmStart.size, pmStart.Next);
|
||||||
|
printf("----------------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pmem_free (void* address){
|
||||||
|
|
||||||
|
PMSegment* before = 0;
|
||||||
|
PMSegment* current = &pmStart;
|
||||||
|
|
||||||
|
printf("Address of pmStart : 0x%x\n", pmStart);
|
||||||
|
printf("Looking for segment with address: 0x%x \n", address );
|
||||||
|
printf("Address of pmStart(a.k.a current) : 0x%x \n", current);
|
||||||
|
while( current )
|
||||||
|
{
|
||||||
|
//printf("address of current segment 0x%x\n", current->address );
|
||||||
|
if ( current->address == address ) {
|
||||||
|
// this is the address we want to free
|
||||||
|
printf("Segment found!! Segment address: 0x%x \n", current->address);
|
||||||
|
if ( current->Next && before ){
|
||||||
|
before->Next = current->Next;
|
||||||
|
}else{
|
||||||
|
before->Next = 0;
|
||||||
|
}
|
||||||
|
// TODO: Clean memory [ Something like memset to zeroes]
|
||||||
|
printf("Removing segment of size: 0x%x\n", current->size);
|
||||||
|
AllocatedMemorySize -= current->size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
before = current;
|
||||||
|
current = current->Next;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void* pmem_alloc ( uint32_t size ){
|
||||||
|
// Get the last segment
|
||||||
|
PMSegment* lastSegment = &pmStart;
|
||||||
|
|
||||||
|
while (lastSegment ) {
|
||||||
|
if( lastSegment->Next == 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lastSegment = lastSegment->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("LastSegment is for address: 0x%x\n", lastSegment->address);
|
||||||
|
|
||||||
|
|
||||||
|
// So now we have the last segment available
|
||||||
|
PMSegment newSegment = PMSegment();
|
||||||
|
newSegment.address = (PMSegment*)((uint32_t)lastSegment->address + lastSegment->size +1);
|
||||||
|
|
||||||
|
printf("NewSegment for Address: 0x%x\n", newSegment.address);
|
||||||
|
|
||||||
|
newSegment.size = size;
|
||||||
|
|
||||||
|
lastSegment->Next = &newSegment;
|
||||||
|
|
||||||
|
if ( AllocatedMemorySize + newSegment.size > AvailablePhysicalMemory){
|
||||||
|
// No segment available of this size
|
||||||
|
/// ERROR!!
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
AllocatedMemorySize += newSegment.size;
|
||||||
|
|
||||||
|
return newSegment.address;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -49,6 +49,8 @@ void read_rtc() {
|
|||||||
year = get_RTC_register(0x09);
|
year = get_RTC_register(0x09);
|
||||||
if(century_register != 0) {
|
if(century_register != 0) {
|
||||||
century = get_RTC_register(century_register);
|
century = get_RTC_register(century_register);
|
||||||
|
} else {
|
||||||
|
century = 21;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -141,7 +143,7 @@ void WriteTOCMOS(unsigned char array[])
|
|||||||
asm("cli\n\t" // Clear interrupts
|
asm("cli\n\t" // Clear interrupts
|
||||||
"mov al,index\n\t" // move index address
|
"mov al,index\n\t" // move index address
|
||||||
"out 0x70,al\n\t" // copy address to CMOS register
|
"out 0x70,al\n\t" // copy address to CMOS register
|
||||||
/* some kind of real delay here is probably best
|
// some kind of real delay here is probably best
|
||||||
"mov al,tvalue\n\t" // move value to al
|
"mov al,tvalue\n\t" // move value to al
|
||||||
"out 0x71,al\n\t" // write 1 byte to CMOS
|
"out 0x71,al\n\t" // write 1 byte to CMOS
|
||||||
"sti\n\\t" ); // Enable interrupts
|
"sti\n\\t" ); // Enable interrupts
|
||||||
|
9
src/libc/include/string.c
Normal file
9
src/libc/include/string.c
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
size_t strlen(const char* str) {
|
||||||
|
size_t len = 0;
|
||||||
|
while(str[len]){
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
@ -1,8 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
size_t strlen(const char* str){
|
size_t strlen(const char* str);
|
||||||
size_t len = 0;
|
|
||||||
while(str[len]){
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user