Compare commits
2 Commits
73f27f730b
...
2015e0e0aa
Author | SHA1 | Date | |
---|---|---|---|
2015e0e0aa | |||
13ab117b1b |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
/limine
|
/limine
|
||||||
/iso_root
|
/iso_root
|
||||||
/base_root
|
|
||||||
*.iso
|
*.iso
|
||||||
*.img
|
*.img
|
||||||
|
11
Makefile
11
Makefile
@ -1,7 +1,10 @@
|
|||||||
.PHONY: all clean prepare cleanall iso base
|
.PHONY: clean prepare cleanall iso base kernel user
|
||||||
|
|
||||||
all:
|
kernel:
|
||||||
make -C kernel all
|
make -C kernel ROOT=$(PWD) all
|
||||||
|
|
||||||
|
user:
|
||||||
|
make -C user ROOT=$(PWD) all
|
||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
if [ ! -d limine ]; then \
|
if [ ! -d limine ]; then \
|
||||||
@ -13,10 +16,10 @@ prepare:
|
|||||||
cleanall:
|
cleanall:
|
||||||
make clean
|
make clean
|
||||||
rm -rf limine
|
rm -rf limine
|
||||||
rm -rf littlefs-fuse
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
make -C kernel clean
|
make -C kernel clean
|
||||||
|
make -C user clean
|
||||||
rm -f mop2.iso base.img
|
rm -f mop2.iso base.img
|
||||||
|
|
||||||
base:
|
base:
|
||||||
|
3
base/bin/.gitignore
vendored
Normal file
3
base/bin/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!.gitkeep
|
0
base/bin/.gitkeep
Normal file
0
base/bin/.gitkeep
Normal file
@ -29,7 +29,7 @@ endif
|
|||||||
include arch/$(ARCH)/$(ARCH).mk
|
include arch/$(ARCH)/$(ARCH).mk
|
||||||
include extconf/extra.mk
|
include extconf/extra.mk
|
||||||
|
|
||||||
LDFLAGS := -nostdlib -static -T arch/$(ARCH)/link.ld $(shell $(CC) -print-libgcc-file-name)
|
LDFLAGS += -nostdlib -static -T arch/$(ARCH)/link.ld $(shell $(CC) -print-libgcc-file-name)
|
||||||
|
|
||||||
SRCFILES := $(wildcard *.c) \
|
SRCFILES := $(wildcard *.c) \
|
||||||
$(wildcard printf/*.c) \
|
$(wildcard printf/*.c) \
|
||||||
|
355
kernel/elf.h
Normal file
355
kernel/elf.h
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
#ifndef ELF_H_
|
||||||
|
#define ELF_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ELFCLASS64 2
|
||||||
|
#define ELFDATA2LSB 1
|
||||||
|
#define ELFOSABI_SYSV 0
|
||||||
|
#define EM_X86_64 62
|
||||||
|
|
||||||
|
#define SHT_NULL 0
|
||||||
|
#define SHT_PROGBITS 1
|
||||||
|
#define SHT_SYMTAB 2
|
||||||
|
#define SHT_STRTAB 3
|
||||||
|
#define SHT_RELA 4
|
||||||
|
#define SHT_HASH 5
|
||||||
|
#define SHT_DYNAMIC 6
|
||||||
|
#define SHT_NOBITS 8
|
||||||
|
#define SHT_DYNSYM 11
|
||||||
|
|
||||||
|
#define SHF_WRITE 1
|
||||||
|
#define SHF_ALLOC 2
|
||||||
|
#define SHF_EXECINSTR 4
|
||||||
|
|
||||||
|
typedef uint64_t Elf64_Addr;
|
||||||
|
typedef uint64_t Elf64_Off;
|
||||||
|
typedef uint16_t Elf64_Half;
|
||||||
|
typedef uint32_t Elf64_Word;
|
||||||
|
typedef int32_t Elf64_Sword;
|
||||||
|
typedef uint64_t Elf64_Xword;
|
||||||
|
typedef int64_t Elf64_Sxword;
|
||||||
|
|
||||||
|
typedef uint32_t Elf32_Addr;
|
||||||
|
typedef uint32_t Elf32_Off;
|
||||||
|
typedef uint16_t Elf32_Half;
|
||||||
|
typedef uint32_t Elf32_Word;
|
||||||
|
typedef int32_t Elf32_Sword;
|
||||||
|
typedef uint64_t Elf32_Xword;
|
||||||
|
typedef int64_t Elf32_Sxword;
|
||||||
|
|
||||||
|
#define EI_NIDENT (16)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT]; /* ELF identification */
|
||||||
|
Elf32_Half e_type; /* Object file type */
|
||||||
|
Elf32_Half e_machine; /* Machine type */
|
||||||
|
Elf32_Word e_version; /* Object file version */
|
||||||
|
Elf32_Addr e_entry; /* Entry point address */
|
||||||
|
Elf32_Off e_phoff; /* Program header offset */
|
||||||
|
Elf32_Off e_shoff; /* Section header offset */
|
||||||
|
Elf32_Word e_flags; /* Processor-specific flags */
|
||||||
|
Elf32_Half e_ehsize; /* ELF header size */
|
||||||
|
Elf32_Half e_phentsize; /* Size of program header entry */
|
||||||
|
Elf32_Half e_phnum; /* Number of program header entries */
|
||||||
|
Elf32_Half e_shentsize; /* Size of section header entry */
|
||||||
|
Elf32_Half e_shnum; /* Number of section header entries */
|
||||||
|
Elf32_Half e_shstrndx; /* Section name string table index */
|
||||||
|
} Elf32_Ehdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT]; /* ELF identification */
|
||||||
|
Elf64_Half e_type; /* Object file type */
|
||||||
|
Elf64_Half e_machine; /* Machine type */
|
||||||
|
Elf64_Word e_version; /* Object file version */
|
||||||
|
Elf64_Addr e_entry; /* Entry point address */
|
||||||
|
Elf64_Off e_phoff; /* Program header offset */
|
||||||
|
Elf64_Off e_shoff; /* Section header offset */
|
||||||
|
Elf64_Word e_flags; /* Processor-specific flags */
|
||||||
|
Elf64_Half e_ehsize; /* ELF header size */
|
||||||
|
Elf64_Half e_phentsize; /* Size of program header entry */
|
||||||
|
Elf64_Half e_phnum; /* Number of program header entries */
|
||||||
|
Elf64_Half e_shentsize; /* Size of section header entry */
|
||||||
|
Elf64_Half e_shnum; /* Number of section header entries */
|
||||||
|
Elf64_Half e_shstrndx; /* Section name string table index */
|
||||||
|
} Elf64_Ehdr;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ET_NONE = 0,
|
||||||
|
ET_REL = 1,
|
||||||
|
ET_EXEC = 2,
|
||||||
|
ET_DYN = 3,
|
||||||
|
ET_CORE = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { SHN_UNDEF = 0, SHN_ABS = 0xFFF1 };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Word st_name;
|
||||||
|
unsigned char st_info;
|
||||||
|
unsigned char st_other;
|
||||||
|
Elf64_Half st_shndx;
|
||||||
|
Elf64_Addr st_value;
|
||||||
|
Elf64_Xword st_size;
|
||||||
|
} Elf64_Sym;
|
||||||
|
|
||||||
|
enum { STB_GLOBAL = 1, STB_WEAK = 2, STB_GNU_UNIQUE = 10 };
|
||||||
|
|
||||||
|
enum { STT_OBJECT = 1, STT_FUNC = 2, STT_TLS = 6 };
|
||||||
|
|
||||||
|
enum {
|
||||||
|
R_X86_64_NONE = 0,
|
||||||
|
R_X86_64_64 = 1,
|
||||||
|
R_X86_64_COPY = 5,
|
||||||
|
R_X86_64_GLOB_DAT = 6,
|
||||||
|
R_X86_64_JUMP_SLOT = 7,
|
||||||
|
R_X86_64_RELATIVE = 8,
|
||||||
|
R_X86_64_DTPMOD64 = 16,
|
||||||
|
R_X86_64_DTPOFF64 = 17,
|
||||||
|
R_X86_64_TPOFF64 = 18,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
R_AARCH64_ABS64 = 257,
|
||||||
|
R_AARCH64_COPY = 1024,
|
||||||
|
R_AARCH64_GLOB_DAT = 1025,
|
||||||
|
R_AARCH64_JUMP_SLOT = 1026,
|
||||||
|
R_AARCH64_RELATIVE = 1027,
|
||||||
|
R_AARCH64_TLS_TPREL = 1030,
|
||||||
|
R_AARCH64_TLSDESC = 1031
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Addr r_offset;
|
||||||
|
uint64_t r_info;
|
||||||
|
} Elf64_Rel;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Addr r_offset;
|
||||||
|
Elf64_Xword r_info;
|
||||||
|
Elf64_Sxword r_addend;
|
||||||
|
} Elf64_Rela;
|
||||||
|
|
||||||
|
static inline Elf64_Xword ELF64_R_SYM(Elf64_Xword info) { return info >> 32; }
|
||||||
|
static inline Elf64_Xword ELF64_R_TYPE(Elf64_Xword info) {
|
||||||
|
return info & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PT_LOAD = 1,
|
||||||
|
PT_DYNAMIC = 2,
|
||||||
|
PT_INTERP = 3,
|
||||||
|
PT_NOTE = 4,
|
||||||
|
PT_PHDR = 6,
|
||||||
|
PT_TLS = 7,
|
||||||
|
PT_GNU_EH_FRAME = 0x6474E550,
|
||||||
|
PT_GNU_STACK = 0x6474E551,
|
||||||
|
PT_GNU_RELRO = 0x6474E552,
|
||||||
|
PT_GNU_PROPERTY = 0x6474E553,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { PF_X = 1, PF_W = 2, PF_R = 4 };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Word p_type; /* Type of segment */
|
||||||
|
Elf64_Word p_flags; /* Segment attributes */
|
||||||
|
Elf64_Off p_offset; /* Offset in file */
|
||||||
|
Elf64_Addr p_vaddr; /* Virtual address in memory */
|
||||||
|
Elf64_Addr p_paddr; /* Reserved */
|
||||||
|
Elf64_Xword p_filesz; /* Size of segment in file */
|
||||||
|
Elf64_Xword p_memsz; /* Size of segment in memory */
|
||||||
|
Elf64_Xword p_align; /* Alignment of segment */
|
||||||
|
} Elf64_Phdr;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DT_NULL = 0,
|
||||||
|
DT_NEEDED = 1,
|
||||||
|
DT_PLTRELSZ = 2,
|
||||||
|
DT_PLTGOT = 3,
|
||||||
|
DT_HASH = 4,
|
||||||
|
DT_STRTAB = 5,
|
||||||
|
DT_SYMTAB = 6,
|
||||||
|
DT_RELA = 7,
|
||||||
|
DT_RELASZ = 8,
|
||||||
|
DT_RELAENT = 9,
|
||||||
|
DT_STRSZ = 10,
|
||||||
|
DT_SYMENT = 11,
|
||||||
|
DT_INIT = 12,
|
||||||
|
DT_FINI = 13,
|
||||||
|
DT_SONAME = 14,
|
||||||
|
DT_RPATH = 15,
|
||||||
|
DT_SYMBOLIC = 16,
|
||||||
|
DT_REL = 17,
|
||||||
|
DT_BIND_NOW = 24,
|
||||||
|
DT_INIT_ARRAY = 25,
|
||||||
|
DT_FINI_ARRAY = 26,
|
||||||
|
DT_INIT_ARRAYSZ = 27,
|
||||||
|
DT_FINI_ARRAYSZ = 28,
|
||||||
|
DT_RUNPATH = 29,
|
||||||
|
DT_PLTREL = 20,
|
||||||
|
DT_DEBUG = 21,
|
||||||
|
DT_JMPREL = 23,
|
||||||
|
DT_FLAGS = 30,
|
||||||
|
DT_GNU_HASH = 0x6ffffef5,
|
||||||
|
DT_TLSDESC_PLT = 0x6ffffef6,
|
||||||
|
DT_TLSDESC_GOT = 0x6ffffef7,
|
||||||
|
DT_VERSYM = 0x6ffffff0,
|
||||||
|
DT_RELACOUNT = 0x6ffffff9,
|
||||||
|
DT_FLAGS_1 = 0x6ffffffb,
|
||||||
|
DT_VERDEF = 0x6ffffffc,
|
||||||
|
DT_VERDEFNUM = 0x6ffffffd,
|
||||||
|
DT_VERNEED = 0x6ffffffe,
|
||||||
|
DT_VERNEEDNUM = 0x6fffffff
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// For DT_FLAGS.
|
||||||
|
DF_SYMBOLIC = 0x02,
|
||||||
|
DF_STATIC_TLS = 0x10,
|
||||||
|
|
||||||
|
// For DT_FLAGS_1.
|
||||||
|
DF_1_NOW = 0x00000001
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Sword d_tag;
|
||||||
|
union {
|
||||||
|
Elf32_Word d_val;
|
||||||
|
Elf32_Addr d_ptr;
|
||||||
|
} d_un;
|
||||||
|
} Elf32_Dyn;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Sxword d_tag;
|
||||||
|
union {
|
||||||
|
Elf64_Xword d_val;
|
||||||
|
Elf64_Addr d_ptr;
|
||||||
|
} d_un;
|
||||||
|
} Elf64_Dyn;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
Elf64_Word sh_name;
|
||||||
|
Elf64_Word sh_type;
|
||||||
|
Elf64_Xword sh_flags;
|
||||||
|
Elf64_Addr sh_addr;
|
||||||
|
Elf64_Off sh_offset;
|
||||||
|
Elf64_Xword sh_size;
|
||||||
|
Elf64_Word sh_link;
|
||||||
|
Elf64_Word sh_info;
|
||||||
|
Elf64_Xword sh_addralign;
|
||||||
|
Elf64_Xword sh_entsize;
|
||||||
|
} Elf64_Shdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word n_namesz;
|
||||||
|
Elf32_Word n_descsz;
|
||||||
|
Elf32_Word n_type;
|
||||||
|
} Elf32_Nhdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf64_Word n_namesz;
|
||||||
|
Elf64_Word n_descsz;
|
||||||
|
Elf64_Word n_type;
|
||||||
|
} Elf64_Nhdr;
|
||||||
|
|
||||||
|
/* ST_TYPE (subfield of st_info) values (symbol type) */
|
||||||
|
#define STT_NOTYPE 0
|
||||||
|
#define STT_OBJECT 1
|
||||||
|
#define STT_FUNC 2
|
||||||
|
#define STT_SECTION 3
|
||||||
|
#define STT_FILE 4
|
||||||
|
|
||||||
|
/* ST_BIND (subfield of st_info) values (symbol binding) */
|
||||||
|
#define STB_LOCAL 0
|
||||||
|
#define STB_GLOBAL 1
|
||||||
|
#define STB_WEAK 2
|
||||||
|
|
||||||
|
/* sh_type (section type) values */
|
||||||
|
#define SHT_NULL 0
|
||||||
|
#define SHT_PROGBITS 1
|
||||||
|
#define SHT_SYMTAB 2
|
||||||
|
#define SHT_STRTAB 3
|
||||||
|
#define SHT_RELA 4
|
||||||
|
#define SHT_NOBITS 8
|
||||||
|
#define SHT_REL 9
|
||||||
|
#define SHT_INIT_ARRAY 14
|
||||||
|
#define SHT_FINI_ARRAY 15
|
||||||
|
#define SHT_SYMTAB_SHNDX 18
|
||||||
|
|
||||||
|
/* special section indices */
|
||||||
|
#define SHN_UNDEF 0
|
||||||
|
#define SHN_LORESERVE 0xff00
|
||||||
|
#define SHN_COMMON 0xfff2
|
||||||
|
#define SHN_XINDEX 0xffff
|
||||||
|
#define SHN_HIRESERVE 0xff00
|
||||||
|
|
||||||
|
/* values for e_machine */
|
||||||
|
#define EM_NONE 0
|
||||||
|
#define EM_SPARC 2
|
||||||
|
#define EM_386 3
|
||||||
|
#define EM_PPC 20
|
||||||
|
#define EM_PPC64 21
|
||||||
|
#define EM_X86_64 62
|
||||||
|
|
||||||
|
/* e_indent constants */
|
||||||
|
#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'
|
||||||
|
|
||||||
|
#define EI_CLASS 4
|
||||||
|
#define ELFCLASSNONE 0
|
||||||
|
#define ELFCLASS32 1
|
||||||
|
#define ELFCLASS64 2
|
||||||
|
#define ELFCLASSNUM 3
|
||||||
|
|
||||||
|
#define EI_DATA 5
|
||||||
|
#define ELFDATANONE 0
|
||||||
|
#define ELFDATA2LSB 1
|
||||||
|
#define ELFDATA2MSB 2
|
||||||
|
#define ELFDATANUM 3
|
||||||
|
|
||||||
|
#define AT_NULL 0
|
||||||
|
#define AT_IGNORE 1
|
||||||
|
#define AT_EXECFD 2
|
||||||
|
#define AT_PHDR 3
|
||||||
|
#define AT_PHENT 4
|
||||||
|
#define AT_PHNUM 5
|
||||||
|
#define AT_PAGESZ 6
|
||||||
|
#define AT_BASE 7
|
||||||
|
#define AT_FLAGS 8
|
||||||
|
#define AT_ENTRY 9
|
||||||
|
#define AT_NOTELF 10
|
||||||
|
#define AT_UID 11
|
||||||
|
#define AT_EUID 12
|
||||||
|
#define AT_GID 13
|
||||||
|
#define AT_EGID 14
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t entry;
|
||||||
|
uint64_t phdr;
|
||||||
|
uint64_t phent;
|
||||||
|
uint64_t phnum;
|
||||||
|
} ElfAuxval;
|
||||||
|
|
||||||
|
#endif // ELF_H_
|
@ -8,6 +8,6 @@
|
|||||||
#define E_OUTOFBOUNDS -4
|
#define E_OUTOFBOUNDS -4
|
||||||
#define E_UNKNOWN_SDTYPE -5
|
#define E_UNKNOWN_SDTYPE -5
|
||||||
#define E_TODO -6
|
#define E_TODO -6
|
||||||
#define E_GENERIC_ERROR -7
|
#define E_BADIO -7
|
||||||
|
|
||||||
#endif // ERRORS_H_
|
#endif // ERRORS_H_
|
||||||
|
@ -27,6 +27,22 @@ int32_t kvfs_read(struct VfsMountPoint *vmp, const char *key, uint8_t *const buf
|
|||||||
return E_OK;
|
return E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t kvfs_stat(struct VfsMountPoint *vmp, const char *key, struct VfsStat *stat) {
|
||||||
|
KvfsNode *node = NULL;
|
||||||
|
|
||||||
|
spinlock_acquire(&vmp->spinlock);
|
||||||
|
HSHTB_GET(&vmp->fs.kvfs, nodes, (char *)key, key_, node);
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
|
||||||
|
if (node == NULL) {
|
||||||
|
return E_NOENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat->type = VFS_TYPE_FILE;
|
||||||
|
stat->size = KVFS_BUFFER_SIZE;
|
||||||
|
return E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t kvfs_write(struct VfsMountPoint *vmp, const char *key, const uint8_t *const buffer, size_t n, size_t off) {
|
int32_t kvfs_write(struct VfsMountPoint *vmp, const char *key, const uint8_t *const buffer, size_t n, size_t off) {
|
||||||
KvfsNode *node = NULL;
|
KvfsNode *node = NULL;
|
||||||
|
|
||||||
@ -85,7 +101,7 @@ int32_t kvfs_create(struct VfsMountPoint *vmp, const char *path, int32_t type) {
|
|||||||
bool kvfs_check(void) {
|
bool kvfs_check(void) {
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
|
|
||||||
ret = vfs_create("tmpvars", "hello", VFS_CREATE_FILE);
|
ret = vfs_create("tmpvars", "hello", VFS_TYPE_FILE);
|
||||||
if (ret != E_OK) return false;
|
if (ret != E_OK) return false;
|
||||||
|
|
||||||
char *hello = "WAWAWAWA!!!";
|
char *hello = "WAWAWAWA!!!";
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct VfsMountPoint;
|
struct VfsMountPoint;
|
||||||
|
struct VfsStat;
|
||||||
|
|
||||||
#define KVFS_NODE_KEY_MAX 128
|
#define KVFS_NODE_KEY_MAX 128
|
||||||
#define KVFS_NODES_MAX 256
|
#define KVFS_NODES_MAX 256
|
||||||
@ -21,6 +22,7 @@ typedef struct {
|
|||||||
} Kvfs;
|
} Kvfs;
|
||||||
|
|
||||||
int32_t kvfs_read(struct VfsMountPoint *vmp, const char *key, uint8_t *const buffer, size_t n, size_t off);
|
int32_t kvfs_read(struct VfsMountPoint *vmp, const char *key, uint8_t *const buffer, size_t n, size_t off);
|
||||||
|
int32_t kvfs_stat(struct VfsMountPoint *vmp, const char *key, struct VfsStat *stat);
|
||||||
int32_t kvfs_write(struct VfsMountPoint *vmp, const char *key, const uint8_t *const buffer, size_t n, size_t off);
|
int32_t kvfs_write(struct VfsMountPoint *vmp, const char *key, const uint8_t *const buffer, size_t n, size_t off);
|
||||||
int32_t kvfs_remove(struct VfsMountPoint *vmp, const char *key);
|
int32_t kvfs_remove(struct VfsMountPoint *vmp, const char *key);
|
||||||
int32_t kvfs_create(struct VfsMountPoint *vmp, const char *path, int32_t type);
|
int32_t kvfs_create(struct VfsMountPoint *vmp, const char *path, int32_t type);
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#define CHECK(err) \
|
#define CHECK(err) \
|
||||||
do { \
|
do { \
|
||||||
int ok = (err); \
|
int ok = (err); \
|
||||||
kprintf("ok = %d\n", ok); \
|
|
||||||
if (ok < 0) goto bad; \
|
if (ok < 0) goto bad; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
@ -27,7 +26,29 @@ int32_t littlefs_read(struct VfsMountPoint *vmp, const char *path, uint8_t *cons
|
|||||||
return E_OK;
|
return E_OK;
|
||||||
bad:
|
bad:
|
||||||
spinlock_release(&vmp->spinlock);
|
spinlock_release(&vmp->spinlock);
|
||||||
return E_GENERIC_ERROR;
|
return E_BADIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, struct VfsStat *stat) {
|
||||||
|
spinlock_acquire(&vmp->spinlock);
|
||||||
|
|
||||||
|
LittleFs *fs = &vmp->fs.littlefs;
|
||||||
|
struct lfs_info stat1;
|
||||||
|
CHECK(lfs_stat(&fs->instance, path, &stat1));
|
||||||
|
|
||||||
|
if (stat1.type == LFS_TYPE_REG) {
|
||||||
|
stat->type = VFS_TYPE_FILE;
|
||||||
|
} else if (stat1.type == LFS_TYPE_DIR) {
|
||||||
|
stat->type = VFS_TYPE_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat->size = stat1.size;
|
||||||
|
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_OK;
|
||||||
|
bad:
|
||||||
|
spinlock_release(&vmp->spinlock);
|
||||||
|
return E_BADIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off) {
|
int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off) {
|
||||||
@ -44,7 +65,7 @@ int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_
|
|||||||
return E_OK;
|
return E_OK;
|
||||||
bad:
|
bad:
|
||||||
spinlock_release(&vmp->spinlock);
|
spinlock_release(&vmp->spinlock);
|
||||||
return E_GENERIC_ERROR;
|
return E_BADIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path) {
|
int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path) {
|
||||||
@ -57,7 +78,7 @@ int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path) {
|
|||||||
return E_OK;
|
return E_OK;
|
||||||
bad:
|
bad:
|
||||||
spinlock_release(&vmp->spinlock);
|
spinlock_release(&vmp->spinlock);
|
||||||
return E_GENERIC_ERROR;
|
return E_BADIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t littlefs_cleanup(struct VfsMountPoint *vmp) {
|
int32_t littlefs_cleanup(struct VfsMountPoint *vmp) {
|
||||||
@ -67,7 +88,7 @@ int32_t littlefs_cleanup(struct VfsMountPoint *vmp) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
err = lfs_unmount(&vmp->fs.littlefs.instance);
|
err = lfs_unmount(&vmp->fs.littlefs.instance);
|
||||||
if (err < 0) { return E_GENERIC_ERROR; }
|
if (err < 0) { return E_BADIO; }
|
||||||
return E_OK;
|
return E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,10 +97,10 @@ int32_t littlefs_create(struct VfsMountPoint *vmp, const char *path, int32_t typ
|
|||||||
|
|
||||||
LittleFs *fs = &vmp->fs.littlefs;
|
LittleFs *fs = &vmp->fs.littlefs;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VFS_CREATE_DIR:
|
case VFS_TYPE_DIR:
|
||||||
CHECK(lfs_mkdir(&fs->instance, path));
|
CHECK(lfs_mkdir(&fs->instance, path));
|
||||||
break;
|
break;
|
||||||
case VFS_CREATE_FILE: {
|
case VFS_TYPE_FILE: {
|
||||||
lfs_file_t file;
|
lfs_file_t file;
|
||||||
CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_CREAT | LFS_O_WRONLY));
|
CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_CREAT | LFS_O_WRONLY));
|
||||||
CHECK(lfs_file_close(&fs->instance, &file));
|
CHECK(lfs_file_close(&fs->instance, &file));
|
||||||
@ -90,7 +111,7 @@ int32_t littlefs_create(struct VfsMountPoint *vmp, const char *path, int32_t typ
|
|||||||
return E_OK;
|
return E_OK;
|
||||||
bad:
|
bad:
|
||||||
spinlock_release(&vmp->spinlock);
|
spinlock_release(&vmp->spinlock);
|
||||||
return E_GENERIC_ERROR;
|
return E_BADIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool littlefs_check(void) {
|
bool littlefs_check(void) {
|
||||||
|
@ -8,12 +8,14 @@
|
|||||||
#define LITTLEFS_BLOCK_SIZE 4096
|
#define LITTLEFS_BLOCK_SIZE 4096
|
||||||
|
|
||||||
struct VfsMountPoint;
|
struct VfsMountPoint;
|
||||||
|
struct VfsStat;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
lfs_t instance;
|
lfs_t instance;
|
||||||
} LittleFs;
|
} LittleFs;
|
||||||
|
|
||||||
int32_t littlefs_read(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off);
|
int32_t littlefs_read(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off);
|
||||||
|
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, struct VfsStat *stat);
|
||||||
int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off);
|
int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off);
|
||||||
int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path);
|
int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path);
|
||||||
int32_t littlefs_create(struct VfsMountPoint *vmp, const char *path, int32_t type);
|
int32_t littlefs_create(struct VfsMountPoint *vmp, const char *path, int32_t type);
|
||||||
|
@ -19,6 +19,7 @@ size_t hal_strspn(const char *s, const char *accept);
|
|||||||
char *hal_strcpy(char *dest, const char *src);
|
char *hal_strcpy(char *dest, const char *src);
|
||||||
char *hal_strchr(const char *s, int c);
|
char *hal_strchr(const char *s, int c);
|
||||||
void hal_init_withmalloc(void);
|
void hal_init_withmalloc(void);
|
||||||
|
void hal_wait(uint32_t ms);
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
# define HAL_PAGE_SIZE 0x1000
|
# define HAL_PAGE_SIZE 0x1000
|
||||||
|
@ -34,3 +34,7 @@ void hal_init_withmalloc(void) {
|
|||||||
hal_intr_disable();
|
hal_intr_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hal_wait(uint32_t ms) {
|
||||||
|
pit_wait(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include "bootinfo/bootinfo.h"
|
#include "bootinfo/bootinfo.h"
|
||||||
#include "pmm/pmm.h"
|
#include "pmm/pmm.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
|
#include "proc/proc.h"
|
||||||
|
#include "kprintf.h"
|
||||||
|
|
||||||
PgTable *KERNEL_CR3 = NULL;
|
PgTable *KERNEL_CR3 = NULL;
|
||||||
|
|
||||||
@ -73,7 +75,7 @@ void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t si
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags) {
|
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size) {
|
||||||
if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PG_PRESENT != 0) {
|
if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PG_PRESENT != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -96,6 +98,21 @@ void hal_vmm_switch_pd(PgTable *cr3) {
|
|||||||
hal_loadpd(cr3);
|
hal_loadpd(cr3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PgTable *hal_vmm_userproc_pml4(Proc *proc) {
|
||||||
|
uint8_t *cr3 = pmm_alloc(1);
|
||||||
|
PgTable *pml4 = (PgTable *)VIRT(cr3);
|
||||||
|
hal_memset(pml4, 0, HAL_PAGE_SIZE);
|
||||||
|
|
||||||
|
PgTable *kcr3 = VIRT(KERNEL_CR3);
|
||||||
|
|
||||||
|
for (size_t i = 256; i < 512; i++) {
|
||||||
|
pml4->ents[i] = kcr3->ents[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (PgTable *)cr3;
|
||||||
|
}
|
||||||
|
|
||||||
void hal_vmm_init(void) {
|
void hal_vmm_init(void) {
|
||||||
KERNEL_CR3 = hal_vmm_current_cr3();
|
KERNEL_CR3 = hal_vmm_current_cr3();
|
||||||
|
kprintf("KERNEL_CR3 = %p\n", KERNEL_CR3);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "compiler/attr.h"
|
#include "compiler/attr.h"
|
||||||
|
|
||||||
|
struct Proc;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HAL_PG_PRESENT = 1<<0,
|
HAL_PG_PRESENT = 1<<0,
|
||||||
HAL_PG_RW = 1<<1,
|
HAL_PG_RW = 1<<1,
|
||||||
@ -43,6 +45,7 @@ void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr);
|
|||||||
void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags);
|
void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags);
|
||||||
PgTable *hal_vmm_current_cr3(void);
|
PgTable *hal_vmm_current_cr3(void);
|
||||||
void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags);
|
void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags);
|
||||||
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags);
|
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size);
|
||||||
|
PgTable *hal_vmm_userproc_pml4(struct Proc *proc);
|
||||||
|
|
||||||
#endif // HAL_VMM_H_
|
#endif // HAL_VMM_H_
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include "hal/hal.h"
|
#include "hal/hal.h"
|
||||||
#include "vmm/vmm.h"
|
#include "vmm/vmm.h"
|
||||||
#include "spinlock/spinlock.h"
|
#include "spinlock/spinlock.h"
|
||||||
@ -8,15 +9,84 @@
|
|||||||
#include "pmm/pmm.h"
|
#include "pmm/pmm.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
|
#include "elf.h"
|
||||||
|
#include "errors.h"
|
||||||
|
#include "vfs/vfs.h"
|
||||||
|
#include "bootinfo/bootinfo.h"
|
||||||
|
|
||||||
#define PROC_REAPER_FREQ 30
|
#define PROC_REAPER_FREQ 30
|
||||||
|
|
||||||
|
#define PROC_DIE() \
|
||||||
|
do { \
|
||||||
|
proc_killself(); \
|
||||||
|
for(;;); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
uint64_t pids = 0;
|
uint64_t pids = 0;
|
||||||
uint64_t sched_ticks = 0;
|
uint64_t sched_ticks = 0;
|
||||||
|
|
||||||
Procs PROCS;
|
Procs PROCS;
|
||||||
|
|
||||||
|
bool proc_checkelf(uint8_t *elf) {
|
||||||
|
if (elf[0] != 0x7f || elf[1] != 'E' || elf[2] != 'L' || elf[3] != 'F') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) {
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
PgTable *vas = proc->platformdata.cr3;
|
||||||
|
#endif
|
||||||
|
ElfAuxval aux = {0};
|
||||||
|
|
||||||
|
Elf64_Ehdr *elfhdr = (Elf64_Ehdr *)data;
|
||||||
|
aux.entry = elfhdr->e_entry;
|
||||||
|
aux.phnum = elfhdr->e_phnum;
|
||||||
|
aux.phent = elfhdr->e_phentsize;
|
||||||
|
|
||||||
|
for (uint64_t seg = 0; seg < elfhdr->e_phnum; seg++) {
|
||||||
|
Elf64_Phdr *phdr = (Elf64_Phdr *)(data + elfhdr->e_phoff + (elfhdr->e_phentsize * seg));
|
||||||
|
|
||||||
|
switch (phdr->p_type) {
|
||||||
|
case PT_PHDR: {
|
||||||
|
aux.phdr = (uint64_t)phdr->p_vaddr;
|
||||||
|
} break;
|
||||||
|
case PT_LOAD: {
|
||||||
|
uint64_t off = phdr->p_vaddr & (HAL_PAGE_SIZE - 1);
|
||||||
|
uint64_t blocks = (phdr->p_memsz / HAL_PAGE_SIZE) + 1;
|
||||||
|
|
||||||
|
uint8_t *physaddr = pmm_alloc(blocks);
|
||||||
|
uint8_t *virtaddr = (uint8_t *)(phdr->p_vaddr - off);
|
||||||
|
|
||||||
|
hal_memset(VIRT(physaddr), 0, phdr->p_memsz);
|
||||||
|
hal_memcpy(VIRT(physaddr) + off, (data + phdr->p_offset), phdr->p_filesz);
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
uint32_t pgflags = HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT;
|
||||||
|
hal_vmm_map_range(VIRT(vas), virtaddr, physaddr, blocks * HAL_PAGE_SIZE, pgflags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VasRange *range = dlmalloc(sizeof(*range));
|
||||||
|
range->virtstart = virtaddr;
|
||||||
|
range->physstart = physaddr;
|
||||||
|
range->size = blocks * HAL_PAGE_SIZE;
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
range->pgflags = pgflags;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LL_APPEND(proc->vas, range);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aux;
|
||||||
|
}
|
||||||
|
|
||||||
Proc *proc_spawnkern(void (*ent)(void), char *name) {
|
Proc *proc_spawnkern(void (*ent)(void), char *name) {
|
||||||
|
if (pids >= PROC_MAX) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Proc *proc = dlmalloc(sizeof(*proc));
|
Proc *proc = dlmalloc(sizeof(*proc));
|
||||||
if (proc == NULL) {
|
if (proc == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -45,6 +115,56 @@ Proc *proc_spawnkern(void (*ent)(void), char *name) {
|
|||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Proc *proc_spawnuser(char *mountpoint, char *path) {
|
||||||
|
VfsStat stat;
|
||||||
|
if (vfs_stat(mountpoint, path, &stat) != E_OK) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (stat.type != VFS_TYPE_FILE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *data = dlmalloc(stat.size);
|
||||||
|
if (vfs_read(mountpoint, path, data, stat.size, 0) != E_OK) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Proc *proc = dlmalloc(sizeof(*proc));
|
||||||
|
hal_memset(proc, 0, sizeof(*proc));
|
||||||
|
ksprintf(proc->name, "%s:%s", mountpoint, path);
|
||||||
|
|
||||||
|
uint8_t *sp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
|
||||||
|
uint8_t *spbase = sp - PROC_STACKSIZE;
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
proc->platformdata.kstack = sp;
|
||||||
|
hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe));
|
||||||
|
|
||||||
|
proc->platformdata.cr3 = hal_vmm_userproc_pml4(proc);
|
||||||
|
uint32_t flags = HAL_PG_RW | HAL_PG_USER | HAL_PG_PRESENT;
|
||||||
|
hal_vmm_map_range(VIRT(proc->platformdata.cr3), spbase, spbase, PROC_STACKSIZE, flags);
|
||||||
|
VasRange *range = dlmalloc(sizeof(*range));
|
||||||
|
range->virtstart = spbase;
|
||||||
|
range->physstart = spbase;
|
||||||
|
range->size = PROC_STACKSIZE;
|
||||||
|
range->pgflags = flags;
|
||||||
|
|
||||||
|
LL_APPEND(proc->vas, range);
|
||||||
|
|
||||||
|
ElfAuxval aux = proc_load_elf_segs(proc, data);
|
||||||
|
|
||||||
|
proc->platformdata.trapframe.ss = 0x20 | 0x3;
|
||||||
|
proc->platformdata.trapframe.rsp = (uint64_t)VIRT(sp);
|
||||||
|
proc->platformdata.trapframe.rflags = 0x202;
|
||||||
|
proc->platformdata.trapframe.cs = 0x18 | 0x3;
|
||||||
|
proc->platformdata.trapframe.rip = aux.entry;
|
||||||
|
#endif
|
||||||
|
proc->state = PROC_READY;
|
||||||
|
proc->pid = pids++;
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
void proc_register(Proc *proc) {
|
void proc_register(Proc *proc) {
|
||||||
spinlock_acquire(&PROCS.spinlock);
|
spinlock_acquire(&PROCS.spinlock);
|
||||||
LL_APPEND(PROCS.procs, proc);
|
LL_APPEND(PROCS.procs, proc);
|
||||||
@ -57,11 +177,7 @@ Proc *proc_nextready(void) {
|
|||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void proc_sched(void *cpustate) {
|
void proc_reaper(void) {
|
||||||
hal_intr_disable();
|
|
||||||
sched_ticks++;
|
|
||||||
|
|
||||||
if (sched_ticks % PROC_REAPER_FREQ == 0) {
|
|
||||||
Proc *head = PROCS.procs;
|
Proc *head = PROCS.procs;
|
||||||
while (head) {
|
while (head) {
|
||||||
if (head->state == PROC_ZOMBIE) {
|
if (head->state == PROC_ZOMBIE) {
|
||||||
@ -69,12 +185,45 @@ void proc_sched(void *cpustate) {
|
|||||||
head = head->next;
|
head = head->next;
|
||||||
|
|
||||||
LL_REMOVE(PROCS.procs, zombie);
|
LL_REMOVE(PROCS.procs, zombie);
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
pmm_free((uintptr_t)(zombie->platformdata.kstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
|
pmm_free((uintptr_t)(zombie->platformdata.kstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!zombie->kern) {
|
||||||
|
VasRange *vashead = zombie->vas;
|
||||||
|
size_t i = 0;
|
||||||
|
while (vashead) {
|
||||||
|
VasRange *tmp = vashead;
|
||||||
|
vashead = vashead->next;
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
hal_vmm_unmap_range(zombie->platformdata.cr3, tmp->virtstart, tmp->physstart, tmp->size);
|
||||||
|
#endif
|
||||||
|
// first pmm mapping is for the elf itself
|
||||||
|
if (i == 0) {
|
||||||
|
pmm_free((uintptr_t)tmp->physstart, tmp->size / HAL_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
dlfree(tmp);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
pmm_free((uintptr_t)zombie->platformdata.cr3, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
dlfree(zombie);
|
dlfree(zombie);
|
||||||
} else {
|
} else {
|
||||||
head = head->next;
|
head = head->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void proc_sched(void *cpustate) {
|
||||||
|
hal_intr_disable();
|
||||||
|
sched_ticks++;
|
||||||
|
|
||||||
|
if (sched_ticks % PROC_REAPER_FREQ == 0) {
|
||||||
|
proc_reaper();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
@ -110,35 +259,18 @@ void proc_idle(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int a = 0;
|
void proc_status(void) {
|
||||||
|
|
||||||
void proc_print(void) {
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
for (volatile size_t i = 0; i < 0x1000000; i++) {
|
spinlock_acquire(&PROCS.spinlock);
|
||||||
|
Proc *head = PROCS.procs;
|
||||||
|
while (head) {
|
||||||
|
kprintf("%s %s\n", head->kern ? "kern" : "user", head->name);
|
||||||
|
head = head->next;
|
||||||
}
|
}
|
||||||
|
kprintf("\n\n");
|
||||||
|
spinlock_release(&PROCS.spinlock);
|
||||||
|
|
||||||
if (a == 10) {
|
hal_wait(3 * 1000);
|
||||||
proc_killself();
|
|
||||||
for(;;);
|
|
||||||
}
|
|
||||||
kprintf("A");
|
|
||||||
a++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int b = 0;
|
|
||||||
|
|
||||||
void proc_print2(void) {
|
|
||||||
for (;;) {
|
|
||||||
for (volatile size_t i = 0; i < 0x1000000; i++) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b == 20) {
|
|
||||||
proc_killself();
|
|
||||||
for(;;);
|
|
||||||
}
|
|
||||||
kprintf("B");
|
|
||||||
b++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,8 +282,8 @@ void proc_init(void) {
|
|||||||
proc_register(idle);
|
proc_register(idle);
|
||||||
PROCS.current = idle;
|
PROCS.current = idle;
|
||||||
|
|
||||||
proc_register(proc_spawnkern(&proc_print, "print"));
|
proc_register(proc_spawnkern(&proc_status, "status"));
|
||||||
proc_register(proc_spawnkern(&proc_print2, "print"));
|
proc_register(proc_spawnuser("base", "/bin/hello"));
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
hal_switchproc(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3);
|
hal_switchproc(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3);
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#define PROC_STACKBLOCKS 32
|
#define PROC_STACKBLOCKS 32
|
||||||
#define PROC_STACKSIZE (PROC_STACKBLOCKS * BITMAP_BLOCK_SIZE)
|
#define PROC_STACKSIZE (PROC_STACKBLOCKS * BITMAP_BLOCK_SIZE)
|
||||||
|
|
||||||
|
#define PROC_MAX 0x100 // max amount of processes
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROC_READY,
|
PROC_READY,
|
||||||
PROC_RUNNING,
|
PROC_RUNNING,
|
||||||
@ -38,7 +40,9 @@ typedef struct {
|
|||||||
extern Procs PROCS;
|
extern Procs PROCS;
|
||||||
|
|
||||||
void proc_init(void);
|
void proc_init(void);
|
||||||
|
void proc_register(Proc *proc);
|
||||||
Proc *proc_spawnkern(void (*ent)(void), char *name);
|
Proc *proc_spawnkern(void (*ent)(void), char *name);
|
||||||
|
Proc *proc_spawnuser(char *mountpoint, char *path);
|
||||||
void proc_sched(void *cpustate);
|
void proc_sched(void *cpustate);
|
||||||
|
|
||||||
#endif // PROC_PROC_H_
|
#endif // PROC_PROC_H_
|
||||||
|
@ -18,6 +18,7 @@ VfsTable VFS_TABLE;
|
|||||||
|
|
||||||
void vfs_init_kvfs(VfsMountPoint *mp) {
|
void vfs_init_kvfs(VfsMountPoint *mp) {
|
||||||
mp->read = &kvfs_read;
|
mp->read = &kvfs_read;
|
||||||
|
mp->stat = &kvfs_stat;
|
||||||
mp->write = &kvfs_write;
|
mp->write = &kvfs_write;
|
||||||
mp->remove = &kvfs_remove;
|
mp->remove = &kvfs_remove;
|
||||||
mp->check = &kvfs_check;
|
mp->check = &kvfs_check;
|
||||||
@ -52,6 +53,7 @@ void vfs_init_littlefs(VfsMountPoint *mp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mp->read = &littlefs_read;
|
mp->read = &littlefs_read;
|
||||||
|
mp->stat = &littlefs_stat;
|
||||||
mp->write = &littlefs_write;
|
mp->write = &littlefs_write;
|
||||||
mp->remove = &littlefs_remove;
|
mp->remove = &littlefs_remove;
|
||||||
mp->check = &littlefs_check;
|
mp->check = &littlefs_check;
|
||||||
@ -123,6 +125,20 @@ int32_t vfs_read(char *mountpoint, const char *path, uint8_t *const buffer, size
|
|||||||
return mp->read(mp, path, buffer, n, off);
|
return mp->read(mp, path, buffer, n, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat) {
|
||||||
|
VfsMountPoint *mp = NULL;
|
||||||
|
|
||||||
|
spinlock_acquire(&VFS_TABLE.spinlock);
|
||||||
|
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
|
||||||
|
spinlock_release(&VFS_TABLE.spinlock);
|
||||||
|
|
||||||
|
if (mp == NULL) {
|
||||||
|
return E_NOENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mp->stat(mp, path, stat);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t vfs_create(char *mountpoint, const char *path, int32_t type) {
|
int32_t vfs_create(char *mountpoint, const char *path, int32_t type) {
|
||||||
VfsMountPoint *mp = NULL;
|
VfsMountPoint *mp = NULL;
|
||||||
|
|
||||||
|
@ -23,10 +23,15 @@ static const char *vfs_strings[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VFS_CREATE_DIR,
|
VFS_TYPE_DIR,
|
||||||
VFS_CREATE_FILE,
|
VFS_TYPE_FILE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct VfsStat {
|
||||||
|
size_t size;
|
||||||
|
int32_t type;
|
||||||
|
} VfsStat;
|
||||||
|
|
||||||
typedef struct VfsMountPoint {
|
typedef struct VfsMountPoint {
|
||||||
bool taken;
|
bool taken;
|
||||||
uint8_t label[VFS_MOUNTPOINT_LABEL_MAX];
|
uint8_t label[VFS_MOUNTPOINT_LABEL_MAX];
|
||||||
@ -34,6 +39,7 @@ typedef struct VfsMountPoint {
|
|||||||
StoreDev *backingsd;
|
StoreDev *backingsd;
|
||||||
|
|
||||||
int32_t (*read)(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off);
|
int32_t (*read)(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off);
|
||||||
|
int32_t (*stat)(struct VfsMountPoint *vmp, const char *path, struct VfsStat *stat);
|
||||||
int32_t (*write)(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off);
|
int32_t (*write)(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off);
|
||||||
int32_t (*remove)(struct VfsMountPoint *vmp, const char *path);
|
int32_t (*remove)(struct VfsMountPoint *vmp, const char *path);
|
||||||
int32_t (*create)(struct VfsMountPoint *vmp, const char *path, int32_t type);
|
int32_t (*create)(struct VfsMountPoint *vmp, const char *path, int32_t type);
|
||||||
@ -56,9 +62,11 @@ extern VfsTable VFS_TABLE;
|
|||||||
|
|
||||||
void vfs_init(void);
|
void vfs_init(void);
|
||||||
int32_t vfs_read(char *mountpoint, const char *path, uint8_t *const buffer, size_t n, size_t off);
|
int32_t vfs_read(char *mountpoint, const char *path, uint8_t *const buffer, size_t n, size_t off);
|
||||||
|
int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat);
|
||||||
int32_t vfs_write(char *mountpoint, const char *path, const uint8_t *const buffer, size_t n, size_t off);
|
int32_t vfs_write(char *mountpoint, const char *path, const uint8_t *const buffer, size_t n, size_t off);
|
||||||
int32_t vfs_remove(char *mountpoint, const char *path);
|
int32_t vfs_remove(char *mountpoint, const char *path);
|
||||||
int32_t vfs_create(char *mountpoint, const char *path, int32_t type);
|
int32_t vfs_create(char *mountpoint, const char *path, int32_t type);
|
||||||
int32_t vfs_unmount(char *mountpoint);
|
int32_t vfs_unmount(char *mountpoint);
|
||||||
|
|
||||||
|
|
||||||
#endif // VFS_VFS_H_
|
#endif // VFS_VFS_H_
|
||||||
|
@ -35,10 +35,10 @@ void vmm_map_kern_range(void *virtstart, void *physstart, size_t size, uint32_t
|
|||||||
spinlock_release(&VIRT_MEM.spinlock);
|
spinlock_release(&VIRT_MEM.spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmm_unmap_kern_range(void *virtstart, void *physstart, size_t size, uint32_t flags) {
|
void vmm_unmap_kern_range(void *virtstart, void *physstart, size_t size) {
|
||||||
spinlock_acquire(&VIRT_MEM.spinlock);
|
spinlock_acquire(&VIRT_MEM.spinlock);
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
hal_vmm_unmap_range(KERNEL_CR3, virtstart, physstart, size, flags);
|
hal_vmm_unmap_range(KERNEL_CR3, virtstart, physstart, size);
|
||||||
#endif
|
#endif
|
||||||
spinlock_release(&VIRT_MEM.spinlock);
|
spinlock_release(&VIRT_MEM.spinlock);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
make -B && make base && make iso
|
make -B kernel && make -B user && make base && make iso
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
rm -f base.img
|
rm -f base.img
|
||||||
rm -rf base_root
|
cat user/FILES.txt | while read line; do cp -v $line base/bin; done
|
||||||
mkdir -p base_root
|
mklittlefs -c base -b 4096 -s $((1<<20)) base.img
|
||||||
mklittlefs -c base_root -b 4096 -s $((1<<20)) base.img
|
|
||||||
|
1
user/.gitignore
vendored
Normal file
1
user/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
FILES.txt
|
14
user/Makefile
Normal file
14
user/Makefile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
CURRENT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
APP_DIR := $(shell find . -mindepth 1 -maxdepth 1 -type d -not -path "./arch")
|
||||||
|
|
||||||
|
all:
|
||||||
|
rm -f FILES.txt
|
||||||
|
touch FILES.txt
|
||||||
|
for dir in $(APP_DIR); do make -C $$dir FILES=$(CURRENT_DIR)/FILES.txt all; done
|
||||||
|
|
||||||
|
clean:
|
||||||
|
for dir in $(APP_DIR); do make -C $$dir clean; done
|
||||||
|
|
9
user/Makefile.inc
Normal file
9
user/Makefile.inc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
ARCH ?= x86_64
|
||||||
|
|
||||||
|
CFLAGS := -ffreestanding -Wall -Wextra -g -fcommon -nostdinc
|
||||||
|
|
||||||
|
CURRENT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||||
|
|
||||||
|
include $(CURRENT_DIR)/arch/$(ARCH)/$(ARCH).mk
|
||||||
|
|
||||||
|
LDFLAGS += -nostdlib -static $(shell $(CC) -print-libgcc-file-name) -T $(CURRENT_DIR)/arch/$(ARCH)/link.ld
|
26
user/arch/x86_64/link.ld
Normal file
26
user/arch/x86_64/link.ld
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/* . = 0xffff000000000000; */
|
||||||
|
. = 0x0000000000000000;
|
||||||
|
|
||||||
|
.rodata ALIGN(4K):
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.text ALIGN(4K):
|
||||||
|
{
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data ALIGN(4K):
|
||||||
|
{
|
||||||
|
*(.data .data.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss ALIGN(4K):
|
||||||
|
{
|
||||||
|
*(.bss .bss.*)
|
||||||
|
}
|
||||||
|
}
|
22
user/arch/x86_64/x86_64.mk
Normal file
22
user/arch/x86_64/x86_64.mk
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
CC := x86_64-elf-gcc
|
||||||
|
LD := x86_64-elf-ld
|
||||||
|
|
||||||
|
CFLAGS += -m64 \
|
||||||
|
-fPIE \
|
||||||
|
-mno-80387 \
|
||||||
|
-mno-mmx \
|
||||||
|
-mno-sse \
|
||||||
|
-nostartfiles \
|
||||||
|
-nostdlib \
|
||||||
|
-mno-sse2 \
|
||||||
|
-mno-red-zone \
|
||||||
|
-fno-stack-protector \
|
||||||
|
-fno-stack-check \
|
||||||
|
-Os \
|
||||||
|
|
||||||
|
LDFLAGS += -m elf_x86_64 \
|
||||||
|
-pie \
|
||||||
|
--no-dynamic-linker \
|
||||||
|
-z text \
|
||||||
|
-z max-page-size=0x1000
|
||||||
|
|
2
user/hello/.gitignore
vendored
Normal file
2
user/hello/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.o
|
||||||
|
hello
|
21
user/hello/Makefile
Normal file
21
user/hello/Makefile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
include ../Makefile.inc
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
TARGET := hello
|
||||||
|
|
||||||
|
SRCFILES := $(wildcard *.s)
|
||||||
|
ASFILES := $(filter %.s,$(SRCFILES))
|
||||||
|
OBJ := $(patsubst %.s,%.o,$(ASFILES))
|
||||||
|
|
||||||
|
%.o: %.s
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
hello: $(OBJ)
|
||||||
|
$(LD) $^ $(LDFLAGS) -o $@
|
||||||
|
echo "$(realpath $@)" >> $(FILES)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJ) $(TARGET)
|
6
user/hello/hello.s
Normal file
6
user/hello/hello.s
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
.spin:
|
||||||
|
jmp .spin
|
||||||
|
|
Reference in New Issue
Block a user