summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--makefile2
-rw-r--r--src/kernel/ata.h36
-rw-r--r--src/kernel/drive.c12
-rw-r--r--src/kernel/drive.h12
-rw-r--r--src/kernel/fat.c70
-rw-r--r--src/kernel/fat.h2
-rw-r--r--src/kernel/ide.c226
-rw-r--r--src/kernel/ide.h6
-rw-r--r--src/kernel/main.c49
-rw-r--r--src/kernel/mem.c4
-rw-r--r--src/kernel/mem.h4
-rw-r--r--src/kernel/panic.c7
-rw-r--r--src/kernel/panic.h4
-rw-r--r--src/kernel/pci.c9
-rw-r--r--src/kernel/pci.h8
-rw-r--r--src/kernel/plef.c7
-rw-r--r--src/kernel/plef.h3
-rw-r--r--src/kernel/serial.c7
-rw-r--r--src/kernel/serial.h8
-rw-r--r--src/kernel/task.c2
-rw-r--r--src/kernel/task.h2
-rw-r--r--src/kernel/util.c10
-rw-r--r--src/kernel/util.h16
-rw-r--r--src/kernel/vesa.c18
-rw-r--r--src/kernel/vesa.h25
-rw-r--r--src/kernel/vga.c6
-rw-r--r--src/kernel/vga.h4
27 files changed, 285 insertions, 274 deletions
diff --git a/makefile b/makefile
index 03ab19a..2152dde 100644
--- a/makefile
+++ b/makefile
@@ -21,7 +21,7 @@ skel:
mkdir -p out/fs
cp -r fs-skel/* out/fs/
-kgccargs = -Wall -m32 -Og -ffreestanding -fno-asynchronous-unwind-tables
+kgccargs = -Wall -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=malloc -m32 -Og -ffreestanding -fno-asynchronous-unwind-tables
ugccargs = ${kgccargs} -Isrc/libc/inc
nasmargs = -f elf32
diff --git a/src/kernel/ata.h b/src/kernel/ata.h
index 7c42cdb..28ef0de 100644
--- a/src/kernel/ata.h
+++ b/src/kernel/ata.h
@@ -38,23 +38,16 @@ enum {
};
enum {
- ATA_REG_DATA = 0x0,
- ATA_REG_ERROR = 0x1,
- ATA_REG_FEAT = 0x1,
- ATA_REG_COUNT_LOW = 0x2,
- ATA_REG_LBA0 = 0x3,
- ATA_REG_LBA1 = 0x4,
- ATA_REG_LBA2 = 0x5,
- ATA_REG_SELECT = 0x6,
- ATA_REG_CMD = 0x7,
- ATA_REG_STATUS = 0x7,
- ATA_REG_COUNT_HIGH = 0x8,
- ATA_REG_LBA3 = 0x9,
- ATA_REG_LBA4 = 0xa,
- ATA_REG_LBA5 = 0xb,
- ATA_REG_CONTROL = 0xc,
- ATA_REG_ALT_STATUS = 0xc,
- ATA_REG_ADDR = 0xd
+ ATA_REG_DATA = 0x0,
+ ATA_REG_ERROR = 0x1,
+ ATA_REG_FEAT = 0x1,
+ ATA_REG_COUNT = 0x2,
+ ATA_REG_LBA0 = 0x3,
+ ATA_REG_LBA1 = 0x4,
+ ATA_REG_LBA2 = 0x5,
+ ATA_REG_SELECT = 0x6,
+ ATA_REG_CMD = 0x7,
+ ATA_REG_STATUS = 0x7,
};
enum {
@@ -71,5 +64,12 @@ enum {
};
enum {
- ATA_CONTROL_NO_IRQS = 0x02
+ ATA_CONTROL_NO_IRQS = 0x02,
+};
+
+enum {
+ PATA_TYPE_ID = 0x0000,
+ SATA_TYPE_ID = 0xc33c,
+ PATAPI_TYPE_ID = 0xeb14,
+ SATAPI_TYPE_ID = 0x9669
}; \ No newline at end of file
diff --git a/src/kernel/drive.c b/src/kernel/drive.c
index bf27ec6..b001aca 100644
--- a/src/kernel/drive.c
+++ b/src/kernel/drive.c
@@ -1,24 +1,24 @@
#include "drive.h"
-#include "fat.h"
#include "panic.h"
+#include "fat.h"
uint8_t n_drives = 0;
struct drive drives[256];
-drive_file_id_t unknown_get_file(struct drive *d, char *path) {
+__attribute__ ((const)) drive_file_id_t unknown_get_file(const struct drive *d, const char *path) {
return 0;
}
-void unknown_free_file(struct drive *d, drive_file_id_t fid) {
+void unknown_free_file(const struct drive *d, drive_file_id_t fid) {
panic("Free file called on unknown file system");
}
-void unknown_load_sector(struct drive *d, drive_file_id_t fid, uint32_t sector, void *at) {
+void unknown_load_sector(const struct drive *d, drive_file_id_t fid, uint32_t sector, void *at) {
panic("Load sector called on unknown file system");
}
-uint32_t unknown_get_free_sectors(struct drive *d) {
- return d->n_sectors;
+__attribute__ ((const)) uint32_t unknown_get_free_sectors(const struct drive *d) {
+ return -1;
}
void determine_fs(struct drive *d) {
diff --git a/src/kernel/drive.h b/src/kernel/drive.h
index 8d3f3b2..ca6d1ee 100644
--- a/src/kernel/drive.h
+++ b/src/kernel/drive.h
@@ -14,15 +14,15 @@ struct drive {
char *drive_type;
char *fs_type;
- uint8_t (*read_sectors)(struct drive *d, uint32_t start, uint32_t count, void *buffer);
- uint8_t (*write_sectors)(struct drive *d, uint32_t start, uint32_t count, void *buffer);
+ uint8_t (*read_sectors)(const struct drive *d, uint32_t start, uint32_t count, void *buffer);
+ uint8_t (*write_sectors)(const struct drive *d, uint32_t start, uint32_t count, const void *buffer);
uint32_t n_sectors;
drive_id_t drive_id;
- drive_file_id_t (*get_file)(struct drive *d, char *path);
- void (*free_file)(struct drive *d, drive_file_id_t fid);
- void (*load_sector)(struct drive *d, drive_file_id_t fid, uint32_t sector, void *at);
- uint32_t (*get_free_sectors)(struct drive *d);
+ drive_file_id_t (*get_file)(const struct drive *d, const char *path);
+ void (*free_file)(const struct drive *d, drive_file_id_t fid);
+ void (*load_sector)(const struct drive *d, drive_file_id_t fid, uint32_t sector, void *at);
+ uint32_t (*get_free_sectors)(const struct drive *d);
fs_id_t fs_id;
};
diff --git a/src/kernel/fat.c b/src/kernel/fat.c
index 087d79e..807af00 100644
--- a/src/kernel/fat.c
+++ b/src/kernel/fat.c
@@ -1,9 +1,9 @@
-#include "fat.h"
-#include "ata.h"
-#include "panic.h"
#include "drive.h"
-#include "mem.h"
+#include "panic.h"
#include "util.h"
+#include "ata.h"
+#include "fat.h"
+#include "mem.h"
#define MAX_FAT_DRIVES 16
#define MAX_OPEN_FILES_PER_DRIVE 32
@@ -57,20 +57,19 @@ struct fat_info {
uint8_t fs_type[8];
} __attribute__ ((packed));
-#define CTOS(c, fi) ((fi)->reserved_sectors + (fi)->sectors_per_fat * (fi)->fats + ((fi)->root_entries >> 4) + (c) - 2)
+#define CTOS(c, fdi) ((fdi)->data_start + (c) - 2)
struct fat_drive_info {
- struct fat_info *fi;
+ const struct fat_info *fi;
uint16_t *fat;
+ uint16_t root_start;
+ uint16_t data_start;
struct directory_entry open_files[MAX_OPEN_FILES_PER_DRIVE];
};
struct fat_drive_info infos[MAX_FAT_DRIVES];
uint8_t next_id = 0;
-#define FI(n) ((struct fat_info *)(infos[n].fi + 3))
-#define FN(n, f) (infos[n].open_files[f - 1])
-
uint8_t fat_driver_buffer[512];
struct fat_info *next_fi;
@@ -80,8 +79,9 @@ void alloc_next_fi() {
panic("Out of memory in FAT driver.");
}
-struct drive *cur_drive;
+const struct drive *cur_drive;
fs_id_t cur_id;
+const struct fat_drive_info *cur_fdi;
struct directory_entry *cur_dir;
//loads cluster `c`
@@ -91,7 +91,7 @@ void load_cluster(uint16_t c, void *to) {
return;
}
- uint32_t s = CTOS(c, FI(cur_id));
+ uint32_t s = CTOS(c, cur_fdi);
cur_drive->read_sectors(cur_drive, s, 1, to);
}
@@ -99,7 +99,7 @@ uint16_t next_cluster(uint16_t c) {
panic("TODO: compute next sector (or 0 for none)");
}
-static inline bool check_fat_names(uint8_t *a, uint8_t *b) {
+static inline bool check_fat_names(const uint8_t *a, const uint8_t *b) {
return (((uint32_t *)a)[0] == ((uint32_t *)b)[0]) &&
(((uint32_t *)a)[1] == ((uint32_t *)b)[1]) &&
(((uint16_t *)a)[8] == ((uint16_t *)b)[8]) &&
@@ -107,8 +107,8 @@ static inline bool check_fat_names(uint8_t *a, uint8_t *b) {
}
//after: cur_dir -> specified entry in root
-bool try_locate_root_entry(uint8_t *fat_name) {
- uint32_t cur_dir_sect = FI(cur_id)->reserved_sectors + FI(cur_id)->sectors_per_fat * FI(cur_id)->fats - 1;
+bool try_locate_root_entry(const uint8_t *fat_name) {
+ uint32_t cur_dir_sect = cur_fdi->root_start - 1;
cur_dir = (struct directory_entry *)(fat_driver_buffer + 512);
while (true) {
if (cur_dir == (struct directory_entry *)(fat_driver_buffer + 512)) {
@@ -127,7 +127,7 @@ bool try_locate_root_entry(uint8_t *fat_name) {
//before: cur_dir -> entry of dir to search
//after: cur_dir -> specified entry in dir
-bool try_locate_entry(uint8_t *fat_name) {
+bool try_locate_entry(const uint8_t *fat_name) {
uint16_t cur_dir_cluster = cur_dir->first_cluster;
load_cluster(cur_dir_cluster, fat_driver_buffer);
cur_dir = (struct directory_entry *)fat_driver_buffer;
@@ -146,32 +146,41 @@ bool try_locate_entry(uint8_t *fat_name) {
}
}
-drive_file_id_t fat_get_file(struct drive *d, char *path) {
+drive_file_id_t fat_get_file(const struct drive *d, const char *path) {
cur_drive = d;
cur_id = d->drive_id;
+ cur_fdi = &infos[cur_id];
+ const struct directory_entry *open_files = cur_fdi->open_files - 1;
for (drive_file_id_t n = 1; n != MAX_OPEN_FILES_PER_DRIVE + 1; ++n)
- if (!*(uint8_t *)(&FN(d->drive_id, n))) {
- panic("TODO: open path at FN(id, n)");
+ if (!*(uint8_t *)(&open_files[n])) {
+ panic("TODO: open path into open_files[n]");
return n;
}
panic("Maximum number of files open reached for FAT drive.");
}
-void fat_free_file(struct drive *d, drive_file_id_t fid) {
- *(uint8_t *)(&FN(d->drive_id, fid)) = 0;
+void fat_free_file(const struct drive *d, drive_file_id_t fid) {
+ *(uint8_t *)(&infos[d->drive_id].open_files[fid - 1]) = 0;
}
-void fat_load_sector(struct drive *d, drive_file_id_t fid, uint32_t sector, void *at) {
+void fat_load_sector(const struct drive *d, drive_file_id_t fid, uint32_t sector, void *at) {
cur_drive = d;
cur_id = d->drive_id;
- uint16_t c = FN(d->drive_id, fid).first_cluster;
+ cur_fdi = &infos[cur_id];
+ uint16_t c = cur_fdi->open_files[fid - 1].first_cluster;
for (uint32_t i = 0; i < sector; ++i)
c = next_cluster(c);
load_cluster(c, at);
}
-uint32_t fat_get_free_sectors(struct drive *d) {
- panic("TODO: get free sectors of drive");
+__attribute__ ((pure)) uint32_t fat_get_free_sectors(const struct drive *d) {
+ uint16_t *start = infos[d->fs_id].fat + 2;
+ uint16_t *end = start + d->n_sectors - infos[d->fs_id].data_start;
+ uint32_t count = 0;
+ for (uint16_t *i = start; i < end; ++i)
+ if (!*i)
+ ++count;
+ return count;
}
void init_fat() {
@@ -186,8 +195,8 @@ bool try_fat_init_drive(struct drive *d) {
return false;
memcpy(next_fi, fat_driver_buffer + 3, sizeof(struct fat_info));
uint32_t *fs_type_32 = (uint32_t *)next_fi->fs_type;
- if ((fs_type_32[0] != ('F' + 'A' * 256 + 'T' + 65536 + '1' * 16777216)) ||
- (fs_type_32[1] != ('6' + ' ' * 256 + ' ' + 65536 + ' ' * 16777216)))
+ if ((fs_type_32[0] != ('F' + 'A' * 256 + 'T' * 65536 + '1' * 16777216)) ||
+ (fs_type_32[1] != ('6' + ' ' * 256 + ' ' * 65536 + ' ' * 16777216)))
return false;
d->fs_type = "FAT16";
@@ -199,10 +208,15 @@ bool try_fat_init_drive(struct drive *d) {
d->fs_id = next_id;
infos[next_id].fi = next_fi;
infos[next_id].fat = allocate_pages(((next_fi->sectors_per_fat - 1) >> 3) + 1);
- for (drive_file_id_t i = 0; i < MAX_OPEN_FILES_PER_DRIVE; ++i)
- *(uint8_t *)&FN(next_id, i) = 0;
+ infos[next_id].root_start = next_fi->reserved_sectors +
+ next_fi->sectors_per_fat * next_fi->fats;
+ infos[next_id].data_start = infos[next_id].root_start +
+ ((next_fi->root_entries - 1) >> 4) + 1;
d->read_sectors(d, next_fi->reserved_sectors, next_fi->sectors_per_fat, infos[next_id].fat);
+ struct directory_entry *open_files = infos[next_id].open_files - 1;
+ for (drive_file_id_t i = 0; i < MAX_OPEN_FILES_PER_DRIVE; ++i)
+ *(uint8_t *)&open_files[i] = 0;
alloc_next_fi();
++next_id;
diff --git a/src/kernel/fat.h b/src/kernel/fat.h
index d9db906..cadb073 100644
--- a/src/kernel/fat.h
+++ b/src/kernel/fat.h
@@ -1,8 +1,8 @@
#ifndef FAT_H
#define FAT_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#include "drive.h"
void init_fat();
diff --git a/src/kernel/ide.c b/src/kernel/ide.c
index a2d3895..a32f149 100644
--- a/src/kernel/ide.c
+++ b/src/kernel/ide.c
@@ -1,171 +1,192 @@
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
+#include "drive.h"
#include "panic.h"
#include "util.h"
-#include "drive.h"
-#include "pci.h"
#include "ata.h"
+#include "pci.h"
#define MAX_IDE_DRIVES 8
struct ide_drive_info {
uint16_t base_port;
- uint16_t control_port;
+ uint16_t alt_port;
bool slave;
};
struct ide_drive_info ide_drives[MAX_IDE_DRIVES];
drive_id_t n_ide_drives = 0;
-void spin_delay() {
- for (uint32_t i = -1; i; --i)
- ;
-}
-
-//return true on error condition
-bool poll(struct ide_drive_info *info) {
- spin_delay();
-
- uint8_t status;
+typedef uint16_t spinner_t;
- while ((status = inb(info->base_port | ATA_REG_STATUS)) & ATA_STATUS_BUSY)
- ;
+//returns the status after waiting
+uint8_t wait_after_cmd(uint16_t base_port) {
+ for (spinner_t n = -1; n; --n) {
+ uint8_t s = inb(base_port | ATA_REG_STATUS);
+ if (s & ATA_STATUS_ERROR)
+ panic("Error status in IDE driver.");
+ if (!(s & ATA_STATUS_BUSY))
+ return s;
+ }
+ panic("Spun out in IDE driver.");
+}
- return (status & (ATA_STATUS_ERROR | ATA_STATUS_DRIVE_FAULT)) || !(status & ATA_STATUS_DRIVE_READY);
+//returns the status after waiting
+uint8_t wait_for_ready(uint16_t base_port) {
+ for (spinner_t n = -1; n; --n) {
+ uint8_t s = inb(base_port | ATA_REG_STATUS);
+ if (s & ATA_STATUS_ERROR)
+ panic("Error status in IDE driver.");
+ if (s & ATA_STATUS_DRIVE_READY)
+ return s;
+ }
+ panic("Spun out in IDE driver.");
}
-uint8_t ide_ata_rs(struct drive *d, uint32_t start, uint32_t count, void *buffer) {
- if (start & 0xf0000000)
- panic("IDE ATA driver only supports LBA28 addressing currently.");
+//returns the status after waiting
+uint8_t wait_for_error_or_ready(uint16_t base_port) {
+ for (spinner_t n = -1; n; --n) {
+ uint8_t s = inb(base_port | ATA_REG_STATUS);
+ if (s & (ATA_STATUS_DRIVE_READY | ATA_STATUS_ERROR))
+ return s;
+ }
+ panic("Spun out in IDE driver.");
+}
- struct ide_drive_info *info = ide_drives + d->drive_id;
+//returns the status after waiting
+uint8_t wait_for_data_ready_not_busy(uint16_t base_port) {
+ for (spinner_t n = -1; n; --n) {
+ uint8_t s = inb(base_port | ATA_REG_STATUS);
+ if (!(s & ATA_STATUS_BUSY) && (s & ATA_STATUS_DATA_READY))
+ return s;
+ if (s & ATA_STATUS_ERROR)
+ panic("Error status in IDE driver.");
+ }
+ panic("Spun out in IDE driver.");
+}
+uint8_t ide_ata_rs(const struct drive *d, uint32_t start, uint32_t count, void *buffer) {
+ if (start >= d->n_sectors)
+ return 0;
if (start + count > d->n_sectors)
count = d->n_sectors - start;
+ if (!count)
+ return 0;
+ if (start & 0xf0000000)
+ panic("IDE ATA driver does not support reads starting past 256MiB currently.");
if (count & 0xffffff00)
- panic("IDE ATA driver only supports reading up to 128k at a time currently.");
+ panic("IDE ATA driver does not support reads over 128kiB in length currently.");
uint32_t lba = start & 0x00ffffff;
- uint32_t spin = -1;
- while (inb(info->base_port | ATA_REG_STATUS) & ATA_STATUS_BUSY)
- if (!spin--)
- panic("Spun out in IDE ATA reading");
+ struct ide_drive_info *info = ide_drives + d->drive_id;
outb(info->base_port | ATA_REG_SELECT, (info->slave ? 0xf0 : 0xe0) | (start >> 24));
- outb(info->base_port | ATA_REG_COUNT_LOW, count);
+ //spin?
+
+ outb(info->base_port | ATA_REG_COUNT, count);
outb(info->base_port | ATA_REG_LBA0, lba);
outb(info->base_port | ATA_REG_LBA1, lba >> 8);
outb(info->base_port | ATA_REG_LBA2, lba >> 16);
- uint16_t *buffer_16 = buffer;
+ outb(info->base_port | ATA_REG_CMD, ATA_CMD_READ);
+
+ uint16_t *buf16 = (uint16_t *)buffer;
for (uint16_t i = 0; i < count; ++i) {
- if (poll(info))
- return i;
+ wait_for_data_ready_not_busy(info->base_port);
for (uint16_t j = 0; j < 256; ++j)
- *buffer_16++ = inw(info->base_port + ATA_REG_DATA);
+ *buf16++ = inw(info->base_port | ATA_REG_DATA);
}
return count;
}
-uint8_t ide_ata_ws(struct drive *d, uint32_t start, uint32_t count, void *buffer) {
+uint8_t ide_ata_ws(const struct drive *d, uint32_t start, uint32_t count, const void *buffer) {
panic("IDE ATA writing not implemented yet");
return 0;
}
-uint8_t ide_atapi_rs(struct drive *d, uint32_t start, uint32_t count, void *buffer) {
+uint8_t ide_atapi_rs(const struct drive *d, uint32_t start, uint32_t count, void *buffer) {
//panic("IDE ATAPI reading not implemented yet");
return 0;
}
-uint8_t ide_atapi_ws(struct drive *d, uint32_t start, uint32_t count, void *buffer) {
+uint8_t ide_atapi_ws(const struct drive *d, uint32_t start, uint32_t count, const void *buffer) {
panic("IDE ATAPI writing not implemented yet");
return 0;
}
struct id_space {
- uint16_t device_type;//0
- uint8_t skip1[98 - 2];
- uint16_t capabilities;//98
- uint8_t skip2[120 - (98 + 2)];
+ uint8_t skip1[120];
uint32_t max_lba;//120
- uint8_t skip3[164 - (120 + 4)];
- uint32_t command_sets;//164
- uint8_t skip4[200 - (164 + 4)];
- uint32_t max_lba_ext;//200
- uint8_t skip5[512 - (200 + 4)];
-} __attribute__ ((__packed__));
-
-void read_id_space(uint16_t base_port, struct id_space *to) {
- uint32_t *to_32 = (uint32_t *)to;
- for (uint8_t i = 0; i < 128; ++i)
- *(to_32++) = ind(base_port | ATA_REG_DATA);
-}
+ uint8_t skip2[512 - (120 + 4)];
+} __attribute__ ((__packed__ ));
-void test_drive(uint16_t base_port, uint16_t control_port, bool slave) {
- outb(base_port | ATA_REG_SELECT, slave ? ATA_SLAVE_SELECT : ATA_MASTER_SELECT);
- spin_delay();
+void vga_printsz(char *s);
- outb(base_port | ATA_REG_CMD, ATA_CMD_ID);
- spin_delay();
+void test_drive(uint16_t base_port, uint16_t alt_port, bool slave) {
+ if (n_ide_drives == MAX_IDE_DRIVES)
+ panic("Maximum number of IDE drives reached.");
- if (!inb(base_port | ATA_REG_STATUS))
- return;
+ struct ide_drive_info *next = ide_drives + n_ide_drives;
+ struct drive next_d;
+ next_d.drive_id = n_ide_drives;
- if (n_ide_drives == MAX_IDE_DRIVES)
- panic("Maximum IDE drives reached");
+ next->base_port = base_port;
+ next->alt_port = alt_port;
+ next->slave = slave;
- outb(base_port | ATA_REG_CONTROL, ATA_CONTROL_NO_IRQS);
+ outb(base_port | ATA_REG_SELECT, slave ? 0xb0 : 0xa0);
+ outb(base_port | ATA_REG_COUNT, 0);
+ outb(base_port | ATA_REG_LBA0, 0);
+ outb(base_port | ATA_REG_LBA1, 0);
+ outb(base_port | ATA_REG_LBA2, 0);
- struct ide_drive_info *this_drive = ide_drives + n_ide_drives;
- this_drive->base_port = base_port;
- this_drive->control_port = control_port;
- this_drive->slave = slave;
+ outb(base_port | ATA_REG_CMD, ATA_CMD_ID);
- struct drive data;
- data.drive_id = n_ide_drives;
+ if (!inb(base_port | ATA_REG_STATUS))
+ return;
- uint32_t spin_out = -1;
- while (1) {//wait for identify to complete
- uint8_t status = inb(base_port | ATA_REG_STATUS);
- if (status & ATA_STATUS_ERROR) {
- uint16_t type = inb(base_port | ATA_REG_LBA1) +
- (inb(base_port | ATA_REG_LBA2) << 8);
+ struct id_space ids;
- //These two are listed on OSDev Wiki
- // as being ATAPI device types.
- if ((type != 0xeb14) && (type != 0x9669))
- return;
+ if (!(wait_for_error_or_ready(base_port) & ATA_STATUS_ERROR)) {
+ wait_for_ready(base_port);
+ for (uint16_t *ids_16 = (uint16_t *)&ids; ids_16 < (uint16_t *)&ids + 256; ++ids_16)
+ *ids_16 = inw(base_port | ATA_REG_DATA);
- outb(base_port | ATA_REG_CMD, ATAPI_CMD_ID);
+ next_d.drive_type = "IDE PATA";
+ next_d.read_sectors = &ide_ata_rs;
+ next_d.write_sectors = &ide_ata_ws;
+ }
+ else {
+ uint16_t code = inb(base_port | 0x4) + (inb(base_port | 0x5) << 8);
+ if (!code) {
+ panic("PATA identification aborted.");
+ }
+ if (code == 0xeb14) {
+ next_d.drive_type = "IDE PATAPI";
+ next_d.read_sectors = &ide_atapi_rs;
+ next_d.write_sectors = &ide_atapi_ws;
- data.read_sectors = &ide_atapi_rs;
- data.write_sectors = &ide_atapi_ws;
- data.drive_type = "IDE ATAPI";
- break;
+ //TODO: issue proper identify command
+ ids.max_lba = -1;
}
- if (!(status & ATA_STATUS_BUSY) && (status & ATA_STATUS_DATA_READY)) {
- data.read_sectors = &ide_ata_rs;
- data.write_sectors = &ide_ata_ws;
- data.drive_type = "IDE ATA";
- break;
+ else if (code == 0xc33c) {
+ next_d.drive_type = "IDE SATA";
+
+ //TODO: set up drive hooks, issue proper identify command
+ return;
}
- if (!spin_out--)
- panic("IDE ATA identify won't complete");
}
- struct id_space id;
- read_id_space(base_port, &id);
-
- if (!(id.capabilities & ATA_CAP_LBA))
- //TODO: CHS compability driver?
- return;
- data.n_sectors = (id.command_sets & ATA_SET_EXT) ? id.max_lba_ext : id.max_lba;
+ //in the future, maybe add support for 48-bit LBA, and/or CHS addressing
+ if (!ids.max_lba)
+ panic("Encountered ATA drive that doesn't support 28-bit LBA");
+ next_d.n_sectors = ids.max_lba;
- commit_drive(data);
+ commit_drive(next_d);
++n_ide_drives;
}
@@ -176,14 +197,9 @@ void init_ide() {
while ((device = find_pci_device_from_class_and_subclass(PCI_MASS_STORAGE, PCI_IDE, check_from, &check_from))) {
++check_from;
- uint16_t primary_base_port = device->bar0 <= 1 ? 0x01f0 : device->bar0;
- uint16_t primary_control_port = device->bar1 <= 1 ? 0x03f6 : device->bar1;
- uint16_t secondary_base_port = device->bar2 <= 1 ? 0x0170 : device->bar2;
- uint16_t secondary_control_port = device->bar3 <= 1 ? 0x0376 : device->bar3;
-
- test_drive(primary_base_port, primary_control_port, false);
- test_drive(primary_base_port, primary_control_port, true);
- test_drive(secondary_base_port, secondary_control_port, false);
- test_drive(secondary_base_port, secondary_control_port, true);
+ test_drive(0x01f0, 0x03f6, false);
+ test_drive(0x01f0, 0x03f6, true);
+ test_drive(0x0170, 0x0376, false);
+ test_drive(0x0170, 0x0376, true);
}
} \ No newline at end of file
diff --git a/src/kernel/ide.h b/src/kernel/ide.h
index 44b02ec..47bcc49 100644
--- a/src/kernel/ide.h
+++ b/src/kernel/ide.h
@@ -1,12 +1,6 @@
#ifndef IDE_H
#define IDE_H
-#include <stdint.h>
-#include "drive.h"
-
void init_ide();
-uint8_t ide_read_sectors(drive_id_t id, uint32_t start, uint32_t count, void *buffer);
-uint8_t ide_write_sectors(drive_id_t id, uint32_t start, uint32_t count, void *buffer);
-
#endif \ No newline at end of file
diff --git a/src/kernel/main.c b/src/kernel/main.c
index e5c0013..cbdebfa 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -1,30 +1,20 @@
#include <stdint.h>
-#include "vga.h"
-#include "fat.h"
-#include "ide.h"
-#include "panic.h"
#include "serial.h"
+#include "panic.h"
+#include "boot.h"
#include "util.h"
+#include "vesa.h"
+#include "fat.h"
+#include "ide.h"
#include "mem.h"
#include "pci.h"
-#include "boot.h"
-#include "vesa.h"
-
-char nbuf[11];
-
-#define SOTL(field) field = (void *)((*((uint16_t *)(&field) + 1) << 16) + *(uint16_t *)(&field));
+#include "vga.h"
__attribute__ ((noreturn)) void main() {
- SOTL(VESA_INFO->oem)
- SOTL(VESA_INFO->modes)
- SOTL(VESA_INFO->vendor)
- SOTL(VESA_INFO->pname)
- SOTL(VESA_INFO->prev)
+ char nbuf[11];
init_mmap();
-
init_vesa();
-
init_serial();
vga_blank();
@@ -64,8 +54,10 @@ __attribute__ ((noreturn)) void main() {
vga_printch('\n');
init_fat();
+ //other fs drivers
init_ide();
+ //other drive drivers
u8_dec(n_drives, nbuf);
vga_printsz(nbuf);
@@ -79,24 +71,27 @@ __attribute__ ((noreturn)) void main() {
vga_printsz(nbuf);
vga_printsz(" (");
vga_printsz(d->drive_type);
- vga_printsz("): ");
-
- vga_printsz(d->fs_type);
vga_printsz(", ");
u32_dec(d->n_sectors / 2, nbuf);
vga_printsz(nbuf);
if (d->n_sectors % 2)
vga_printsz(".5");
- vga_printsz("k, ");
+ vga_printsz("k): ");
- uint32_t free_sectors = d->get_free_sectors(d);
+ vga_printsz(d->fs_type);
- u32_dec(free_sectors / 2, nbuf);
- vga_printsz(nbuf);
- if (d->n_sectors % 2)
- vga_printsz(".5");
- vga_printsz("k free.\n");
+ uint32_t free_sectors = d->get_free_sectors(d);
+ if (free_sectors != -1) {
+ u32_dec(free_sectors / 2, nbuf);
+ vga_printsz(", ");
+ vga_printsz(nbuf);
+ if (free_sectors % 2)
+ vga_printsz(".5");
+ vga_printsz("k free");
+ }
+
+ vga_printsz(".\n");
}
vga_printch('\n');
diff --git a/src/kernel/mem.c b/src/kernel/mem.c
index 2e8173d..d3baad3 100644
--- a/src/kernel/mem.c
+++ b/src/kernel/mem.c
@@ -1,6 +1,6 @@
#include <stdint.h>
-#include <stdbool.h>
#include "panic.h"
+#include "mem.h"
#define DYNAMIC_START (0x10000000)
#define DYNAMIC_END (DYNAMIC_START + 65536 * 4096)
@@ -55,7 +55,7 @@ void *allocate_pages(uint16_t n) {
}
//in the future, change this to go by bytes or dwords instead of bits.
-void free_pages(void *ptr, uint16_t n) {
+void free_pages(const void *ptr, uint16_t n) {
uint16_t page = ADDR_TO_PAGE(ptr);
for (uint32_t i = page; i < page + n; ++i)
CLEAR_PAGE(i);
diff --git a/src/kernel/mem.h b/src/kernel/mem.h
index 913f70b..9a9ae79 100644
--- a/src/kernel/mem.h
+++ b/src/kernel/mem.h
@@ -7,7 +7,7 @@ extern uint16_t pages_left;
void init_mmap();
-void *allocate_pages(uint16_t n);
-void free_pages(void *ptr, uint16_t n);
+void *allocate_pages(uint16_t n) __attribute__ ((malloc));
+void free_pages(const void *ptr, uint16_t n);
#endif \ No newline at end of file
diff --git a/src/kernel/panic.c b/src/kernel/panic.c
index 93944ff..e04ae38 100644
--- a/src/kernel/panic.c
+++ b/src/kernel/panic.c
@@ -1,10 +1,7 @@
-#include <stdint.h>
-#include "vga.h"
-#include "serial.h"
-#include "util.h"
#include "panic.h"
+#include "vga.h"
-void panic(char *message) {
+void panic(const char *message) {
vga_set_color(0x4f);
vga_blank();
vga_printsz("Kernel panic: ");
diff --git a/src/kernel/panic.h b/src/kernel/panic.h
index 7d2e9df..08328f2 100644
--- a/src/kernel/panic.h
+++ b/src/kernel/panic.h
@@ -1,8 +1,6 @@
#ifndef PANIC_H
#define PANIC_H
-#include <stdint.h>
-
-void panic(char *message) __attribute__ ((noreturn));
+void panic(const char *message) __attribute__ ((noreturn));
#endif \ No newline at end of file
diff --git a/src/kernel/pci.c b/src/kernel/pci.c
index fe96c4c..5d8170d 100644
--- a/src/kernel/pci.c
+++ b/src/kernel/pci.c
@@ -1,8 +1,8 @@
+#include "panic.h"
#include "boot.h"
-#include "mem.h"
#include "util.h"
+#include "mem.h"
#include "pci.h"
-#include "panic.h"
enum {
PCP_SELECT = 0x0cf8,
@@ -59,11 +59,6 @@ void pci_device_check(uint16_t number) {
next_device->class = class >> 24;
next_device->subclass = class >> 16;
next_device->iface = class >> 8;
-
- next_device->bar0 = pci_read_config(number, 4);
- next_device->bar1 = pci_read_config(number, 5);
- next_device->bar2 = pci_read_config(number, 6);
- next_device->bar3 = pci_read_config(number, 7);
}
void pci_init() {
diff --git a/src/kernel/pci.h b/src/kernel/pci.h
index 1ab5936..8ff9f45 100644
--- a/src/kernel/pci.h
+++ b/src/kernel/pci.h
@@ -20,16 +20,10 @@ struct pci_device {
uint8_t class;
uint8_t subclass;
uint8_t iface;
-
- uint32_t bar0;
- uint32_t bar1;
- uint32_t bar2;
- uint32_t bar3;
- //etc
};
extern uint16_t n_pci_devices;
-struct pci_device *nth_pci_device(uint16_t n);
+struct pci_device *nth_pci_device(uint16_t n) __attribute__ ((pure));
struct pci_device *find_pci_device_from_class_and_subclass(uint8_t class, uint8_t subclass, uint16_t start, uint16_t *index);
diff --git a/src/kernel/plef.c b/src/kernel/plef.c
index 2cba843..710943f 100644
--- a/src/kernel/plef.c
+++ b/src/kernel/plef.c
@@ -1,13 +1,12 @@
#include <stdint.h>
-#include <stdbool.h>
-#include "plef.h"
#include "drive.h"
-#include "util.h"
+#include "plef.h"
#include "task.h"
+#include "util.h"
#define PLEF_MAGIC 0xb9ba4c50
-task_handle plef_run(struct drive *d, char *path) {
+task_handle plef_run(const struct drive *d, const char *path) {
drive_file_id_t h = d->get_file(d, path);
if (!h)
return 0;
diff --git a/src/kernel/plef.h b/src/kernel/plef.h
index 29100ee..a14ea9b 100644
--- a/src/kernel/plef.h
+++ b/src/kernel/plef.h
@@ -2,7 +2,6 @@
#define PLEF_H
#include <stdint.h>
-#include <stdbool.h>
#include "drive.h"
typedef uint8_t task_handle;
@@ -17,6 +16,6 @@ struct plef_header {
uint32_t entry_point;
} __attribute__ ((packed));
-task_handle plef_run(struct drive *d, char *path);
+task_handle plef_run(const struct drive *d, const char *path);
#endif \ No newline at end of file
diff --git a/src/kernel/serial.c b/src/kernel/serial.c
index 0f7abe6..c92f173 100644
--- a/src/kernel/serial.c
+++ b/src/kernel/serial.c
@@ -1,5 +1,6 @@
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
+#include "serial.h"
#include "util.h"
enum {
@@ -76,12 +77,12 @@ void sout(char b) {
outb(CP_1 | CP_DATA, (uint8_t)b);
}
-void soutsz(char *s) {
+void soutsz(const char *s) {
while (*s)
sout(*(s++));
}
-void soutsn(char *s, uint8_t n) {
+void soutsn(const char *s, uint8_t n) {
while (n--)
sout(*(s++));
}
diff --git a/src/kernel/serial.h b/src/kernel/serial.h
index bb12edb..2fb21a6 100644
--- a/src/kernel/serial.h
+++ b/src/kernel/serial.h
@@ -1,14 +1,14 @@
#ifndef SERIAL_H
#define SERIAL_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
-bool serr();
+bool serr() __attribute__ ((pure));
void init_serial();
void sout(char b);
-void soutsz(char *s);
-void soutsn(char *s, uint8_t n);
+void soutsz(const char *s);
+void soutsn(const char *s, uint8_t n);
char sin();
void sinsn(char *s, uint8_t n);
diff --git a/src/kernel/task.c b/src/kernel/task.c
index c08a195..3e64639 100644
--- a/src/kernel/task.c
+++ b/src/kernel/task.c
@@ -1,5 +1,5 @@
-#include "task.h"
#include "panic.h"
+#include "task.h"
segment_id new_segment(bool is_code, uint32_t length, uint32_t *location_out) {
panic("TODO: make new segment");
diff --git a/src/kernel/task.h b/src/kernel/task.h
index add668b..c3f2acd 100644
--- a/src/kernel/task.h
+++ b/src/kernel/task.h
@@ -1,8 +1,8 @@
#ifndef TASK_H
#define TASK_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
typedef uint8_t segment_id;
typedef uint8_t task_handle;
diff --git a/src/kernel/util.c b/src/kernel/util.c
index 1531f83..29d7e3f 100644
--- a/src/kernel/util.c
+++ b/src/kernel/util.c
@@ -1,10 +1,10 @@
-#include <stdint.h>
-#include "panic.h"
#include <stdbool.h>
+#include <stdint.h>
#include "drive.h"
-void memcpy(void *to, void *from, uint32_t n) {
- uint32_t *tp = to, *fp = from;
+void memcpy(void *to, const void *from, uint32_t n) {
+ uint32_t *tp = to;
+ const uint32_t *fp = from;
while (n >= 4) {
*(tp++) = *(fp++);
n -= 4;
@@ -14,7 +14,7 @@ void memcpy(void *to, void *from, uint32_t n) {
*(tpp++) = *(fpp++);
}
-void fmcpy(void *to, struct drive *d, drive_file_id_t f, uint32_t from, uint32_t n) {
+void fmcpy(void *to, const struct drive *d, drive_file_id_t f, uint32_t from, uint32_t n) {
uint8_t buf[512];
d->load_sector(d, f, from >> 9, buf);
uint16_t from_low = from & 511;
diff --git a/src/kernel/util.h b/src/kernel/util.h
index 243541c..324f379 100644
--- a/src/kernel/util.h
+++ b/src/kernel/util.h
@@ -10,8 +10,8 @@ static inline void outb(uint16_t port, uint8_t value) {
: : "a"(value), "Nd"(port));
}
static inline uint8_t inb(uint16_t port) {
- uint8_t value;
- asm volatile (
+ volatile uint8_t value;
+ asm (
"inb %1, %0"
: "=a"(value) : "Nd"(port));
return value;
@@ -22,8 +22,8 @@ static inline void outw(uint16_t port, uint16_t value) {
: : "a"(value), "Nd"(port));
}
static inline uint16_t inw(uint16_t port) {
- uint16_t value;
- asm volatile (
+ volatile uint16_t value;
+ asm (
"inw %1, %0"
: "=a"(value) : "Nd"(port));
return value;
@@ -34,15 +34,15 @@ static inline void outd(uint16_t port, uint32_t value) {
: : "a"(value), "Nd"(port));
}
static inline uint32_t ind(uint16_t port) {
- uint32_t value;
- asm volatile (
+ volatile uint32_t value;
+ asm (
"inl %1, %0"
: "=a"(value) : "Nd"(port));
return value;
}
-void memcpy(void *to, void *from, uint32_t n);
-void fmcpy(void *to, struct drive *d, drive_file_id_t f, uint32_t from, uint32_t n);
+void memcpy(void *to, const void *from, uint32_t n);
+void fmcpy(void *to, const struct drive *d, drive_file_id_t f, uint32_t from, uint32_t n);
void u32_dec(uint32_t n, char *b);
void u16_dec(uint16_t n, char *b);
diff --git a/src/kernel/vesa.c b/src/kernel/vesa.c
index e781249..4cdabb2 100644
--- a/src/kernel/vesa.c
+++ b/src/kernel/vesa.c
@@ -1,5 +1,21 @@
#include "vesa.h"
+uint16_t screen_width;
+uint16_t screen_height;
+uint8_t bpp;
+
+void *frame_buffer;
+
+void put_pixel(uint16_t x, uint16_t y, color c) {
+
+}
+
+void screen_fill(color c) {
+
+}
+
void init_vesa() {
-
+// for (void *v = 0; v < 0x65536; ++v) {
+// if (*(uint32_t *)v == 'P' + 'M' * 256 + 'I' * 65536 + 'D' * 16777216)
+// }
} \ No newline at end of file
diff --git a/src/kernel/vesa.h b/src/kernel/vesa.h
index 495b593..b2f17c8 100644
--- a/src/kernel/vesa.h
+++ b/src/kernel/vesa.h
@@ -1,23 +1,16 @@
#ifndef VESA_H
#define VESA_H
-struct video_mode {
- //TODO
-};
+#include <stdint.h>
-#define VESA_INFO \
- ((struct { \
- uint32_t sig; \
- uint16_t vbe_ver; \
- char *oem; \
- uint32_t capabilities; \
- struct video_mode *modes; \
- uint16_t vram_size_high; \
- uint16_t soft_ver; \
- char *vendor; \
- char *pname; \
- char *prev; \
- } *)0x4200)
+extern uint16_t screen_width;
+extern uint16_t screen_height;
+extern uint8_t bpp;
+
+typedef uint32_t color;
+
+void put_pixel(uint16_t x, uint16_t y, color c);
+void screen_fill(color c);
void init_vesa();
diff --git a/src/kernel/vga.c b/src/kernel/vga.c
index 788ce6c..e103732 100644
--- a/src/kernel/vga.c
+++ b/src/kernel/vga.c
@@ -1,5 +1,5 @@
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#define VGA_COM_MIRROR
@@ -50,12 +50,12 @@ void vga_printch(char ch) {
vga_scroll();
}
-void vga_printsz(char *sz) {
+void vga_printsz(const char *sz) {
while (*sz)
vga_printch(*(sz++));
}
-void vga_printsn(char *sn, uint8_t n) {
+void vga_printsn(const char *sn, uint8_t n) {
while (n--)
vga_printch(*(sn++));
} \ No newline at end of file
diff --git a/src/kernel/vga.h b/src/kernel/vga.h
index 1be2131..e88ddfe 100644
--- a/src/kernel/vga.h
+++ b/src/kernel/vga.h
@@ -7,7 +7,7 @@ void vga_set_color(uint8_t color);
void vga_blank();
void vga_scroll();
void vga_printch(char ch);
-void vga_printsz(char *sz);
-void vga_printsn(char *sn, uint8_t n);
+void vga_printsz(const char *sz);
+void vga_printsn(const char *sn, uint8_t n);
#endif \ No newline at end of file