2019-05-24 09:04:31 -05:00
|
|
|
#include "cpu/cpu_init.h"
|
2020-07-22 19:35:23 -05:00
|
|
|
#include "cpu/isr.h"
|
|
|
|
#include "cpu/paging.h"
|
2020-07-22 19:26:55 -05:00
|
|
|
#include "cpu/serial.h"
|
|
|
|
#include "pmem.h"
|
2020-07-22 19:35:23 -05:00
|
|
|
#include "tasking.h"
|
|
|
|
#include "vga_err.h"
|
|
|
|
#include <elf.h>
|
|
|
|
#include <grub/multiboot2.h>
|
|
|
|
#include <memory.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <tasking.h>
|
2019-04-27 09:51:32 -05:00
|
|
|
|
2020-07-25 16:54:37 -05:00
|
|
|
/**
|
|
|
|
* REspresents a TAR file header
|
|
|
|
*/
|
2019-05-23 17:38:26 -05:00
|
|
|
typedef struct {
|
2020-07-25 16:54:37 -05:00
|
|
|
char filename[100]; //!< Filename of file descried by the tar header
|
|
|
|
char mode[8]; //!< Mode as an octal string
|
|
|
|
char uid[8]; //!< UID of owner as an octal string
|
|
|
|
char gid[8]; //!< GID of owner as an octal string
|
|
|
|
char size[12]; //!< Size of file as an octal string
|
|
|
|
char mtime[12]; //!< Modification time as an octal string
|
|
|
|
char chksum[8]; //!< Checksum as octal string
|
|
|
|
char typeflag[1]; //!< File type. (0 for normal file)
|
2019-05-23 17:38:26 -05:00
|
|
|
} tar_header;
|
|
|
|
|
2019-08-26 13:07:01 -05:00
|
|
|
long initrd_sz;
|
|
|
|
char* initrd;
|
2019-04-27 09:51:32 -05:00
|
|
|
typedef int (*func_ptr)();
|
2019-05-01 09:39:23 -05:00
|
|
|
static struct multiboot_boot_header_tag* tags;
|
2019-04-27 15:03:31 -05:00
|
|
|
|
2019-05-01 09:39:23 -05:00
|
|
|
static void read_initrd(struct multiboot_boot_header_tag* tags) {
|
|
|
|
struct multiboot_tag* tag=(struct multiboot_tag*)(tags+1);
|
|
|
|
while (tag->type!=0) {
|
|
|
|
switch (tag->type) {
|
|
|
|
case MULTIBOOT_TAG_TYPE_MODULE: {
|
|
|
|
struct multiboot_tag_module* mod=(struct multiboot_tag_module*) tag;
|
|
|
|
initrd=malloc(sizeof(char)*(mod->mod_end-mod->mod_start));
|
|
|
|
initrd_sz=mod->mod_end-mod->mod_start;
|
2019-05-05 07:27:57 -05:00
|
|
|
memcpy(initrd,(void*)(mod->mod_start+0xC0000000),mod->mod_end-mod->mod_start);
|
2019-05-01 09:39:23 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
tag=(struct multiboot_tag*)((char*)tag+((tag->size+7)&0xFFFFFFF8));
|
|
|
|
}
|
|
|
|
}
|
2019-04-27 09:51:32 -05:00
|
|
|
|
2020-07-23 11:50:23 -05:00
|
|
|
size_t getsize(const char *in) {
|
|
|
|
size_t size=0;
|
|
|
|
size_t j;
|
|
|
|
size_t count=1;
|
2019-05-23 17:38:26 -05:00
|
|
|
for (j=11;j>0;j--,count*=8) {
|
|
|
|
size+=((in[j-1]-'0')*count);
|
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
2019-05-03 08:34:22 -05:00
|
|
|
|
|
|
|
void kmain(struct multiboot_boot_header_tag* hdr) {
|
|
|
|
tags=hdr;
|
2020-07-22 19:26:55 -05:00
|
|
|
cpu_init();
|
|
|
|
serial_init();
|
|
|
|
pmem_init(tags);
|
|
|
|
paging_init();
|
2020-07-24 10:38:01 -05:00
|
|
|
isr_install();
|
|
|
|
asm volatile("sti");
|
2020-07-22 19:26:55 -05:00
|
|
|
tasking_init();
|
2019-05-22 14:18:29 -05:00
|
|
|
vga_init((char*)0xC00B8000);
|
2019-05-01 09:39:23 -05:00
|
|
|
read_initrd(tags);
|
2019-05-03 08:34:22 -05:00
|
|
|
int pos=0;
|
2020-07-23 11:50:23 -05:00
|
|
|
size_t datapos;
|
2019-07-13 10:18:41 -05:00
|
|
|
tar_header* tar_hdr;
|
2019-05-23 17:38:26 -05:00
|
|
|
for (int i=0;;i++) {
|
2019-07-13 10:18:41 -05:00
|
|
|
tar_hdr=(tar_header*)&initrd[pos];
|
|
|
|
if (tar_hdr->filename[0]=='\0') break;
|
2020-07-23 11:50:23 -05:00
|
|
|
size_t size=getsize(tar_hdr->size);
|
2019-05-23 17:38:26 -05:00
|
|
|
pos+=512;
|
2019-07-20 11:03:27 -05:00
|
|
|
if (strcmp(&tar_hdr->filename[0],"init")==0) {
|
2019-05-23 17:38:26 -05:00
|
|
|
datapos=pos;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pos+=size;
|
2019-05-24 11:52:13 -05:00
|
|
|
if (pos%512!=0) {
|
|
|
|
pos+=512-(pos%512);
|
|
|
|
}
|
2019-04-30 17:11:26 -05:00
|
|
|
}
|
2019-05-01 09:39:23 -05:00
|
|
|
elf_header header;
|
2019-05-03 08:34:22 -05:00
|
|
|
pos=datapos;
|
|
|
|
char* hdr_ptr=(char*)&header;
|
2019-05-05 07:27:57 -05:00
|
|
|
for (size_t i=0;i<sizeof(elf_header);i++) {
|
2019-05-03 08:34:22 -05:00
|
|
|
hdr_ptr[i]=initrd[pos];
|
|
|
|
pos++;
|
|
|
|
}
|
2019-05-01 09:39:23 -05:00
|
|
|
if (header.magic!=ELF_MAGIC) {
|
2019-05-03 08:34:22 -05:00
|
|
|
vga_write_string("[INFO] Invalid magic number for prog.elf\n");
|
2019-05-01 09:39:23 -05:00
|
|
|
} else {
|
2020-07-29 07:27:12 -05:00
|
|
|
void* address_space=new_address_space();
|
2019-05-01 09:39:23 -05:00
|
|
|
for (int i=0;i<header.pheader_ent_nm;i++) {
|
|
|
|
elf_pheader pheader;
|
2019-05-03 08:34:22 -05:00
|
|
|
pos=(header.prog_hdr)+(header.pheader_ent_sz*i)+datapos;
|
|
|
|
char* phdr_ptr=(char*)&pheader;
|
2019-05-05 07:27:57 -05:00
|
|
|
for (size_t i=0;i<sizeof(elf_pheader);i++) {
|
2019-05-03 08:34:22 -05:00
|
|
|
phdr_ptr[i]=initrd[pos];
|
|
|
|
pos++;
|
|
|
|
}
|
2019-05-06 08:24:57 -05:00
|
|
|
char* ptr=alloc_memory(((pheader.memsz)/4096)+1);
|
|
|
|
memset(ptr,0,pheader.memsz);
|
2019-05-01 09:39:23 -05:00
|
|
|
if (pheader.filesz>0) {
|
2019-05-03 08:34:22 -05:00
|
|
|
pos=pheader.offset+datapos;
|
2019-05-05 07:27:57 -05:00
|
|
|
for (size_t i=0;i<pheader.filesz;i++) {
|
2019-05-06 08:24:57 -05:00
|
|
|
ptr[i]=initrd[pos];
|
2019-05-03 08:34:22 -05:00
|
|
|
pos++;
|
|
|
|
}
|
2019-05-01 09:39:23 -05:00
|
|
|
}
|
2020-07-29 07:27:12 -05:00
|
|
|
copy_data(address_space,ptr,pheader.memsz,(void*)pheader.vaddr);
|
2019-05-06 08:24:57 -05:00
|
|
|
}
|
2020-07-29 10:35:04 -05:00
|
|
|
create_proc((void*)header.entry,address_space,NULL,NULL);
|
2020-07-12 14:28:58 -05:00
|
|
|
for (int i=0;i<4;i++) {
|
|
|
|
yield();
|
|
|
|
}
|
2020-07-29 08:09:53 -05:00
|
|
|
unblock_thread(1,0);
|
2020-07-12 14:28:58 -05:00
|
|
|
for (int i=0;i<4;i++) {
|
|
|
|
yield();
|
|
|
|
}
|
2019-08-25 17:33:05 -05:00
|
|
|
exit(0);
|
2019-04-30 17:11:26 -05:00
|
|
|
}
|
2019-02-09 12:52:45 -06:00
|
|
|
}
|