view cos/kernel/kernel.h @ 66:bcd55a341512

Added py3k check
author windel
date Sun, 07 Oct 2012 17:27:09 +0200
parents 35cc54e078dd
children
line wrap: on
line source

#ifndef KERNEL_H
#define KERNEL_H

// Include common functions, available to all!
#define NULL ((void*)0)

/* Types */

// Type defs:
typedef unsigned char       uint8_t;
typedef unsigned short      uint16_t;
typedef unsigned int        uint32_t;
typedef unsigned long int   uint64_t;
typedef long int            int64_t;

_Static_assert(sizeof(uint8_t) == 1, "sizeof(uint8_t) != 1");
_Static_assert(sizeof(uint16_t) == 2, "sizeof(uint16_t) != 2");
_Static_assert(sizeof(uint32_t) == 4, "sizeof(uint32_t) != 4");
_Static_assert(sizeof(uint64_t) == 8, "sizeof(uint64_t) != 8");
_Static_assert(sizeof(int64_t) == 8, "sizeof(int64_t) != 8");

// IDT related structures:
typedef struct {
  uint16_t baseLow;
  uint16_t selector;
  uint8_t reserved1;
  uint8_t flags;
  uint16_t baseMid;
  uint32_t baseHigh;
  uint32_t reserved2;
} __attribute__((packed)) IDT_entry;

typedef struct {
      uint16_t   limit;
      uint64_t   base;
} __attribute__((packed)) idtPointer;

// Multiboot structs:
struct multiboot_aout_symbol_table {
  uint32_t tabsize;
  uint32_t strsize, addr, reserved;
};

typedef struct multiboot_info_tag 
{
  uint32_t flags; // Multiboot flags / version
  uint32_t mem_lower; // available memory from BIOS
  uint32_t mem_upper;
  uint32_t boot_device; 
  uint32_t cmdline; // COmmand line
  uint32_t mods_count;
  uint32_t mods_addr;
  union {
   struct multiboot_aout_symbol_table aout_sym;
  } u;

  uint32_t mmap_length;
  uint32_t mmap_addr;
} multiboot_info_t;

typedef struct memory_map_tag 
{
  uint32_t size;
  uint64_t base;
  uint64_t length;
  uint32_t type;
} __attribute__((packed)) multiboot_memory_map_t;

typedef struct
{
   uint32_t mod_start;
   uint32_t mod_end;
   uint32_t cmdline;
   uint32_t pad;
} multiboot_module_t;

// Memory manager structures:
typedef struct
{
   uint64_t present : 1;
   uint64_t rw : 1;
   uint64_t us : 1; // user or supervisor
   uint64_t pwt : 1; // page level write-through
   uint64_t pcd : 1; // page cache disable
   uint64_t accessed : 1;
   uint64_t ignored : 1;
   uint64_t ps : 1; // must be 0.
   uint64_t ignored2 : 4;
   // 12 bits so far
   uint64_t address : 40; // address of page directory pointer table.
   uint64_t ignored3 : 11;
   uint64_t xd : 1; // execute disable
} PML4E_t; // 64 bits wide, PML4 table must be 4096 byte aligned.

typedef struct
{
   // Must be 12 bits aligned!
   PML4E_t table[512];
   uint64_t physicalAddress; // Physical address of the table above
} PML4_t;

typedef struct
{
   uint64_t present : 1;
   uint64_t rw : 1;
   uint64_t us : 1; // user or supervisor
   uint64_t pwt : 1; // page level write-through
   uint64_t pcd : 1; // page cache disable
   uint64_t accessed : 1;
   uint64_t ignored : 1;
   uint64_t ps : 1; // page size, must be 0, otherwise maps a 1 GB page.
   uint64_t ignored2 : 4;
   // 12 bits so far
   uint64_t address : 40; // address of page directory table.
   uint64_t ignored3 : 11;
   uint64_t xd : 1; // execute disable
} PDPTE_t; // Page directory pointer table entry, 64 bits wide. 4-kB aligned.

// Page directory pointer table:
typedef struct
{
   PDPTE_t table[512];
   uint64_t physicalAddress;
} PDPT_t;

typedef struct
{
   uint64_t present : 1;
   uint64_t rw : 1;
   uint64_t us : 1; // user or supervisor
   uint64_t pwt : 1;
   uint64_t pcd : 1; // page cache disable
   uint64_t accessed : 1;
   uint64_t ignored : 1;
   uint64_t ps : 1; // page size, must be 0, otherwise maps a 2-MB page.
   uint64_t ignored2 : 4;
   // 12 bits so far
   uint64_t address : 40; // address of page table.
   uint64_t ignored3 : 11;
   uint64_t xd : 1; // execute disable
} PDE_t;

// Page directory:
typedef struct
{
   PDE_t table[512];
   uint64_t physicalAddress;
} PD_t;

typedef struct
{
   unsigned present : 1;
   uint64_t rw : 1;
   uint64_t us : 1; // user or supervisor
   uint64_t pwt : 1;
   uint64_t pcd : 1; // page cache disable
   uint64_t accessed : 1;
   uint64_t dirty : 1;
   uint64_t pat : 1; // memory type?
   uint64_t g : 1; // Global?
   uint64_t ignored : 3;

   uint64_t address : 40;
   uint64_t ignored2 : 11;
   uint64_t xd : 1;
} page_t;

_Static_assert(sizeof(page_t) == 8, "sizeof(page_t) != 8");
_Static_assert(sizeof(PDE_t) == 8, "sizeof(PDE_t) != 8");
_Static_assert(sizeof(PDPTE_t) == 8, "sizeof(PDPTE_t) != 8");
_Static_assert(sizeof(PML4E_t) == 8, "sizeof(PML4E_t) != 8");

// Page table:
typedef struct
{
   page_t table[512];
   uint64_t physicalAddress;
} PT_t;

// Make memmap a PML4 type:
typedef PML4_t memmap_t;

// Malloc related functions
typedef struct {
   uint64_t magic;
   uint64_t state;
   uint64_t size;
} heap_header_t;

typedef struct
{
   heap_header_t *first_block;
   uint64_t start_address;
   uint64_t end_address;
} heap_t;

// Task related types:
typedef struct 
{
  char name[32]; // Name of the console
  unsigned char screendata[80*25]; // All chars in the console!
} console_t;

typedef struct task_t {
  struct task_t* next;
  uint32_t kstack;
  uint32_t ustack;

  // For task switching:
  uint64_t cr3;
  uint64_t rip;
  uint64_t rsp;
  uint64_t rbp;

  uint32_t pid;
  uint32_t parent;
  uint32_t owner;
  uint32_t groups;
  uint32_t timetorun;
  uint32_t sleep;
  uint32_t priority;
  uint32_t filehandle;
  char naam[32];

  console_t *console;
} task_t;

/* Filesystem related types: */
struct fs_node_tag;
struct fs_dirent_tag;

typedef uint64_t (*read_type_t)(struct fs_node_tag*, uint64_t, uint64_t, uint8_t*);
typedef uint64_t (*write_type_t)(struct fs_node_tag*, uint64_t, uint64_t, uint8_t*);
typedef void (*open_type_t)(struct fs_node_tag*);
typedef void (*close_type_t)(struct fs_node_tag*);
typedef struct fs_dirent_tag* (*readdir_type_t)(struct fs_node_tag*, int);

typedef struct fs_node_tag
{
   char name[129];
   uint64_t flags;
   uint64_t length;
   uint64_t inode;
   // Accessor functions:
   read_type_t read;
   write_type_t write;
   open_type_t open;
   close_type_t close;
   readdir_type_t readdir;
} fs_node_t;

typedef struct fs_dirent_tag
{
   char name[65];
   uint64_t inode;
} fs_dirent_t;

#define FS_FILE 0x1
#define FS_DIRECTORY 0x2

uint64_t read_fs(fs_node_t *node, uint64_t offset, uint64_t size, uint8_t *buffer);
uint64_t write_fs(fs_node_t *node, uint64_t offset, uint64_t size, uint8_t *buffer);
void open_fs(fs_node_t *node);
void close_fs(fs_node_t *node);
fs_dirent_t* readdir_fs(fs_node_t *node, int i);

// Initial ramdisk functions:
fs_node_t* initialize_initrd(uint64_t location);

void load_ramdisk(void);

// Variable argument list things:
#define va_start(v,l)	__builtin_va_start(v,l)
#define va_end(v)	__builtin_va_end(v)
#define va_arg(v,l)	__builtin_va_arg(v,l)
typedef __builtin_va_list va_list;

/* Global variables */
extern uint64_t kernel_end;
extern uint64_t placement_address;
extern memmap_t* kernel_map;

/* Procedures */

// memory functions:
// TODO: remove some redundant API functions:
void init_memory(uint64_t total_mem_size);
page_t* get_page(uint64_t address, memmap_t*);
void alloc_frame(page_t *page);
void loadPageTable(void* tableAddress);
void switch_mapping(memmap_t* mapping);
void enablePaging();

// Malloc related:
void* kmalloc(uint64_t size);
void* kmalloc_a(uint64_t size); // Aligned on a 4 KiB page.
void kfree(void* ptr);
heap_t* create_heap(uint64_t location, uint64_t size);

// task related functions:
void initialize_tasking();
void new_task();
void task_scheduler();

// STDout funcs:
void printf(const char* fmt, ... );
void memset(void* ptr, uint8_t value, uint64_t num);
void memcpy(void* dst, void* src, uint64_t num);
int strncmp(const char* s1, const char* s2, int size); 

// Screen related:
void clear_screen();
void init_screen();
void print_string(const char *);
void set_cursor(int newrow, int newcol);
void get_cursor(int *therow, int *thecol);
void set_color(int forecolor, int backcolor);

// For IO ports:
uint8_t inb(uint16_t);
uint16_t inw(uint16_t);
void outb(uint16_t, uint8_t);

// Interrupt functions:
void setupIDT(void);
void PICremap(void);
void loadIDT(void);

// ASM helper:
uint64_t read_rip();

// Helpers:
void halt(void);
void panic(char *msg);
void reboot(void);
void magicBochsBreak();
void doCPUID(int eax, int *ebx, int *ecx, int *edx);

// Keyboard driver:
void keyboardDriverUpdate(void);
void getline(char *buffer, int len);
void keyboard_init(void);

// Timer:
void timerDriverUpdate(void);
uint64_t getTimeMS();
void timer_init(void);

// Multiboot:
extern uint64_t available_memory;
extern uint64_t ramdisk_location;
void read_multiboot_info(void);

// Shell
void shell(void);

#endif