Added initrd driver
This commit is contained in:
parent
dd48ba577d
commit
f263f3f481
@ -1,5 +1,5 @@
|
|||||||
OBJS = tty.o gdt.o idt.o isr.o timer.o keyboard.o \
|
OBJS = tty.o gdt.o idt.o isr.o timer.o keyboard.o \
|
||||||
fs.o cpuid.o
|
fs.o cpuid.o initrd.o
|
||||||
|
|
||||||
CC = i686-elf-gcc # cross-compiler
|
CC = i686-elf-gcc # cross-compiler
|
||||||
CFLAGS = -m32 -fno-stack-protector -DDEFAULT_USER=root -DDEFAULT_HOSTNAME=vulcan -ffreestanding -Wall -Wextra -Werror -g -c
|
CFLAGS = -m32 -fno-stack-protector -DDEFAULT_USER=root -DDEFAULT_HOSTNAME=vulcan -ffreestanding -Wall -Wextra -Werror -g -c
|
||||||
|
@ -1,26 +1,79 @@
|
|||||||
#include "initrd.h"
|
#include "initrd.h"
|
||||||
|
|
||||||
|
// Private API to IO operations on dir and files
|
||||||
|
static uint32_t initrd_read(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer);
|
||||||
|
static struct dirent *initrd_readdir(fs_node_t *node, uint32_t index);
|
||||||
|
static fs_node_t *initrd_finddir(fs_node_t *node, uint8_t *name);
|
||||||
|
|
||||||
// Declare various things
|
// Declare various things
|
||||||
initrd_header_t *initrd_header; // Header
|
initrd_header_t *initrd_header; // Header
|
||||||
initrd_file_header_t *file_header; // List of headers
|
initrd_file_header_t *file_headers; // List of headers
|
||||||
fs_node_t *initrd_root; // Directory root node
|
fs_node_t *initrd_root; // Directory root node
|
||||||
fs_node_t *initrd_dev; // Directory dev node(/dev)
|
fs_node_t *initrd_dev; // Directory dev node(/dev)
|
||||||
fs_node_t *root_nodes; // List of file nodes
|
fs_node_t *root_nodes; // List of file nodes
|
||||||
uint32_t nroot_nodes;
|
uint32_t nroot_nodes; // Number of file nodes
|
||||||
|
|
||||||
struct dirent dirent;
|
struct dirent dirent;
|
||||||
|
|
||||||
fs_node_t *init_ramdisk(uint32_t multiboot_location) {
|
fs_node_t *init_ramdisk(uint32_t multiboot_location) {
|
||||||
// Initialize main and file headers
|
// Initialize main and file headers
|
||||||
initrd_header = (initrd_header_t*)multiboot_location;
|
initrd_header = (initrd_header_t*)multiboot_location;
|
||||||
file_header = (initrd_file_header_t*)(multiboot_location+sizeof(initrd_header_t));
|
file_headers = (initrd_file_header_t*)(multiboot_location+sizeof(initrd_header_t));
|
||||||
// Initialize root directory
|
// Initialize root directory
|
||||||
initrd_root = (fs_node_t*)
|
initrd_root = (fs_node_t*)kmalloc(sizeof(fs_node_t));
|
||||||
|
strcpy(initrd_root->name, "initrd");
|
||||||
|
initrd_root->mask = initrd_root->uid = initrd_root->gid = initrd_root->inode = initrd_root->length = 0;
|
||||||
|
initrd_root->flags = FS_DIRECTORY;
|
||||||
|
initrd_root->read = 0;
|
||||||
|
initrd_root->write = 0;
|
||||||
|
initrd_root->open = 0;
|
||||||
|
initrd_root->close = 0;
|
||||||
|
initrd_root->readdir = &initrd_readdir;
|
||||||
|
initrd_root->finddir = &initrd_finddir;
|
||||||
|
initrd_root->ptr = 0;
|
||||||
|
initrd_root->impl = 0;
|
||||||
|
|
||||||
|
// Initialize the /dev/ directory
|
||||||
|
initrd_dev = (fs_node_t*)kmalloc(sizeof(fs_node_t));
|
||||||
|
strcpy(initrd_root->name, "dev");
|
||||||
|
initrd_root->mask = initrd_root->uid = initrd_root->gid = initrd_root->inode = initrd_root->length = 0;
|
||||||
|
initrd_root->flags = FS_DIRECTORY;
|
||||||
|
initrd_root->read = 0;
|
||||||
|
initrd_root->write = 0;
|
||||||
|
initrd_root->open = 0;
|
||||||
|
initrd_root->close = 0;
|
||||||
|
initrd_root->readdir = &initrd_readdir;
|
||||||
|
initrd_root->finddir = &initrd_finddir;
|
||||||
|
initrd_root->ptr = 0;
|
||||||
|
initrd_root->impl = 0;
|
||||||
|
|
||||||
|
// Add dev and root directories to the ramdisk
|
||||||
|
// Let us first allocate space for them
|
||||||
|
root_nodes = (fs_node_t*)kmalloc(sizeof(fs_node_t) *initrd_header->nfiles);
|
||||||
|
nroot_nodes = initrd_header->nfiles;
|
||||||
|
// and then, add each file to an inode
|
||||||
|
for(uint32_t i = 0; i < initrd_header->nfiles; i++) {
|
||||||
|
file_headers[i].offset += multiboot_location;
|
||||||
|
// Create an inode for the file
|
||||||
|
strcpy(root_nodes[i].name, &file_headers[i].name);
|
||||||
|
root_nodes[i].mask = root_nodes[i].uid = root_nodes[i].gid = 0;
|
||||||
|
root_nodes[i].length = file_headers[i].length;
|
||||||
|
root_nodes[i].inode = i;
|
||||||
|
root_nodes[i].flags = FS_FILE;
|
||||||
|
root_nodes[i].read = &initrd_read;
|
||||||
|
root_nodes[i].write = 0;
|
||||||
|
root_nodes[i].readdir = 0;
|
||||||
|
root_nodes[i].finddir = 0;
|
||||||
|
root_nodes[i].open = 0;
|
||||||
|
root_nodes[i].close = 0;
|
||||||
|
root_nodes[i].impl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return initrd_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t initrd_read(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
static uint32_t initrd_read(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
||||||
initrd_file_header_t header = file_header[node->inode];
|
initrd_file_header_t header = file_headers[node->inode];
|
||||||
if(offset > header.length)
|
if(offset > header.length)
|
||||||
return 0;
|
return 0;
|
||||||
if(offset+size > header.length)
|
if(offset+size > header.length)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../libc/string.h"
|
#include "../libc/string.h"
|
||||||
|
#include "../mem/kheap.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -29,8 +30,5 @@ typedef struct {
|
|||||||
// Function to initialize initrd, we'll pass the multiboot
|
// Function to initialize initrd, we'll pass the multiboot
|
||||||
// module as parameter
|
// module as parameter
|
||||||
fs_node_t *init_ramdisk(uint32_t multiboot_location);
|
fs_node_t *init_ramdisk(uint32_t multiboot_location);
|
||||||
static uint32_t initrd_read(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer);
|
|
||||||
static struct dirent *initrd_readdir(fs_node_t *node, uint32_t index);
|
|
||||||
static fs_node_t *initrd_finddir(fs_node_t *node, uint8_t *name);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "drivers/idt.h"
|
#include "drivers/idt.h"
|
||||||
#include "drivers/timer.h"
|
#include "drivers/timer.h"
|
||||||
#include "drivers/keyboard.h"
|
#include "drivers/keyboard.h"
|
||||||
|
#include "drivers/initrd.h"
|
||||||
#include "mem/paging.h"
|
#include "mem/paging.h"
|
||||||
#include "mem/kheap.h"
|
#include "mem/kheap.h"
|
||||||
#include "mem/multiboot.h"
|
#include "mem/multiboot.h"
|
||||||
@ -23,8 +24,22 @@
|
|||||||
#define PRTAT printf("\n["); printf_color(" ** ", LIGHT_BROWN, BLACK); printf("]"); // Ugly hack to print "[ * ]"
|
#define PRTAT printf("\n["); printf_color(" ** ", LIGHT_BROWN, BLACK); printf("]"); // Ugly hack to print "[ * ]"
|
||||||
#define PRTER printf("\n["); printf_color(" ERR ", LIGHT_RED, BLACK); printf("]"); // Ugly hack to print "[ ER ]"
|
#define PRTER printf("\n["); printf_color(" ERR ", LIGHT_RED, BLACK); printf("]"); // Ugly hack to print "[ ER ]"
|
||||||
|
|
||||||
|
uint32_t initrd_setup( struct multiboot *mboot_ptr) {
|
||||||
|
if(mboot_ptr->mods_count < 0) { // Assert that initrd image is available
|
||||||
|
PRTER
|
||||||
|
puts(" - initrd not found!");
|
||||||
|
PANIC("Cannot find initrd");
|
||||||
|
}
|
||||||
|
|
||||||
void kernel_main(unsigned long magic, uint32_t addr) {
|
extern uint32_t placement_addr;
|
||||||
|
uint32_t initrd_location = *((uint32_t*)mboot_ptr->mods_addr);
|
||||||
|
uint32_t initrd_end = *(uint32_t*)(mboot_ptr->mods_addr+4);
|
||||||
|
placement_addr = initrd_end;
|
||||||
|
|
||||||
|
return initrd_location;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kernel_main(unsigned long magic, uint32_t addr, struct multiboot *mboot_ptr) {
|
||||||
// First of all, check if we're booted by a Multiboot-compliant boot loader
|
// First of all, check if we're booted by a Multiboot-compliant boot loader
|
||||||
if(magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
|
if(magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
|
||||||
PRTER
|
PRTER
|
||||||
@ -57,9 +72,16 @@ void kernel_main(unsigned long magic, uint32_t addr) {
|
|||||||
PRTOK
|
PRTOK
|
||||||
printf(" - Loaded PS/2 driver");
|
printf(" - Loaded PS/2 driver");
|
||||||
|
|
||||||
|
uint32_t loc = initrd_setup(mboot_ptr); // Setup initial ramdisk
|
||||||
|
|
||||||
init_paging(); // Initialize paging
|
init_paging(); // Initialize paging
|
||||||
PRTOK
|
PRTOK
|
||||||
printf(" - Loaded Paging");
|
printf(" - Loaded Paging");
|
||||||
|
|
||||||
|
// Now we can start initrd
|
||||||
|
fs_root = init_ramdisk(loc);
|
||||||
|
PRTOK
|
||||||
|
printf(" - Loaded Initrd");
|
||||||
|
|
||||||
PRTAT
|
PRTAT
|
||||||
printf(" - Testing heap...\t");
|
printf(" - Testing heap...\t");
|
||||||
|
@ -94,6 +94,36 @@ typedef unsigned short multiboot_uint16_t;
|
|||||||
typedef unsigned int multiboot_uint32_t;
|
typedef unsigned int multiboot_uint32_t;
|
||||||
typedef unsigned long long multiboot_uint64_t;
|
typedef unsigned long long multiboot_uint64_t;
|
||||||
|
|
||||||
|
struct multiboot
|
||||||
|
{
|
||||||
|
multiboot_uint32_t flags;
|
||||||
|
multiboot_uint32_t mem_lower;
|
||||||
|
multiboot_uint32_t mem_upper;
|
||||||
|
multiboot_uint32_t boot_device;
|
||||||
|
multiboot_uint32_t cmdline;
|
||||||
|
int32_t mods_count;
|
||||||
|
multiboot_uint32_t mods_addr;
|
||||||
|
multiboot_uint32_t num;
|
||||||
|
multiboot_uint32_t size;
|
||||||
|
multiboot_uint32_t addr;
|
||||||
|
multiboot_uint32_t shndx;
|
||||||
|
multiboot_uint32_t mmap_length;
|
||||||
|
multiboot_uint32_t mmap_addr;
|
||||||
|
multiboot_uint32_t drives_length;
|
||||||
|
multiboot_uint32_t drives_addr;
|
||||||
|
multiboot_uint32_t config_table;
|
||||||
|
multiboot_uint32_t boot_loader_name;
|
||||||
|
multiboot_uint32_t apm_table;
|
||||||
|
multiboot_uint32_t vbe_control_info;
|
||||||
|
multiboot_uint32_t vbe_mode_info;
|
||||||
|
multiboot_uint32_t vbe_mode;
|
||||||
|
multiboot_uint32_t vbe_interface_seg;
|
||||||
|
multiboot_uint32_t vbe_interface_off;
|
||||||
|
multiboot_uint32_t vbe_interface_len;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
typedef struct multiboot_header multiboot_header_t;
|
||||||
|
|
||||||
struct multiboot_header
|
struct multiboot_header
|
||||||
{
|
{
|
||||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||||
|
Loading…
Reference in New Issue
Block a user