We can now read from the disk in protected mode
This commit is contained in:
parent
b2e2cdb19b
commit
ec314d7b1b
2
Makefile
2
Makefile
@ -2,7 +2,7 @@ CFLAGS = -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exceptions -fno-le
|
|||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
|
||||||
DISK_IMG_FILES = kernel.bin hello.bin print.bin boot32.bin kernel32.bin
|
DISK_IMG_FILES = kernel.bin hello.bin print.bin boot32.bin kernel32.bin
|
||||||
KERNEL32_OBJS = screenstuff.o io.o idt.o keyboard.o strings.o kernel32_strap.o kernel32.o
|
KERNEL32_OBJS = screenstuff.o io.o idt.o keyboard.o strings.o atapio.o kernel32_strap.o kernel32.o
|
||||||
|
|
||||||
run: disk.img
|
run: disk.img
|
||||||
qemu-system-x86_64 disk.img
|
qemu-system-x86_64 disk.img
|
||||||
|
122
atapio.c
Normal file
122
atapio.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "atapio.h"
|
||||||
|
|
||||||
|
// Disk code
|
||||||
|
|
||||||
|
// Primary ATA Bus: 0x1f0 to 0x1f7
|
||||||
|
// Device Control Register: 0x3f6
|
||||||
|
// Secondary ATA Bus: 0x170 to 0x177
|
||||||
|
// Device Control Register: 0x376
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t identify_result[256];
|
||||||
|
uint32_t total_28_lbas = 0;
|
||||||
|
|
||||||
|
uint8_t* rootDirEntries = 0x1000000;
|
||||||
|
uint16_t* FAT1 = 0x1002000;
|
||||||
|
|
||||||
|
uint16_t countReserved;
|
||||||
|
uint8_t countFATs;
|
||||||
|
uint16_t countRDEs;
|
||||||
|
uint16_t sectorsPerFAT;
|
||||||
|
|
||||||
|
|
||||||
|
void init_atapio() {
|
||||||
|
countReserved = *(uint16_t*)0x7c0e;
|
||||||
|
countFATs = *(uint8_t*)0x7c10;
|
||||||
|
countRDEs = *(uint16_t*)0x7c11;
|
||||||
|
sectorsPerFAT = *(uint16_t*)0x7c16;
|
||||||
|
|
||||||
|
// Select Drive 0 on the Primary Bus
|
||||||
|
outb(0x1f6, 0xa0);
|
||||||
|
|
||||||
|
// Set sector count to 0 for IDENTIFY
|
||||||
|
outb(0x1f2, 0);
|
||||||
|
// Set LBAlo to 0
|
||||||
|
outb(0x1f3, 0);
|
||||||
|
// Set LBAmid to 0
|
||||||
|
outb(0x1f4, 0);
|
||||||
|
// Set LBAhi to 0
|
||||||
|
outb(0x1f5, 0);
|
||||||
|
|
||||||
|
// Send IDENTIFY command
|
||||||
|
outb(0x1f7, 0xec);
|
||||||
|
|
||||||
|
uint8_t status = inb(0x1f7);
|
||||||
|
if (status) {
|
||||||
|
while ((status = inb(0x1f7)) & 0x80);
|
||||||
|
|
||||||
|
if ( !(inb(0x1f4) || inb(0x1f5)) ) {
|
||||||
|
while ( !(status & 8 || status & 1) )
|
||||||
|
status = inb(0x1f7);
|
||||||
|
|
||||||
|
if (!(status & 1)) {
|
||||||
|
for (int index=0; index<256; index++)
|
||||||
|
identify_result[index] = inw(0x1f0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
total_28_lbas = *(uint32_t*)(identify_result+60);
|
||||||
|
|
||||||
|
// We've initialised now, let's load the FAT and RootDirEntries.
|
||||||
|
read_sectors(sectorsPerFAT * countFATs + 1, countRDEs / 16, rootDirEntries);
|
||||||
|
read_sectors(1, sectorsPerFAT, FAT1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_sector(uint32_t address, uint8_t* buffer) {
|
||||||
|
outb(0x1f6, 0xe0 | ((address>>24)&0x0f));
|
||||||
|
// Read a single sector
|
||||||
|
outb(0x1f2, 1);
|
||||||
|
// Set LBAlo, LBAmid and LBAhi
|
||||||
|
outb(0x1f3, address);
|
||||||
|
outb(0x1f4, address>>8);
|
||||||
|
outb(0x1f5, address>>16);
|
||||||
|
|
||||||
|
// Send read command
|
||||||
|
outb(0x1f7, 0x20);
|
||||||
|
// Poll
|
||||||
|
uint8_t status = inb(0x1f7);
|
||||||
|
while ( (status & 0x80) && !(status & 8) )
|
||||||
|
status = inb(0x1f7);
|
||||||
|
|
||||||
|
for (int index=0; index<256; index++)
|
||||||
|
((uint16_t*)buffer)[index] = inw(0x1f0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_sectors(uint32_t address, int count, uint8_t* buffer) {
|
||||||
|
for (int i=0; i<count; i++) {
|
||||||
|
read_sector(address+i, buffer+512*i);
|
||||||
|
for (int i=0; i<15; i++)
|
||||||
|
inb(0x1f7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t file_exists(char* filename) {
|
||||||
|
for (int i=0; i<countRDEs; i++) {
|
||||||
|
bool found = strcmp(rootDirEntries+(i*32), filename, 11);
|
||||||
|
if (found) {
|
||||||
|
uint16_t* correctEntry = (rootDirEntries+(i*32));
|
||||||
|
return correctEntry[13];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_file(char* filename, uint8_t* destination) {
|
||||||
|
uint16_t location = file_exists(filename);
|
||||||
|
if (!location)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
bool loaded = false;
|
||||||
|
while (!loaded) {
|
||||||
|
uint16_t fromSector = location + (sectorsPerFAT * countFATs) + (countRDEs / 16) - 1;
|
||||||
|
read_sector(fromSector, destination+offset);
|
||||||
|
offset += 512;
|
||||||
|
|
||||||
|
location = FAT1[location++];
|
||||||
|
if (location == 0xffff)
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
}
|
17
atapio.h
Normal file
17
atapio.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef ATA_PIO
|
||||||
|
#define ATA_PIO
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "io.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "strings.h"
|
||||||
|
#include "screenstuff.h"
|
||||||
|
|
||||||
|
void init_atapio();
|
||||||
|
void read_sector(uint32_t address, uint8_t* buffer);
|
||||||
|
void read_sectors(uint32_t address, int count, uint8_t* buffer);
|
||||||
|
uint16_t file_exists(char* filename);
|
||||||
|
void load_file(char* filename, uint8_t* location);
|
||||||
|
|
||||||
|
#endif
|
24
kernel32.c
24
kernel32.c
@ -3,8 +3,8 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
|
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
|
#include "atapio.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
init_idt();
|
init_idt();
|
||||||
@ -16,6 +16,18 @@ int main() {
|
|||||||
|
|
||||||
init_keyboard();
|
init_keyboard();
|
||||||
enable_idt();
|
enable_idt();
|
||||||
|
init_atapio();
|
||||||
|
|
||||||
|
uint8_t sector[512];
|
||||||
|
|
||||||
|
read_sector(0, sector);
|
||||||
|
|
||||||
|
printf("OEM ID: %s\n", (char*)(sector+0x3));
|
||||||
|
|
||||||
|
char hellotxt[1024];
|
||||||
|
|
||||||
|
load_file("HELLO TXT", hellotxt);
|
||||||
|
printf("%s", hellotxt);
|
||||||
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -32,12 +44,12 @@ int main() {
|
|||||||
printf(
|
printf(
|
||||||
"XnoeOS 32 Bit Mode Help.\n"
|
"XnoeOS 32 Bit Mode Help.\n"
|
||||||
"------------------------\n"
|
"------------------------\n"
|
||||||
"- help\n"
|
" - help\n"
|
||||||
": Shows this message\n"
|
" : Shows this message\n"
|
||||||
"- clear\n"
|
" - clear\n"
|
||||||
": Clears the screen\n"
|
" : Clears the screen\n"
|
||||||
" - echo\n"
|
" - echo\n"
|
||||||
": Repeats the text written afterwards\n"
|
" : Repeats the text written afterwards\n"
|
||||||
);
|
);
|
||||||
} else if (strcmp(buffer, "clear", 5)) {
|
} else if (strcmp(buffer, "clear", 5)) {
|
||||||
clear_screen();
|
clear_screen();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user