Functioning bootloader
This commit is contained in:
parent
2e3279350e
commit
c73c832ade
2
Makefile
2
Makefile
@ -6,7 +6,7 @@ KLD = $(KERNEL_TARGET)-ld
|
|||||||
all: image.iso
|
all: image.iso
|
||||||
|
|
||||||
image.iso: stuff/boot/boot.sys
|
image.iso: stuff/boot/boot.sys
|
||||||
xorriso -as mkisofs -R -J -c boot/bootcat -b boot/boot.sys -no-emul-boot -boot-load-size 4 -o image.iso stuff
|
xorriso -as mkisofs -R -J -c boot/bootcat -b boot/boot.sys -no-emul-boot -boot-load-size 16 -o image.iso stuff
|
||||||
|
|
||||||
cstuff.o: cstuff.c
|
cstuff.o: cstuff.c
|
||||||
${KCC} -c -Os -o cstuff.o cstuff.c
|
${KCC} -c -Os -o cstuff.o cstuff.c
|
||||||
|
154
ata.h
Normal file
154
ata.h
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
|
*
|
||||||
|
* Values for ATA / PATA devices
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ATA_SR_BSY 0x80
|
||||||
|
#define ATA_SR_DRDY 0x40
|
||||||
|
#define ATA_SR_DF 0x20
|
||||||
|
#define ATA_SR_DSC 0x10
|
||||||
|
#define ATA_SR_DRQ 0x08
|
||||||
|
#define ATA_SR_CORR 0x04
|
||||||
|
#define ATA_SR_IDX 0x02
|
||||||
|
#define ATA_SR_ERR 0x01
|
||||||
|
|
||||||
|
#define ATA_ER_BBK 0x80
|
||||||
|
#define ATA_ER_UNC 0x40
|
||||||
|
#define ATA_ER_MC 0x20
|
||||||
|
#define ATA_ER_IDNF 0x10
|
||||||
|
#define ATA_ER_MCR 0x08
|
||||||
|
#define ATA_ER_ABRT 0x04
|
||||||
|
#define ATA_ER_TK0NF 0x02
|
||||||
|
#define ATA_ER_AMNF 0x01
|
||||||
|
|
||||||
|
#define ATA_CMD_READ_PIO 0x20
|
||||||
|
#define ATA_CMD_READ_PIO_EXT 0x24
|
||||||
|
#define ATA_CMD_READ_DMA 0xC8
|
||||||
|
#define ATA_CMD_READ_DMA_EXT 0x25
|
||||||
|
#define ATA_CMD_WRITE_PIO 0x30
|
||||||
|
#define ATA_CMD_WRITE_PIO_EXT 0x34
|
||||||
|
#define ATA_CMD_WRITE_DMA 0xCA
|
||||||
|
#define ATA_CMD_WRITE_DMA_EXT 0x35
|
||||||
|
#define ATA_CMD_CACHE_FLUSH 0xE7
|
||||||
|
#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
|
||||||
|
#define ATA_CMD_PACKET 0xA0
|
||||||
|
#define ATA_CMD_IDENTIFY_PACKET 0xA1
|
||||||
|
#define ATA_CMD_IDENTIFY 0xEC
|
||||||
|
|
||||||
|
#define ATAPI_CMD_READ 0xA8
|
||||||
|
#define ATAPI_CMD_EJECT 0x1B
|
||||||
|
|
||||||
|
#define ATA_IDENT_DEVICETYPE 0
|
||||||
|
#define ATA_IDENT_CYLINDERS 2
|
||||||
|
#define ATA_IDENT_HEADS 6
|
||||||
|
#define ATA_IDENT_SECTORS 12
|
||||||
|
#define ATA_IDENT_SERIAL 20
|
||||||
|
#define ATA_IDENT_MODEL 54
|
||||||
|
#define ATA_IDENT_CAPABILITIES 98
|
||||||
|
#define ATA_IDENT_FIELDVALID 106
|
||||||
|
#define ATA_IDENT_MAX_LBA 120
|
||||||
|
#define ATA_IDENT_COMMANDSETS 164
|
||||||
|
#define ATA_IDENT_MAX_LBA_EXT 200
|
||||||
|
|
||||||
|
#define IDE_ATA 0x00
|
||||||
|
#define IDE_ATAPI 0x01
|
||||||
|
|
||||||
|
#define ATA_MASTER 0x00
|
||||||
|
#define ATA_SLAVE 0x01
|
||||||
|
|
||||||
|
#define ATA_REG_DATA 0x00
|
||||||
|
#define ATA_REG_ERROR 0x01
|
||||||
|
#define ATA_REG_FEATURES 0x01
|
||||||
|
#define ATA_REG_SECCOUNT0 0x02
|
||||||
|
#define ATA_REG_LBA0 0x03
|
||||||
|
#define ATA_REG_LBA1 0x04
|
||||||
|
#define ATA_REG_LBA2 0x05
|
||||||
|
#define ATA_REG_HDDEVSEL 0x06
|
||||||
|
#define ATA_REG_COMMAND 0x07
|
||||||
|
#define ATA_REG_STATUS 0x07
|
||||||
|
#define ATA_REG_SECCOUNT1 0x08
|
||||||
|
#define ATA_REG_LBA3 0x09
|
||||||
|
#define ATA_REG_LBA4 0x0A
|
||||||
|
#define ATA_REG_LBA5 0x0B
|
||||||
|
#define ATA_REG_CONTROL 0x0C
|
||||||
|
#define ATA_REG_ALTSTATUS 0x0C
|
||||||
|
#define ATA_REG_DEVADDRESS 0x0D
|
||||||
|
|
||||||
|
// Channels:
|
||||||
|
#define ATA_PRIMARY 0x00
|
||||||
|
#define ATA_SECONDARY 0x01
|
||||||
|
|
||||||
|
// Directions:
|
||||||
|
#define ATA_READ 0x00
|
||||||
|
#define ATA_WRITE 0x01
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t base;
|
||||||
|
uint16_t ctrl;
|
||||||
|
uint16_t bmide;
|
||||||
|
uint16_t nien;
|
||||||
|
} ide_channel_regs_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t reserved;
|
||||||
|
uint8_t channel;
|
||||||
|
uint8_t drive;
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t signature;
|
||||||
|
uint16_t capabilities;
|
||||||
|
uint32_t command_sets;
|
||||||
|
uint32_t size;
|
||||||
|
uint8_t model[41];
|
||||||
|
} ide_device_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t status;
|
||||||
|
uint8_t chs_first_sector[3];
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t chs_last_sector[3];
|
||||||
|
uint32_t lba_first_sector;
|
||||||
|
uint32_t sector_count;
|
||||||
|
} partition_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t flags;
|
||||||
|
uint16_t unused1[9];
|
||||||
|
char serial[20];
|
||||||
|
uint16_t unused2[3];
|
||||||
|
char firmware[8];
|
||||||
|
char model[40];
|
||||||
|
uint16_t sectors_per_int;
|
||||||
|
uint16_t unused3;
|
||||||
|
uint16_t capabilities[2];
|
||||||
|
uint16_t unused4[2];
|
||||||
|
uint16_t valid_ext_data;
|
||||||
|
uint16_t unused5[5];
|
||||||
|
uint16_t size_of_rw_mult;
|
||||||
|
uint32_t sectors_28;
|
||||||
|
uint16_t unused6[38];
|
||||||
|
uint64_t sectors_48;
|
||||||
|
uint16_t unused7[152];
|
||||||
|
} __attribute__((packed)) ata_identify_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t boostrap[446];
|
||||||
|
partition_t partitions[4];
|
||||||
|
uint8_t signature[2];
|
||||||
|
} __attribute__((packed)) mbr_t;
|
||||||
|
|
||||||
|
struct ata_device {
|
||||||
|
int io_base;
|
||||||
|
int control;
|
||||||
|
int slave;
|
||||||
|
int is_atapi;
|
||||||
|
ata_identify_t identity;
|
||||||
|
unsigned int atapi_lba;
|
||||||
|
unsigned int atapi_sector_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
uint8_t command_bytes[12];
|
||||||
|
uint16_t command_words[6];
|
||||||
|
} atapi_command_t;
|
223
atapi_imp.h
Normal file
223
atapi_imp.h
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
static struct ata_device ata_primary_master = {.io_base = 0x1F0, .control = 0x3F6, .slave = 0};
|
||||||
|
static struct ata_device ata_primary_slave = {.io_base = 0x1F0, .control = 0x3F6, .slave = 1};
|
||||||
|
static struct ata_device ata_secondary_master = {.io_base = 0x170, .control = 0x376, .slave = 0};
|
||||||
|
static struct ata_device ata_secondary_slave = {.io_base = 0x170, .control = 0x376, .slave = 1};
|
||||||
|
|
||||||
|
static void ata_io_wait(struct ata_device * dev) {
|
||||||
|
inportb(dev->io_base + ATA_REG_ALTSTATUS);
|
||||||
|
inportb(dev->io_base + ATA_REG_ALTSTATUS);
|
||||||
|
inportb(dev->io_base + ATA_REG_ALTSTATUS);
|
||||||
|
inportb(dev->io_base + ATA_REG_ALTSTATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ata_status_wait(struct ata_device * dev, int timeout) {
|
||||||
|
int status;
|
||||||
|
if (timeout > 0) {
|
||||||
|
int i = 0;
|
||||||
|
while ((status = inportb(dev->io_base + ATA_REG_STATUS)) & ATA_SR_BSY && (i < timeout)) i++;
|
||||||
|
} else {
|
||||||
|
while ((status = inportb(dev->io_base + ATA_REG_STATUS)) & ATA_SR_BSY);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ata_soft_reset(struct ata_device * dev) {
|
||||||
|
outportb(dev->control, 0x04);
|
||||||
|
ata_io_wait(dev);
|
||||||
|
outportb(dev->control, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ata_wait(struct ata_device * dev, int advanced) {
|
||||||
|
uint8_t status = 0;
|
||||||
|
|
||||||
|
ata_io_wait(dev);
|
||||||
|
|
||||||
|
status = ata_status_wait(dev, -1);
|
||||||
|
|
||||||
|
if (advanced) {
|
||||||
|
status = inportb(dev->io_base + ATA_REG_STATUS);
|
||||||
|
if (status & ATA_SR_ERR) return 1;
|
||||||
|
if (status & ATA_SR_DF) return 1;
|
||||||
|
if (!(status & ATA_SR_DRQ)) return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void atapi_device_init(struct ata_device * dev) {
|
||||||
|
|
||||||
|
dev->is_atapi = 1;
|
||||||
|
|
||||||
|
outportb(dev->io_base + 1, 1);
|
||||||
|
outportb(dev->control, 0);
|
||||||
|
|
||||||
|
outportb(dev->io_base + ATA_REG_HDDEVSEL, 0xA0 | dev->slave << 4);
|
||||||
|
ata_io_wait(dev);
|
||||||
|
|
||||||
|
outportb(dev->io_base + ATA_REG_COMMAND, ATA_CMD_IDENTIFY_PACKET);
|
||||||
|
ata_io_wait(dev);
|
||||||
|
|
||||||
|
ata_wait(dev, 0);
|
||||||
|
|
||||||
|
uint16_t * buf = (uint16_t *)&dev->identity;
|
||||||
|
|
||||||
|
for (int i = 0; i < 256; ++i) {
|
||||||
|
buf[i] = inports(dev->io_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t * ptr = (uint8_t *)&dev->identity.model;
|
||||||
|
for (int i = 0; i < 39; i+=2) {
|
||||||
|
uint8_t tmp = ptr[i+1];
|
||||||
|
ptr[i+1] = ptr[i];
|
||||||
|
ptr[i] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detect medium */
|
||||||
|
atapi_command_t command;
|
||||||
|
memset(&command, 0, sizeof(command));
|
||||||
|
command.command_bytes[0] = 0x25;
|
||||||
|
|
||||||
|
uint16_t bus = dev->io_base;
|
||||||
|
|
||||||
|
outportb(bus + ATA_REG_FEATURES, 0x00);
|
||||||
|
outportb(bus + ATA_REG_LBA1, 0x08);
|
||||||
|
outportb(bus + ATA_REG_LBA2, 0x08);
|
||||||
|
outportb(bus + ATA_REG_COMMAND, ATA_CMD_PACKET);
|
||||||
|
|
||||||
|
/* poll */
|
||||||
|
while (1) {
|
||||||
|
uint8_t status = inportb(dev->io_base + ATA_REG_STATUS);
|
||||||
|
if ((status & ATA_SR_ERR)) goto atapi_error;
|
||||||
|
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
outports(bus, command.command_words[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* poll */
|
||||||
|
while (1) {
|
||||||
|
uint8_t status = inportb(dev->io_base + ATA_REG_STATUS);
|
||||||
|
if ((status & ATA_SR_ERR)) goto atapi_error_read;
|
||||||
|
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break;
|
||||||
|
if ((status & ATA_SR_DRQ)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t data[4];
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
data[i] = inports(bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define htonl(l) ( (((l) & 0xFF) << 24) | (((l) & 0xFF00) << 8) | (((l) & 0xFF0000) >> 8) | (((l) & 0xFF000000) >> 24))
|
||||||
|
uint32_t lba, blocks;;
|
||||||
|
memcpy(&lba, &data[0], sizeof(uint32_t));
|
||||||
|
lba = htonl(lba);
|
||||||
|
memcpy(&blocks, &data[2], sizeof(uint32_t));
|
||||||
|
blocks = htonl(blocks);
|
||||||
|
|
||||||
|
dev->atapi_lba = lba;
|
||||||
|
dev->atapi_sector_size = blocks;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
atapi_error_read:
|
||||||
|
return;
|
||||||
|
|
||||||
|
atapi_error:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ata_device_detect(struct ata_device * dev) {
|
||||||
|
ata_soft_reset(dev);
|
||||||
|
ata_io_wait(dev);
|
||||||
|
outportb(dev->io_base + ATA_REG_HDDEVSEL, 0xA0 | dev->slave << 4);
|
||||||
|
ata_io_wait(dev);
|
||||||
|
ata_status_wait(dev, 10000);
|
||||||
|
|
||||||
|
unsigned char cl = inportb(dev->io_base + ATA_REG_LBA1); /* CYL_LO */
|
||||||
|
unsigned char ch = inportb(dev->io_base + ATA_REG_LBA2); /* CYL_HI */
|
||||||
|
|
||||||
|
if (cl == 0xFF && ch == 0xFF) {
|
||||||
|
/* Nothing here */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((cl == 0x00 && ch == 0x00) ||
|
||||||
|
(cl == 0x3C && ch == 0xC3)) {
|
||||||
|
return 1;
|
||||||
|
} else if ((cl == 0x14 && ch == 0xEB) ||
|
||||||
|
(cl == 0x69 && ch == 0x96)) {
|
||||||
|
atapi_device_init(dev);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ata_device_read_sector_atapi(struct ata_device * dev, uint32_t lba, uint8_t * buf) {
|
||||||
|
|
||||||
|
if (!dev->is_atapi) return;
|
||||||
|
|
||||||
|
uint16_t bus = dev->io_base;
|
||||||
|
|
||||||
|
outportb(dev->io_base + ATA_REG_HDDEVSEL, 0xA0 | dev->slave << 4);
|
||||||
|
ata_io_wait(dev);
|
||||||
|
|
||||||
|
outportb(bus + ATA_REG_FEATURES, 0x00);
|
||||||
|
outportb(bus + ATA_REG_LBA1, dev->atapi_sector_size & 0xFF);
|
||||||
|
outportb(bus + ATA_REG_LBA2, dev->atapi_sector_size >> 8);
|
||||||
|
outportb(bus + ATA_REG_COMMAND, ATA_CMD_PACKET);
|
||||||
|
|
||||||
|
/* poll */
|
||||||
|
while (1) {
|
||||||
|
uint8_t status = inportb(dev->io_base + ATA_REG_STATUS);
|
||||||
|
if ((status & ATA_SR_ERR)) goto atapi_error_on_read_setup;
|
||||||
|
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
atapi_command_t command;
|
||||||
|
command.command_bytes[0] = 0xA8;
|
||||||
|
command.command_bytes[1] = 0;
|
||||||
|
command.command_bytes[2] = (lba >> 0x18) & 0xFF;
|
||||||
|
command.command_bytes[3] = (lba >> 0x10) & 0xFF;
|
||||||
|
command.command_bytes[4] = (lba >> 0x08) & 0xFF;
|
||||||
|
command.command_bytes[5] = (lba >> 0x00) & 0xFF;
|
||||||
|
command.command_bytes[6] = 0;
|
||||||
|
command.command_bytes[7] = 0;
|
||||||
|
command.command_bytes[8] = 0; /* bit 0 = PMI (0, last sector) */
|
||||||
|
command.command_bytes[9] = 1; /* control */
|
||||||
|
command.command_bytes[10] = 0;
|
||||||
|
command.command_bytes[11] = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
outports(bus, command.command_words[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
uint8_t status = inportb(dev->io_base + ATA_REG_STATUS);
|
||||||
|
if ((status & ATA_SR_ERR)) goto atapi_error_on_read_setup;
|
||||||
|
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t size_to_read = inportb(bus + ATA_REG_LBA2) << 8;
|
||||||
|
size_to_read = size_to_read | inportb(bus + ATA_REG_LBA1);
|
||||||
|
|
||||||
|
|
||||||
|
inportsm(bus,buf,size_to_read/2);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
uint8_t status = inportb(dev->io_base + ATA_REG_STATUS);
|
||||||
|
if ((status & ATA_SR_ERR)) goto atapi_error_on_read_setup;
|
||||||
|
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
atapi_error_on_read_setup:
|
||||||
|
print("error on setup\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
10
boot.s
10
boot.s
@ -124,3 +124,13 @@ gdt_end
|
|||||||
global mmap_ent
|
global mmap_ent
|
||||||
mmap_ent db 0, 0
|
mmap_ent db 0, 0
|
||||||
|
|
||||||
|
[bits 32]
|
||||||
|
global jump_to_main
|
||||||
|
jump_to_main:
|
||||||
|
extern _eax
|
||||||
|
extern _ebx
|
||||||
|
extern _xmain
|
||||||
|
mov eax, [_eax]
|
||||||
|
mov ebx, [_ebx]
|
||||||
|
jmp [_xmain]
|
||||||
|
|
||||||
|
271
cstuff.c
271
cstuff.c
@ -1,54 +1,249 @@
|
|||||||
#define __DEBUG__
|
#include "types.h"
|
||||||
#ifdef __DEBUG__
|
#include "ata.h"
|
||||||
unsigned short * textmemptr = (unsigned short *)0xB8000;
|
#include "text.h"
|
||||||
static void placech(unsigned char c, int x, int y, int attr) {
|
#include "util.h"
|
||||||
unsigned short *where;
|
#include "atapi_imp.h"
|
||||||
unsigned att = attr << 8;
|
#include "iso9660.h"
|
||||||
where = textmemptr + (y * 80 + x);
|
#include "elf.h"
|
||||||
*where = c | att;
|
#include "multiboot.h"
|
||||||
|
|
||||||
|
static void restore_root(void) {
|
||||||
|
memcpy(dir_entry, (iso_9660_directory_entry_t *)&root->root, sizeof(iso_9660_directory_entry_t));
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
print("Root restored.");
|
||||||
|
print("\n Entry len: "); print_hex( dir_entry->length);
|
||||||
|
print("\n File start: "); print_hex( dir_entry->extent_start_LSB);
|
||||||
|
print("\n File len: "); print_hex( dir_entry->extent_length_LSB);
|
||||||
|
print("\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int x = 0;
|
static void restore_mod(void) {
|
||||||
static int y = 0;
|
memcpy(dir_entry, (iso_9660_directory_entry_t *)mod_dir, sizeof(iso_9660_directory_entry_t));
|
||||||
static void print(char * str) {
|
#if 0
|
||||||
while (*str) {
|
print("mod restored.");
|
||||||
if (*str == '\n') {
|
print("\n Entry len: "); print_hex( dir_entry->length);
|
||||||
x = 0;
|
print("\n File start: "); print_hex( dir_entry->extent_start_LSB);
|
||||||
y += 1;
|
print("\n File len: "); print_hex( dir_entry->extent_length_LSB);
|
||||||
if (y == 24) {
|
print("\n");
|
||||||
y = 0;
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define KERNEL_LOAD_START 0x300000
|
||||||
|
|
||||||
|
static char * modules[] = {
|
||||||
|
"ZERO.KO",
|
||||||
|
"RANDOM.KO",
|
||||||
|
"SERIAL.KO",
|
||||||
|
"DEBUG_SH.KO",
|
||||||
|
"PROCFS.KO",
|
||||||
|
"TMPFS.KO",
|
||||||
|
"ATA.KO",
|
||||||
|
"EXT2.KO",
|
||||||
|
"ISO9660.KO",
|
||||||
|
"PS2KBD.KO",
|
||||||
|
"PS2MOUSE.KO",
|
||||||
|
"LFBVIDEO.KO",
|
||||||
|
"VBOXGUES.KO",
|
||||||
|
"VMWARE.KO",
|
||||||
|
"VIDSET.KO",
|
||||||
|
"PACKETFS.KO",
|
||||||
|
"SND.KO",
|
||||||
|
"AC97.KO",
|
||||||
|
"NET.KO",
|
||||||
|
"PCNET.KO",
|
||||||
|
"RTL.KO",
|
||||||
|
"E1000.KO",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
static mboot_mod_t modules_mboot[23] = {
|
||||||
|
{0,0,0,1}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct multiboot multiboot_header = {
|
||||||
|
/* flags; */ (1 << 3),
|
||||||
|
/* mem_lower; */ 0x100000,
|
||||||
|
/* mem_upper; */ 0x640000,
|
||||||
|
/* boot_device; */ 0,
|
||||||
|
/* cmdline; */ (uintptr_t)"vid=auto,1024,768 root=/dev/ram0,nocache start=session",
|
||||||
|
/* mods_count; */ 23,
|
||||||
|
/* mods_addr; */ &modules_mboot,
|
||||||
|
/* num; */ 0,
|
||||||
|
/* size; */ 0,
|
||||||
|
/* addr; */ 0,
|
||||||
|
/* shndx; */ 0,
|
||||||
|
/* mmap_length; */ 0,
|
||||||
|
/* mmap_addr; */ 0,
|
||||||
|
/* drives_length; */ 0,
|
||||||
|
/* drives_addr; */ 0,
|
||||||
|
/* config_table; */ 0,
|
||||||
|
/* boot_loader_name; */ 0,
|
||||||
|
/* apm_table; */ 0,
|
||||||
|
/* vbe_control_info; */ 0,
|
||||||
|
/* vbe_mode_info; */ 0,
|
||||||
|
/* vbe_mode; */ 0,
|
||||||
|
/* vbe_interface_seg; */ 0,
|
||||||
|
/* vbe_interface_off; */ 0,
|
||||||
|
/* vbe_interface_len; */ 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static long ramdisk_off = 1;
|
||||||
|
static long ramdisk_len = 1;
|
||||||
|
|
||||||
|
extern void jump_to_main(void);
|
||||||
|
|
||||||
|
int _eax = 1;
|
||||||
|
int _ebx = 1;
|
||||||
|
int _xmain = 1;
|
||||||
|
|
||||||
|
static void move_kernel(void) {
|
||||||
|
clear();
|
||||||
|
print("Relocating kernel...\n");
|
||||||
|
|
||||||
|
Elf32_Header * header = (Elf32_Header *)KERNEL_LOAD_START;
|
||||||
|
|
||||||
|
if (header->e_ident[0] != ELFMAG0 ||
|
||||||
|
header->e_ident[1] != ELFMAG1 ||
|
||||||
|
header->e_ident[2] != ELFMAG2 ||
|
||||||
|
header->e_ident[3] != ELFMAG3) {
|
||||||
|
print("Kernel is invalid?\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t entry = (uintptr_t)header->e_entry;
|
||||||
|
|
||||||
|
for (uintptr_t x = 0; x < (uint32_t)header->e_phentsize * header->e_phnum; x += header->e_phentsize) {
|
||||||
|
Elf32_Phdr * phdr = (Elf32_Phdr *)((uint8_t*)KERNEL_LOAD_START + header->e_phoff + x);
|
||||||
|
if (phdr->p_type == PT_LOAD) {
|
||||||
|
//read_fs(file, phdr->p_offset, phdr->p_filesz, (uint8_t *)phdr->p_vaddr);
|
||||||
|
print("Loading a Phdr... ");
|
||||||
|
print_hex(phdr->p_vaddr);
|
||||||
|
print(" ");
|
||||||
|
print_hex(phdr->p_offset);
|
||||||
|
print(" ");
|
||||||
|
print_hex(phdr->p_filesz);
|
||||||
|
print("\n");
|
||||||
|
memcpy((uint8_t*)phdr->p_vaddr, (uint8_t*)KERNEL_LOAD_START + phdr->p_offset, phdr->p_filesz);
|
||||||
|
long r = phdr->p_filesz;
|
||||||
|
while (r < phdr->p_memsz) {
|
||||||
|
*(char *)(phdr->p_vaddr + r) = 0;
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int foo;
|
||||||
|
//__asm__ __volatile__("jmp %1" : "=a"(foo) : "a" (MULTIBOOT_EAX_MAGIC), "b"((unsigned int)multiboot_header), "r"((unsigned int)entry));
|
||||||
|
_eax = MULTIBOOT_EAX_MAGIC;
|
||||||
|
_ebx = &multiboot_header;
|
||||||
|
_xmain = entry;
|
||||||
|
jump_to_main();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_it(struct ata_device * _device) {
|
||||||
|
device = _device;
|
||||||
|
if (device->atapi_sector_size != 2048) {
|
||||||
|
print_hex(device->atapi_sector_size);
|
||||||
|
print("\n - bad sector size\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
print("Locating stage2...\n");
|
||||||
|
for (int i = 0x10; i < 0x15; ++i) {
|
||||||
|
ata_device_read_sector_atapi(device, i, (uint8_t *)root);
|
||||||
|
switch (root->type) {
|
||||||
|
case 1:
|
||||||
|
root_sector = i;
|
||||||
|
goto done;
|
||||||
|
case 0xFF:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
done:
|
||||||
|
restore_root();
|
||||||
|
|
||||||
|
if (navigate("KERNEL.")) {
|
||||||
|
print("Found kernel.\n");
|
||||||
|
print_hex(dir_entry->extent_start_LSB); print(" ");
|
||||||
|
print_hex(dir_entry->extent_length_LSB); print("\n");
|
||||||
|
long offset = 0;
|
||||||
|
for (int i = dir_entry->extent_start_LSB; i < dir_entry->extent_start_LSB + dir_entry->extent_length_LSB / 2048 + 1; ++i, offset += 2048) {
|
||||||
|
ata_device_read_sector_atapi(device, i, (uint8_t *)KERNEL_LOAD_START + offset);
|
||||||
|
}
|
||||||
|
restore_root();
|
||||||
|
if (navigate("MOD")) {
|
||||||
|
memcpy(mod_dir, dir_entry, sizeof(iso_9660_directory_entry_t));
|
||||||
|
print("Scanning modules...\n");
|
||||||
|
char ** c = modules;
|
||||||
|
int j = 0;
|
||||||
|
while (*c) {
|
||||||
|
print("load "); print(*c); print("\n");
|
||||||
|
if (!navigate(*c)) {
|
||||||
|
print("Failed to locate module! [");
|
||||||
|
print(*c);
|
||||||
|
print("]\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
modules_mboot[j].mod_start = KERNEL_LOAD_START + offset;
|
||||||
|
modules_mboot[j].mod_end = KERNEL_LOAD_START + offset + dir_entry->extent_length_LSB;
|
||||||
|
for (int i = dir_entry->extent_start_LSB; i < dir_entry->extent_start_LSB + dir_entry->extent_length_LSB / 2048 + 1; ++i, offset += 2048) {
|
||||||
|
ata_device_read_sector_atapi(device, i, (uint8_t *)KERNEL_LOAD_START + offset);
|
||||||
|
}
|
||||||
|
restore_mod();
|
||||||
|
c++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
print("Done.\n");
|
||||||
|
restore_root();
|
||||||
|
if (navigate("RAMDISK.IMG")) {
|
||||||
|
print("Loading ramdisk...\n");
|
||||||
|
ramdisk_off = KERNEL_LOAD_START + offset;
|
||||||
|
ramdisk_len = dir_entry->extent_length_LSB;
|
||||||
|
modules_mboot[22].mod_start = ramdisk_off;
|
||||||
|
modules_mboot[22].mod_end = ramdisk_off + ramdisk_len;
|
||||||
|
for (int i = dir_entry->extent_start_LSB; i < dir_entry->extent_start_LSB + dir_entry->extent_length_LSB / 2048 + 1; ++i, offset += 2048) {
|
||||||
|
if (i % 32 == 0) {
|
||||||
|
print(".");
|
||||||
|
}
|
||||||
|
ata_device_read_sector_atapi(device, i, (uint8_t *)KERNEL_LOAD_START + offset);
|
||||||
|
}
|
||||||
|
print("Done.\n");
|
||||||
|
move_kernel();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
placech(*str, x, y, 0x07);
|
print("No mod directory?\n");
|
||||||
x++;
|
|
||||||
if (x == 80) {
|
|
||||||
x = 0;
|
|
||||||
y += 1;
|
|
||||||
if (y == 24) {
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
str++;
|
} else {
|
||||||
|
print("boo\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void clear() {
|
return;
|
||||||
for (int y = 0; y < 24; ++y) {
|
|
||||||
for (int x = 0; x < 80; ++x) {
|
|
||||||
placech(' ', x, y, 0x00);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#define print(...)
|
|
||||||
#define clear()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int kmain() {
|
int kmain() {
|
||||||
clear();
|
clear();
|
||||||
print("ToaruOS-NIH Bootloader v0.1\n\n");
|
print("ToaruOS-NIH Bootloader v0.1\n\n");
|
||||||
print("Scanning ATA devices.\n");
|
print("Scanning ATA devices.\n");
|
||||||
|
|
||||||
|
ata_device_detect(&ata_primary_master);
|
||||||
|
ata_device_detect(&ata_primary_slave);
|
||||||
|
ata_device_detect(&ata_secondary_master);
|
||||||
|
ata_device_detect(&ata_secondary_slave);
|
||||||
|
|
||||||
|
if (ata_primary_master.is_atapi) {
|
||||||
|
do_it(&ata_primary_master);
|
||||||
|
}
|
||||||
|
if (ata_primary_slave.is_atapi) {
|
||||||
|
do_it(&ata_primary_slave);
|
||||||
|
}
|
||||||
|
if (ata_secondary_master.is_atapi) {
|
||||||
|
do_it(&ata_secondary_master);
|
||||||
|
}
|
||||||
|
if (ata_secondary_slave.is_atapi) {
|
||||||
|
do_it(&ata_secondary_slave);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
157
elf.h
Normal file
157
elf.h
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
#pragma once
|
||||||
|
#define ELFMAG0 0x7f
|
||||||
|
#define ELFMAG1 'E'
|
||||||
|
#define ELFMAG2 'L'
|
||||||
|
#define ELFMAG3 'F'
|
||||||
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
|
typedef uint32_t Elf32_Word;
|
||||||
|
typedef uint32_t Elf32_Addr;
|
||||||
|
typedef uint32_t Elf32_Off;
|
||||||
|
typedef uint32_t Elf32_Sword;
|
||||||
|
typedef uint16_t Elf32_Half;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ELF Header
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT];
|
||||||
|
Elf32_Half e_type;
|
||||||
|
Elf32_Half e_machine;
|
||||||
|
Elf32_Word e_version;
|
||||||
|
Elf32_Addr e_entry;
|
||||||
|
Elf32_Off e_phoff;
|
||||||
|
Elf32_Off e_shoff;
|
||||||
|
Elf32_Word e_flags;
|
||||||
|
Elf32_Half e_ehsize;
|
||||||
|
Elf32_Half e_phentsize;
|
||||||
|
Elf32_Half e_phnum;
|
||||||
|
Elf32_Half e_shentsize;
|
||||||
|
Elf32_Half e_shnum;
|
||||||
|
Elf32_Half e_shstrndx;
|
||||||
|
} Elf32_Header;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_type
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ET_NONE 0 /* No file type */
|
||||||
|
#define ET_REL 1 /* Relocatable file */
|
||||||
|
#define ET_EXEC 2 /* Executable file */
|
||||||
|
#define ET_DYN 3 /* Shared object file */
|
||||||
|
#define ET_CORE 4 /* Core file */
|
||||||
|
#define ET_LOPROC 0xff0 /* [Processor Specific] */
|
||||||
|
#define ET_HIPROC 0xfff /* [Processor Specific] */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine types
|
||||||
|
*/
|
||||||
|
#define EM_NONE 0
|
||||||
|
#define EM_386 3
|
||||||
|
|
||||||
|
#define EV_NONE 0
|
||||||
|
#define EV_CURRENT 1
|
||||||
|
|
||||||
|
/** Program Header */
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word p_type;
|
||||||
|
Elf32_Off p_offset;
|
||||||
|
Elf32_Addr p_vaddr;
|
||||||
|
Elf32_Addr p_paddr;
|
||||||
|
Elf32_Word p_filesz;
|
||||||
|
Elf32_Word p_memsz;
|
||||||
|
Elf32_Word p_flags;
|
||||||
|
Elf32_Word p_align;
|
||||||
|
} Elf32_Phdr;
|
||||||
|
|
||||||
|
/* p_type values */
|
||||||
|
#define PT_NULL 0 /* Unused, skip me */
|
||||||
|
#define PT_LOAD 1 /* Loadable segment */
|
||||||
|
#define PT_DYNAMIC 2 /* Dynamic linking information */
|
||||||
|
#define PT_INTERP 3 /* Interpreter (null-terminated string, pathname) */
|
||||||
|
#define PT_NOTE 4 /* Auxillary information */
|
||||||
|
#define PT_SHLIB 5 /* Reserved. */
|
||||||
|
#define PT_PHDR 6 /* Oh, it's me. Hello! Back-reference to the header table itself */
|
||||||
|
#define PT_LOPROC 0x70000000
|
||||||
|
#define PT_HIPROC 0x7FFFFFFF
|
||||||
|
|
||||||
|
|
||||||
|
/** Section Header */
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word sh_name;
|
||||||
|
Elf32_Word sh_type;
|
||||||
|
Elf32_Word sh_flags;
|
||||||
|
Elf32_Addr sh_addr;
|
||||||
|
Elf32_Off sh_offset;
|
||||||
|
Elf32_Word sh_size;
|
||||||
|
Elf32_Word sh_link;
|
||||||
|
Elf32_Word sh_info;
|
||||||
|
Elf32_Word sh_addralign;
|
||||||
|
Elf32_Word sh_entsize;
|
||||||
|
} Elf32_Shdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t id;
|
||||||
|
uintptr_t ptr;
|
||||||
|
} Elf32_auxv;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word st_name;
|
||||||
|
Elf32_Addr st_value;
|
||||||
|
Elf32_Word st_size;
|
||||||
|
unsigned char st_info;
|
||||||
|
unsigned char st_other;
|
||||||
|
Elf32_Half st_shndx;
|
||||||
|
} Elf32_Sym;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Addr r_offset;
|
||||||
|
Elf32_Word r_info;
|
||||||
|
} Elf32_Rel;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Sword d_tag;
|
||||||
|
union {
|
||||||
|
Elf32_Word d_val;
|
||||||
|
Elf32_Addr d_ptr;
|
||||||
|
Elf32_Off d_off;
|
||||||
|
} d_un;
|
||||||
|
} Elf32_Dyn;
|
||||||
|
|
||||||
|
/* sh_type values */
|
||||||
|
#define SHT_NONE 0
|
||||||
|
#define SHT_PROGBITS 1
|
||||||
|
#define SHT_SYMTAB 2
|
||||||
|
#define SHT_STRTAB 3
|
||||||
|
#define SHT_NOBITS 8
|
||||||
|
#define SHT_REL 9
|
||||||
|
|
||||||
|
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||||
|
#define ELF32_R_TYPE(i) ((unsigned char)(i))
|
||||||
|
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
|
||||||
|
|
||||||
|
#define ELF32_ST_BIND(i) ((i) >> 4)
|
||||||
|
#define ELF32_ST_TYPE(i) ((i) & 0xf)
|
||||||
|
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
|
||||||
|
|
||||||
|
#define STB_LOCAL 0
|
||||||
|
#define STB_GLOBAL 1
|
||||||
|
#define STB_WEAK 2
|
||||||
|
#define STB_NUM 3
|
||||||
|
|
||||||
|
#define STB_LOPROC 13
|
||||||
|
#define STB_HIPROC 15
|
||||||
|
|
||||||
|
#define STT_NOTYPE 0
|
||||||
|
#define STT_OBJECT 1
|
||||||
|
#define STT_FUNC 2
|
||||||
|
#define STT_SECTION 3
|
||||||
|
#define STT_FILE 4
|
||||||
|
#define STT_COMMON 5
|
||||||
|
#define STT_TLS 6
|
||||||
|
#define STT_NUM 7
|
||||||
|
|
||||||
|
#define STT_LOPROC 13
|
||||||
|
#define STT_HIPROC 15
|
||||||
|
|
||||||
|
|
165
iso9660.h
Normal file
165
iso9660.h
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char year[4];
|
||||||
|
char month[2];
|
||||||
|
char day[2];
|
||||||
|
char hour[2];
|
||||||
|
char minute[2];
|
||||||
|
char second[2];
|
||||||
|
char hundredths[2];
|
||||||
|
int8_t timezone;
|
||||||
|
} __attribute__((packed)) iso_9660_datetime_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t year;
|
||||||
|
uint8_t month;
|
||||||
|
uint8_t day;
|
||||||
|
uint8_t hour;
|
||||||
|
uint8_t minute;
|
||||||
|
uint8_t second;
|
||||||
|
int8_t timezone;
|
||||||
|
} __attribute__((packed)) iso_9660_rec_date_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t length;
|
||||||
|
uint8_t ext_length;
|
||||||
|
|
||||||
|
uint32_t extent_start_LSB;
|
||||||
|
uint32_t extent_start_MSB;
|
||||||
|
|
||||||
|
uint32_t extent_length_LSB;
|
||||||
|
uint32_t extent_length_MSB;
|
||||||
|
|
||||||
|
iso_9660_rec_date_t record_date;
|
||||||
|
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t interleave_units;
|
||||||
|
uint8_t interleave_gap;
|
||||||
|
|
||||||
|
uint16_t volume_seq_LSB;
|
||||||
|
uint16_t volume_seq_MSB;
|
||||||
|
|
||||||
|
uint8_t name_len;
|
||||||
|
char name[];
|
||||||
|
} __attribute__((packed)) iso_9660_directory_entry_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t type; /* 0x01 */
|
||||||
|
char id[5]; /* CD001 */
|
||||||
|
|
||||||
|
uint8_t version;
|
||||||
|
uint8_t _unused0;
|
||||||
|
|
||||||
|
char system_id[32];
|
||||||
|
char volume_id[32];
|
||||||
|
|
||||||
|
uint8_t _unused1[8];
|
||||||
|
|
||||||
|
uint32_t volume_space_LSB;
|
||||||
|
uint32_t volume_space_MSB;
|
||||||
|
|
||||||
|
uint8_t _unused2[32];
|
||||||
|
|
||||||
|
uint16_t volume_set_LSB;
|
||||||
|
uint16_t volume_set_MSB;
|
||||||
|
|
||||||
|
uint16_t volume_seq_LSB;
|
||||||
|
uint16_t volume_seq_MSB;
|
||||||
|
|
||||||
|
uint16_t logical_block_size_LSB;
|
||||||
|
uint16_t logical_block_size_MSB;
|
||||||
|
|
||||||
|
uint32_t path_table_size_LSB;
|
||||||
|
uint32_t path_table_size_MSB;
|
||||||
|
|
||||||
|
uint32_t path_table_LSB;
|
||||||
|
uint32_t optional_path_table_LSB;
|
||||||
|
|
||||||
|
uint32_t path_table_MSB;
|
||||||
|
uint32_t optional_path_table_MSB;
|
||||||
|
|
||||||
|
/* iso_9660_directory_entry_t */
|
||||||
|
char root[34];
|
||||||
|
|
||||||
|
char volume_set_id[128];
|
||||||
|
char volume_publisher[128];
|
||||||
|
char data_preparer[128];
|
||||||
|
char application_id[128];
|
||||||
|
|
||||||
|
char copyright_file[38];
|
||||||
|
char abstract_file[36];
|
||||||
|
char bibliographic_file[37];
|
||||||
|
|
||||||
|
iso_9660_datetime_t creation;
|
||||||
|
iso_9660_datetime_t modification;
|
||||||
|
iso_9660_datetime_t expiration;
|
||||||
|
iso_9660_datetime_t effective;
|
||||||
|
|
||||||
|
uint8_t file_structure_version;
|
||||||
|
uint8_t _unused_3;
|
||||||
|
|
||||||
|
char application_use[];
|
||||||
|
} __attribute__((packed)) iso_9660_volume_descriptor_t;
|
||||||
|
|
||||||
|
#define ISO_SECTOR_SIZE 2048
|
||||||
|
|
||||||
|
#define FLAG_HIDDEN 0x01
|
||||||
|
#define FLAG_DIRECTORY 0x02
|
||||||
|
#define FLAG_ASSOCIATED 0x04
|
||||||
|
#define FLAG_EXTENDED 0x08
|
||||||
|
#define FLAG_PERMISSIONS 0x10
|
||||||
|
#define FLAG_CONTINUES 0x80
|
||||||
|
|
||||||
|
static int root_sector = 0;
|
||||||
|
static iso_9660_volume_descriptor_t * root = (iso_9660_volume_descriptor_t *)((uint8_t *)0x20000);
|
||||||
|
static iso_9660_directory_entry_t * dir_entry = (iso_9660_directory_entry_t *)((uint8_t *)0x20800);
|
||||||
|
static uint8_t * mod_dir = (uint8_t *)0x21000;
|
||||||
|
static uint8_t * dir_entries = (uint8_t *)(0x30000);
|
||||||
|
static struct ata_device * device = 0;
|
||||||
|
|
||||||
|
static int navigate(char * name) {
|
||||||
|
memset(dir_entries, 2048, 0xA5);
|
||||||
|
//print("reading from sector ");
|
||||||
|
//print_hex(dir_entry->extent_start_LSB);
|
||||||
|
//print("\n");
|
||||||
|
ata_device_read_sector_atapi(device, dir_entry->extent_start_LSB, dir_entries);
|
||||||
|
ata_device_read_sector_atapi(device, dir_entry->extent_start_LSB+1, dir_entries + 2048);
|
||||||
|
ata_device_read_sector_atapi(device, dir_entry->extent_start_LSB+2, dir_entries + 4096);
|
||||||
|
|
||||||
|
long offset = 0;
|
||||||
|
while (1) {
|
||||||
|
iso_9660_directory_entry_t * dir = (iso_9660_directory_entry_t *)(dir_entries + offset);
|
||||||
|
if (dir->length == 0) {
|
||||||
|
if (offset < dir_entry->extent_length_LSB) {
|
||||||
|
offset += 1; // this->block_size - ((uintptr_t)offset % this->block_size);
|
||||||
|
goto try_again;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!(dir->flags & FLAG_HIDDEN)) {
|
||||||
|
char file_name[dir->name_len + 1];
|
||||||
|
memcpy(file_name, dir->name, dir->name_len);
|
||||||
|
file_name[dir->name_len] = 0;
|
||||||
|
char * s = strchr(file_name,';');
|
||||||
|
if (s) {
|
||||||
|
*s = '\0';
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
print("Found a file: ");
|
||||||
|
print(" Name: ");
|
||||||
|
print(file_name); print("\n");
|
||||||
|
#endif
|
||||||
|
if (!strcmp(file_name, name)) {
|
||||||
|
memcpy(dir_entry, dir, sizeof(iso_9660_directory_entry_t));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset += dir->length;
|
||||||
|
try_again:
|
||||||
|
if ((long)(offset) > dir_entry->extent_length_LSB) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
89
multiboot.h
Normal file
89
multiboot.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MULTIBOOT_MAGIC 0x1BADB002
|
||||||
|
#define MULTIBOOT_EAX_MAGIC 0x2BADB002
|
||||||
|
#define MULTIBOOT_FLAG_MEM 0x001
|
||||||
|
#define MULTIBOOT_FLAG_DEVICE 0x002
|
||||||
|
#define MULTIBOOT_FLAG_CMDLINE 0x004
|
||||||
|
#define MULTIBOOT_FLAG_MODS 0x008
|
||||||
|
#define MULTIBOOT_FLAG_AOUT 0x010
|
||||||
|
#define MULTIBOOT_FLAG_ELF 0x020
|
||||||
|
#define MULTIBOOT_FLAG_MMAP 0x040
|
||||||
|
#define MULTIBOOT_FLAG_CONFIG 0x080
|
||||||
|
#define MULTIBOOT_FLAG_LOADER 0x100
|
||||||
|
#define MULTIBOOT_FLAG_APM 0x200
|
||||||
|
#define MULTIBOOT_FLAG_VBE 0x400
|
||||||
|
|
||||||
|
struct multiboot
|
||||||
|
{
|
||||||
|
uintptr_t flags;
|
||||||
|
uintptr_t mem_lower;
|
||||||
|
uintptr_t mem_upper;
|
||||||
|
uintptr_t boot_device;
|
||||||
|
uintptr_t cmdline;
|
||||||
|
uintptr_t mods_count;
|
||||||
|
uintptr_t mods_addr;
|
||||||
|
uintptr_t num;
|
||||||
|
uintptr_t size;
|
||||||
|
uintptr_t addr;
|
||||||
|
uintptr_t shndx;
|
||||||
|
uintptr_t mmap_length;
|
||||||
|
uintptr_t mmap_addr;
|
||||||
|
uintptr_t drives_length;
|
||||||
|
uintptr_t drives_addr;
|
||||||
|
uintptr_t config_table;
|
||||||
|
uintptr_t boot_loader_name;
|
||||||
|
uintptr_t apm_table;
|
||||||
|
uintptr_t vbe_control_info;
|
||||||
|
uintptr_t vbe_mode_info;
|
||||||
|
uintptr_t vbe_mode;
|
||||||
|
uintptr_t vbe_interface_seg;
|
||||||
|
uintptr_t vbe_interface_off;
|
||||||
|
uintptr_t vbe_interface_len;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t attributes;
|
||||||
|
uint8_t winA, winB;
|
||||||
|
uint16_t granularity;
|
||||||
|
uint16_t winsize;
|
||||||
|
uint16_t segmentA, segmentB;
|
||||||
|
uint32_t realFctPtr;
|
||||||
|
uint16_t pitch;
|
||||||
|
|
||||||
|
uint16_t Xres, Yres;
|
||||||
|
uint8_t Wchar, Ychar, planes, bpp, banks;
|
||||||
|
uint8_t memory_model, bank_size, image_pages;
|
||||||
|
uint8_t reserved0;
|
||||||
|
|
||||||
|
uint8_t red_mask, red_position;
|
||||||
|
uint8_t green_mask, green_position;
|
||||||
|
uint8_t blue_mask, blue_position;
|
||||||
|
uint8_t rsv_mask, rsv_position;
|
||||||
|
uint8_t directcolor_attributes;
|
||||||
|
|
||||||
|
uint32_t physbase;
|
||||||
|
uint32_t reserved1;
|
||||||
|
uint16_t reserved2;
|
||||||
|
} __attribute__ ((packed)) vbe_info_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uintptr_t mod_start;
|
||||||
|
uintptr_t mod_end;
|
||||||
|
uintptr_t cmdline;
|
||||||
|
uintptr_t reserved;
|
||||||
|
} __attribute__ ((packed)) mboot_mod_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t size;
|
||||||
|
uint64_t base_addr;
|
||||||
|
uint64_t length;
|
||||||
|
uint32_t type;
|
||||||
|
} __attribute__ ((packed)) mboot_memmap_t;
|
||||||
|
|
||||||
|
extern struct multiboot *copy_multiboot(struct multiboot *mboot_ptr);
|
||||||
|
extern void dump_multiboot(struct multiboot *mboot_ptr);
|
||||||
|
extern char * ramdisk;
|
||||||
|
extern struct multiboot * mboot_ptr;
|
||||||
|
|
||||||
|
|
63
text.h
Normal file
63
text.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define __DEBUG__
|
||||||
|
#ifdef __DEBUG__
|
||||||
|
unsigned short * textmemptr = (unsigned short *)0xB8000;
|
||||||
|
static void placech(unsigned char c, int x, int y, int attr) {
|
||||||
|
unsigned short *where;
|
||||||
|
unsigned att = attr << 8;
|
||||||
|
where = textmemptr + (y * 80 + x);
|
||||||
|
*where = c | att;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int x = 0;
|
||||||
|
static int y = 0;
|
||||||
|
static void print(char * str) {
|
||||||
|
while (*str) {
|
||||||
|
if (*str == '\n') {
|
||||||
|
for (; x < 80; ++x) {
|
||||||
|
placech(' ', x, y, 0x00);
|
||||||
|
}
|
||||||
|
x = 0;
|
||||||
|
y += 1;
|
||||||
|
if (y == 24) {
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
placech(*str, x, y, 0x07);
|
||||||
|
x++;
|
||||||
|
if (x == 80) {
|
||||||
|
x = 0;
|
||||||
|
y += 1;
|
||||||
|
if (y == 24) {
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_hex(unsigned int value) {
|
||||||
|
char out[9] = {0};
|
||||||
|
for (int i = 7; i > -1; i--) {
|
||||||
|
out[i] = "0123456789abcdef"[(value >> (4 * (7 - i))) & 0xF];
|
||||||
|
}
|
||||||
|
print(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear() {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
for (int y = 0; y < 24; ++y) {
|
||||||
|
for (int x = 0; x < 80; ++x) {
|
||||||
|
placech(' ', x, y, 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define print(...)
|
||||||
|
#define clear()
|
||||||
|
#define print_hex(...)
|
||||||
|
#endif
|
||||||
|
|
10
types.h
Normal file
10
types.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
typedef unsigned long uint32_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef signed char int8_t;
|
||||||
|
typedef unsigned long uintptr_t;
|
||||||
|
|
||||||
|
|
70
util.h
Normal file
70
util.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define _inline inline __attribute__((always_inline))
|
||||||
|
|
||||||
|
static _inline unsigned short inports(unsigned short _port) {
|
||||||
|
unsigned short rv;
|
||||||
|
asm volatile ("inw %1, %0" : "=a" (rv) : "dN" (_port));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _inline void outports(unsigned short _port, unsigned short _data) {
|
||||||
|
asm volatile ("outw %1, %0" : : "dN" (_port), "a" (_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static _inline unsigned int inportl(unsigned short _port) {
|
||||||
|
unsigned int rv;
|
||||||
|
asm volatile ("inl %%dx, %%eax" : "=a" (rv) : "dN" (_port));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _inline void outportl(unsigned short _port, unsigned int _data) {
|
||||||
|
asm volatile ("outl %%eax, %%dx" : : "dN" (_port), "a" (_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static _inline unsigned char inportb(unsigned short _port) {
|
||||||
|
unsigned char rv;
|
||||||
|
asm volatile ("inb %1, %0" : "=a" (rv) : "dN" (_port));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _inline void outportb(unsigned short _port, unsigned char _data) {
|
||||||
|
asm volatile ("outb %1, %0" : : "dN" (_port), "a" (_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static _inline void inportsm(unsigned short port, unsigned char * data, unsigned long size) {
|
||||||
|
asm volatile ("rep insw" : "+D" (data), "+c" (size) : "d" (port) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static _inline void * memcpy(void * restrict dest, const void * restrict src, long n) {
|
||||||
|
asm volatile("cld; rep movsb"
|
||||||
|
: "=c"((int){0})
|
||||||
|
: "D"(dest), "S"(src), "c"(n)
|
||||||
|
: "flags", "memory");
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _inline void * memset(void * dest, int c, long n) {
|
||||||
|
asm volatile("cld; rep stosb"
|
||||||
|
: "=c"((int){0})
|
||||||
|
: "D"(dest), "a"(c), "c"(n)
|
||||||
|
: "flags", "memory");
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int strcmp(const char * l, const char * r) {
|
||||||
|
for (; *l == *r && *l; l++, r++);
|
||||||
|
return *(unsigned char *)l - *(unsigned char *)r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char * strchr(const char * s, int c) {
|
||||||
|
while (*s) {
|
||||||
|
if (*s == c) {
|
||||||
|
return (char *)s;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user