elf: start writing elf loader
This commit is contained in:
parent
175805604e
commit
a6f371b4ad
12 changed files with 4706 additions and 72 deletions
43
kernel/src/exec/elf.c
Normal file
43
kernel/src/exec/elf.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <exec/elf.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/log.h>
|
||||
|
||||
void elf_load(char *data) {
|
||||
Elf64_Ehdr *ehdr = (Elf64_Ehdr*)data;
|
||||
if ( ehdr->e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr->e_ident[EI_MAG1] != ELFMAG1
|
||||
|| ehdr->e_ident[EI_MAG2] != ELFMAG2
|
||||
|| ehdr->e_ident[EI_MAG3] != ELFMAG3)
|
||||
{
|
||||
log("elf - loading failed: magic is incorrect\n");
|
||||
return;
|
||||
}
|
||||
|
||||
log("elf - e_ident[EI_DATA]: %d\n", ehdr->e_ident[EI_DATA]);
|
||||
log("elf - e_ident[EI_CLASS]: %d\n", ehdr->e_ident[EI_CLASS]);
|
||||
log("elf - e_ident[EI_OSABI]: %d\n", ehdr->e_ident[EI_OSABI]);
|
||||
log("elf - e_machine: %d\n", ehdr->e_machine);
|
||||
log("elf - e_entry: %p\n", ehdr->e_entry);
|
||||
log("elf - e_type: %p\n", ehdr->e_type);
|
||||
|
||||
if ( ehdr->e_ident[EI_CLASS] != ELFCLASS64
|
||||
|| ehdr->e_machine != EM_X86_64)
|
||||
{
|
||||
log("elf - loading failed: is the file built for amd64?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ehdr->e_type != ET_EXEC)
|
||||
{
|
||||
log("elf - loading failed: ELF type isn't ET_EXEC\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Elf64_Phdr *phdr = (Elf64_Phdr*)data + ehdr->e_phoff;
|
||||
for (uint16_t i = 0; i < ehdr->e_phnum; i++) {
|
||||
if (phdr[i].p_type != PT_LOAD)
|
||||
continue;
|
||||
|
||||
log("elf - Loadable program header: vaddr: %p", phdr[i].p_vaddr);
|
||||
}
|
||||
}
|
118
kernel/src/exec/elf.h
Normal file
118
kernel/src/exec/elf.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// ELF magic.
|
||||
#define EI_MAG0 0
|
||||
#define ELFMAG0 0x7f
|
||||
|
||||
#define EI_MAG1 1
|
||||
#define ELFMAG1 'E'
|
||||
|
||||
#define EI_MAG2 2
|
||||
#define ELFMAG2 'L'
|
||||
|
||||
#define EI_MAG3 3
|
||||
#define ELFMAG3 'F'
|
||||
|
||||
// ELF class
|
||||
#define EI_CLASS 4
|
||||
#define ELFCLASSNONE 0
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
|
||||
// Is processor-specific data little-endian or big-endian?
|
||||
#define EI_DATA 5
|
||||
#define ELFDATANONE 0
|
||||
#define ELFDATA2LSB 1
|
||||
#define ELFDATA2MSB 2
|
||||
|
||||
// ELF version
|
||||
#define EI_VERSION 6
|
||||
#define EV_NONE 0
|
||||
#define EV_CURRENT 1
|
||||
|
||||
// ELF ABI
|
||||
#define EI_OSABI 7
|
||||
#define ELFOSABI_NONE 0
|
||||
#define ELFOSABI_SYSV 0
|
||||
#define ELFOSABI_HPUX 1
|
||||
#define ELFOSABI_NETBSD 2
|
||||
#define ELFOSABI_LINUX 3
|
||||
#define ELFOSABI_SOLARIS 6
|
||||
#define ELFOSABI_IRIX 8
|
||||
#define ELFOSABI_FREEBSD 9
|
||||
#define ELFOSABI_TRU64 10
|
||||
#define ELFOSABI_ARM 97
|
||||
#define ELFOSABI_STANDALONE 255
|
||||
|
||||
// ABI version
|
||||
#define EI_ABIVERSION 8
|
||||
|
||||
// Unused bytes.
|
||||
#define EI_PAD 9
|
||||
|
||||
// Magic size.
|
||||
#define EI_NIDENT 16
|
||||
|
||||
// e_type
|
||||
#define ET_NONE 0
|
||||
#define ET_REL 1
|
||||
#define ET_EXEC 2
|
||||
#define ET_DYN 3
|
||||
#define ET_CORE 4
|
||||
|
||||
// e_machine (we only included machines supported by Soaplin.)
|
||||
#define EM_X86_64 62
|
||||
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef uint16_t Elf64_Section;
|
||||
typedef uint16_t Elf64_Versym;
|
||||
typedef uint8_t Elf_Byte;
|
||||
typedef uint16_t Elf64_Half;
|
||||
typedef int32_t Elf64_Sword;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef int64_t Elf64_Sxword;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
uint16_t e_type;
|
||||
uint16_t e_machine;
|
||||
uint32_t e_version;
|
||||
Elf64_Addr e_entry;
|
||||
Elf64_Off e_phoff;
|
||||
Elf64_Off e_shoff;
|
||||
uint32_t e_flags;
|
||||
uint16_t e_ehsize;
|
||||
uint16_t e_phentsize;
|
||||
uint16_t e_phnum;
|
||||
uint16_t e_shentsize;
|
||||
uint16_t e_shnum;
|
||||
uint16_t e_shstrndx;
|
||||
} Elf64_Ehdr;
|
||||
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
|
||||
#define PF_X (1 << 0)
|
||||
#define PF_W (1 << 1)
|
||||
#define PF_R (1 << 2)
|
||||
|
||||
typedef struct {
|
||||
uint32_t p_type;
|
||||
uint32_t p_flags;
|
||||
Elf64_Off p_offset;
|
||||
Elf64_Addr p_vaddr;
|
||||
Elf64_Addr p_paddr;
|
||||
uint64_t p_filesz;
|
||||
uint64_t p_memsz;
|
||||
uint64_t p_align;
|
||||
} Elf64_Phdr;
|
||||
|
||||
void elf_load(char *data);
|
|
@ -1,66 +1 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct vfs {
|
||||
struct vfs *vfs_next; /* next vfs in list */
|
||||
struct vfsops *vfs_op; /* operations on vfs */
|
||||
struct vnode *vfs_vnodecovered; /* vnode we cover */
|
||||
int vfs_flag; /* flags */
|
||||
int vfs_bsize; /* native block size */
|
||||
uint64_t vfs_data; /* private data */
|
||||
};
|
||||
|
||||
struct vfsops {
|
||||
int (*vfs_mount)();
|
||||
int (*vfs_unmount)();
|
||||
int (*vfs_root)();
|
||||
int (*vfs_statfs)();
|
||||
int (*vfs_sync)();
|
||||
int (*vfs_fid)();
|
||||
int (*vfs_vget)();
|
||||
};
|
||||
|
||||
enum vtype { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VBAD };
|
||||
struct vnode {
|
||||
uint16_t v_flag; /* vnode flags */
|
||||
uint16_t v_count; /* reference count */
|
||||
uint16_t v_shlockc; /* # of shared locks */
|
||||
uint16_t v_exlockc; /* # of exclusive locks */
|
||||
struct vfs *v_vfsmountedhere; /* covering vfs */
|
||||
struct vnodeops *v_op; /* vnode operations */
|
||||
union {
|
||||
struct socket *v_Socket; /* unix ipc */
|
||||
struct stdata *v_Stream; /* stream */
|
||||
};
|
||||
struct vfs *v_vfsp; /* vfs we are in */
|
||||
enum vtype v_type; /* vnode type */
|
||||
uint64_t v_data; /* private data */
|
||||
};
|
||||
|
||||
struct vnodeops {
|
||||
int (*vn_open)();
|
||||
int (*vn_close)();
|
||||
int (*vn_rdwr)();
|
||||
int (*vn_ioctl)();
|
||||
int (*vn_select)();
|
||||
int (*vn_getattr)();
|
||||
int (*vn_setattr)();
|
||||
int (*vn_access)();
|
||||
int (*vn_lookup)();
|
||||
int (*vn_create)();
|
||||
int (*vn_remove)();
|
||||
int (*vn_link)();
|
||||
int (*vn_rename)();
|
||||
int (*vn_mkdir)();
|
||||
int (*vn_rmdir)();
|
||||
int (*vn_readdir)();
|
||||
int (*vn_symlink)();
|
||||
int (*vn_readlink)();
|
||||
int (*vn_fsync)();
|
||||
int (*vn_inactive)();
|
||||
int (*vn_bmap)();
|
||||
int (*vn_strategy)();
|
||||
int (*vn_bread)();
|
||||
int (*vn_brelse)();
|
||||
};
|
|
@ -1,3 +1,4 @@
|
|||
#include "exec/elf.h"
|
||||
#include "mm/pmm.h"
|
||||
#include "mm/vmm.h"
|
||||
#include "rt.h"
|
||||
|
@ -35,6 +36,12 @@ static volatile struct limine_framebuffer_request framebuffer_request = {
|
|||
.revision = 0
|
||||
};
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_module_request module_request = {
|
||||
.id = LIMINE_MODULE_REQUEST,
|
||||
.revision = 0
|
||||
};
|
||||
|
||||
/*__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_entry_point_request entrypoint_request = {
|
||||
.id = LIMINE_ENTRY_POINT_REQUEST,
|
||||
|
@ -112,18 +119,23 @@ void kmain(void) {
|
|||
vmm_init();
|
||||
|
||||
pit_init(1000);
|
||||
//sched_init();
|
||||
sched_init();
|
||||
//user_init();
|
||||
|
||||
uint8_t *mem = pmm_request_page();
|
||||
mem[0] = 0xCD;
|
||||
mem[1] = 0x80;
|
||||
struct limine_file *f = module_request.response->modules[0];
|
||||
log("kmain - %s\n", f->path);
|
||||
|
||||
elf_load((char*)f->address);
|
||||
|
||||
//uint8_t *mem = pmm_request_page();
|
||||
//mem[0] = 0xCD;
|
||||
//mem[1] = 0x80;
|
||||
//mem[2] = 0xF4;
|
||||
|
||||
//mem[3] = 0xFE;
|
||||
pagemap_t* pm = vmm_alloc_pm();
|
||||
vmm_map(pm, 0x1000, (uint64_t)mem, VMM_PRESENT | VMM_USER);
|
||||
sched_create("Init", 0x1000, pm, SCHED_USER_PROCESS);
|
||||
//pagemap_t* pm = vmm_alloc_pm();
|
||||
//vmm_map(pm, 0x1000, (uint64_t)mem, VMM_PRESENT | VMM_USER);
|
||||
//sched_create("Init", 0x1000, pm, SCHED_USER_PROCESS);
|
||||
|
||||
|
||||
log("kernel - Soaplin initialized sucessfully.\n");
|
||||
|
|
|
@ -90,6 +90,8 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t* pm, uin
|
|||
log("sched - Standby mode has been"
|
||||
"disabled.\n");
|
||||
}
|
||||
|
||||
log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, proc->pid, proc->regs.rip);
|
||||
return proc;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue