forked from PoliEcho-holding-org/kern
Added string.h
This commit is contained in:
@@ -0,0 +1,122 @@
|
|||||||
|
#ifndef _GDT_H
|
||||||
|
#define _GDT_H
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Entries:
|
||||||
|
* 0 Null desc.
|
||||||
|
* 1 Kernel code desc.
|
||||||
|
* 2 Kernel data desc.
|
||||||
|
* 3 SYSENTER
|
||||||
|
* 4 SYSEXIT
|
||||||
|
* 5 User code desc.
|
||||||
|
* 6 User data desc.
|
||||||
|
* 7 Task State Segment
|
||||||
|
*/
|
||||||
|
#define GDT_ENTRIES 8
|
||||||
|
#define GDT_KERNEL_CODE 0x28
|
||||||
|
#define GDT_KERNEL_DATA 0x30
|
||||||
|
#define GDT_USER_CODE 0x50
|
||||||
|
#define GDT_USER_DATA 0x48
|
||||||
|
#define GDT_TSS 0x50
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Segment selector explanation (why kcode is 0x08?)
|
||||||
|
*
|
||||||
|
* Each segment selector must be 16 bits. These bits
|
||||||
|
* have the following layout: (example is 0x08)
|
||||||
|
* 0000000000001 0 00 (lsb)
|
||||||
|
* | | '- Privilege level
|
||||||
|
* | '--- Table indicator
|
||||||
|
* '------ Index in table
|
||||||
|
*
|
||||||
|
* Bits 0-1 are the privilege level. x86 has four,
|
||||||
|
* where 00 is the highest and 11 is the lowest. Only
|
||||||
|
* these two are widely used. 00 being kernel space &
|
||||||
|
* 11 being userspace. Bit 3 is the table indicator.
|
||||||
|
* 0 means the GDT and 1 means the LDT. This will most
|
||||||
|
* likely be 0. Bits 4-15 are the index. This is just
|
||||||
|
* which descriptor in the table is used.
|
||||||
|
*
|
||||||
|
* SO, for the kernel code segment:
|
||||||
|
* Privilege is 00 for kernel space, table indicator
|
||||||
|
* s 0 for the GDT and the index is one, because it
|
||||||
|
* is the second entry in our GDT (after null desc.)
|
||||||
|
*/
|
||||||
|
#define SEGMENT_SEL(_priv, _tab, _i)\
|
||||||
|
(uint16_t)(((_i) << 3) | ((_tab) << 2) | (_priv))
|
||||||
|
|
||||||
|
struct gdt_entry {
|
||||||
|
uint16_t limit;
|
||||||
|
uint16_t baseLow;
|
||||||
|
uint8_t baseMid;
|
||||||
|
uint8_t access;
|
||||||
|
uint8_t granulatiry;
|
||||||
|
uint8_t baseHigh;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct gdt_pointer {
|
||||||
|
uint16_t limit;
|
||||||
|
uint32_t base;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct tss_entry {
|
||||||
|
uint16_t length;
|
||||||
|
uint16_t baseLow;
|
||||||
|
uint8_t baseMid;
|
||||||
|
uint8_t flags1;
|
||||||
|
uint8_t flags2;
|
||||||
|
uint8_t baseHigh;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct tss_pointer {
|
||||||
|
uint16_t link;
|
||||||
|
uint16_t __reserved0;
|
||||||
|
uint32_t esp0;
|
||||||
|
uint16_t ss0;
|
||||||
|
uint16_t __reserved1;
|
||||||
|
uint32_t esp1;
|
||||||
|
uint16_t ss1;
|
||||||
|
uint16_t __reserved2;
|
||||||
|
uint32_t esp2;
|
||||||
|
uint16_t ss2;
|
||||||
|
uint16_t __reserved3;
|
||||||
|
uint32_t cr3;
|
||||||
|
uint32_t eip;
|
||||||
|
uint32_t eflags;
|
||||||
|
uint32_t eax;
|
||||||
|
uint32_t ecx;
|
||||||
|
uint32_t edx;
|
||||||
|
uint32_t ebx;
|
||||||
|
uint32_t esp;
|
||||||
|
uint32_t ebs;
|
||||||
|
uint32_t ebp;
|
||||||
|
uint32_t esi;
|
||||||
|
uint32_t edi;
|
||||||
|
uint16_t es;
|
||||||
|
uint16_t __reserved4;
|
||||||
|
uint16_t cs;
|
||||||
|
uint16_t __reserved5;
|
||||||
|
uint16_t ss;
|
||||||
|
uint16_t __reserved6;
|
||||||
|
uint16_t ds;
|
||||||
|
uint16_t __reserved7;
|
||||||
|
uint16_t fs;
|
||||||
|
uint16_t __reserved8;
|
||||||
|
uint16_t gs;
|
||||||
|
uint16_t __reserved9;
|
||||||
|
uint16_t ldtr;
|
||||||
|
uint32_t __reserved10;
|
||||||
|
uint16_t iopb;
|
||||||
|
uint32_t ssp;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct gdt_entries {
|
||||||
|
struct gdt_entry descriptors[GDT_ENTRIES - 1]; // Subtract one for TSS
|
||||||
|
struct tss_entry tss;
|
||||||
|
};
|
||||||
|
|
||||||
|
int gdt_init(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -77,14 +77,14 @@ extern uint32_t __kernel_start, __kernel_end;
|
|||||||
/*
|
/*
|
||||||
* Logging and errors
|
* Logging and errors
|
||||||
*/
|
*/
|
||||||
// TODO
|
#include <serial.h>
|
||||||
#define printk(_s) NULL
|
#define printk debugf
|
||||||
#define pr_dbg(_s) NULL
|
#define pr_dbg(_s) printk("[debug] %s\n", (_s))
|
||||||
#define pr_wrn(_s) NULL
|
#define pr_wrn(_s) printk("[warning] %s\n", (_s))
|
||||||
#define pr_err(_s) NULL
|
#define pr_err(_s) printk("[error] %s\n", (_s))
|
||||||
#define panic(_s) NULL
|
#define panic(_s) printk("[panic] %s\n", (_s))
|
||||||
#define BUG() NULL
|
#define BUG() panic("BUG()")
|
||||||
#define WARN() NULL
|
#define WARN() pr_wrn("WARN()")
|
||||||
#define BUG_ON(_e) ((_e) ? BUG() : NULL)
|
#define BUG_ON(_e) ((_e) ? BUG() : NULL)
|
||||||
#define WARN_ON(_e) ((_e) ? WARN() : NULL)
|
#define WARN_ON(_e) ((_e) ? WARN() : NULL)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _STRING_H
|
||||||
|
#define _STRING_H
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
|
// Memory functions
|
||||||
|
void* memchr(const void* ptr, uint8_t val, size_t len);
|
||||||
|
int memcmp(const void* ptr1, const void* ptr2, size_t len);
|
||||||
|
void* memcpy(void* dst, const void* src, size_t len);
|
||||||
|
void* memmov(void* dst, const void* src, size_t len);
|
||||||
|
void* memset(void* dst, uint8_t val, size_t len);
|
||||||
|
|
||||||
|
// String functions
|
||||||
|
char* strbrk(char* str, const char* accept);
|
||||||
|
char* strcat(char* dst, const char* src);
|
||||||
|
char* strchr(const char* str, char c);
|
||||||
|
int strcmp(const char* str1, const char* str2);
|
||||||
|
char* strcpy(char* dst, const char* src);
|
||||||
|
size_t strlen(const char* str);
|
||||||
|
size_t strspn(const char* str, const char* accept);
|
||||||
|
char* strstr(const char* str1, const char* str2);
|
||||||
|
char* strtok(char* str, const char* delim);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
#include <kernel.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <gdt.h>
|
||||||
|
|
||||||
|
static struct gdt_entries gdt;
|
||||||
|
static struct gdt_pointer gdtp;
|
||||||
|
static struct tss_pointer tss;
|
||||||
|
struct tss_pointer* tssp = &tss;
|
||||||
|
|
||||||
|
void gdt_loadTss(struct tss_pointer* ptr) {
|
||||||
|
size_t addr = (size_t)ptr;
|
||||||
|
|
||||||
|
gdt.tss.baseLow = (uint16_t)addr;
|
||||||
|
gdt.tss.baseMid = (uint8_t)(addr >> 16);
|
||||||
|
gdt.tss.flags1 = 0x89;
|
||||||
|
gdt.tss.flags2 = 0;
|
||||||
|
gdt.tss.baseHigh = (uint8_t)(addr >> 24);
|
||||||
|
|
||||||
|
__asm__ volatile ("ltr %0" : : "rm"(SEGMENT_SEL(0, 0, 7)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gdt_reload(void) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"cli\n"
|
||||||
|
"lgdt (%0)\n"
|
||||||
|
"ljmp $0x08, $1f\n"
|
||||||
|
"1:\n"
|
||||||
|
"movw $0x10, %%ax\n"
|
||||||
|
"movw %%ax, %%ds\n"
|
||||||
|
"movw %%ax, %%es\n"
|
||||||
|
"movw %%ax, %%fs\n"
|
||||||
|
"movw %%ax, %%gs\n"
|
||||||
|
"movw %%ax, %%ss\n"
|
||||||
|
:
|
||||||
|
: "m" (gdtp)
|
||||||
|
: "memory", "rax"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gdt_init(void) {
|
||||||
|
// Null descriptor (0)
|
||||||
|
gdt.descriptors[0].limit = 0;
|
||||||
|
gdt.descriptors[0].baseLow = 0;
|
||||||
|
gdt.descriptors[0].baseMid = 0;
|
||||||
|
gdt.descriptors[0].access = 0;
|
||||||
|
gdt.descriptors[0].granulatiry = 0;
|
||||||
|
gdt.descriptors[0].baseHigh = 0;
|
||||||
|
|
||||||
|
// Kernel code (8)
|
||||||
|
gdt.descriptors[1].limit = 0xffff;
|
||||||
|
gdt.descriptors[1].baseLow = 0;
|
||||||
|
gdt.descriptors[1].baseMid = 0;
|
||||||
|
gdt.descriptors[1].access = 0x9a;
|
||||||
|
gdt.descriptors[1].granulatiry = 0xcf;
|
||||||
|
gdt.descriptors[1].baseHigh = 0;
|
||||||
|
|
||||||
|
// Kernel data (16)
|
||||||
|
gdt.descriptors[2].limit = 0xffff;
|
||||||
|
gdt.descriptors[2].baseLow = 0;
|
||||||
|
gdt.descriptors[2].baseMid = 0;
|
||||||
|
gdt.descriptors[2].access = 0x90;
|
||||||
|
gdt.descriptors[2].granulatiry = 0xcf;
|
||||||
|
gdt.descriptors[2].baseHigh = 0;
|
||||||
|
|
||||||
|
// SYSENTER/SYSEXIT
|
||||||
|
gdt.descriptors[3] = (struct gdt_entry){ 0 }; // (24)
|
||||||
|
gdt.descriptors[4] = (struct gdt_entry){ 0 }; // (32)
|
||||||
|
|
||||||
|
// User code (40)
|
||||||
|
gdt.descriptors[5].limit = 0;
|
||||||
|
gdt.descriptors[5].baseLow = 0;
|
||||||
|
gdt.descriptors[5].baseMid = 0;
|
||||||
|
gdt.descriptors[5].access = 0xfa;
|
||||||
|
gdt.descriptors[5].granulatiry = 0x20;
|
||||||
|
gdt.descriptors[5].baseHigh = 0;
|
||||||
|
|
||||||
|
// User data (48)
|
||||||
|
gdt.descriptors[6].limit = 0;
|
||||||
|
gdt.descriptors[6].baseLow = 0;
|
||||||
|
gdt.descriptors[6].baseMid = 0;
|
||||||
|
gdt.descriptors[6].access = 0xf2;
|
||||||
|
gdt.descriptors[6].granulatiry = 0;
|
||||||
|
gdt.descriptors[6].baseHigh = 0;
|
||||||
|
|
||||||
|
// TSS (56)
|
||||||
|
gdt.tss.length = 104;
|
||||||
|
gdt.tss.baseLow = 0;
|
||||||
|
gdt.tss.baseMid = 0;
|
||||||
|
gdt.tss.flags1 = 0x89;
|
||||||
|
gdt.tss.flags2 = 0;
|
||||||
|
gdt.tss.baseHigh = 0;
|
||||||
|
|
||||||
|
gdtp.limit = sizeof(struct gdt_entries) - 1;
|
||||||
|
gdtp.base = (uint32_t)&gdt;
|
||||||
|
|
||||||
|
gdt_reload();
|
||||||
|
|
||||||
|
memset(tssp, 0, sizeof(struct tss_pointer));
|
||||||
|
gdt_loadTss(tssp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
+4
-2
@@ -1,9 +1,10 @@
|
|||||||
#include <bootloader.h>
|
#include <bootloader.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
|
#include <gdt.h>
|
||||||
#include <tty.h>
|
#include <tty.h>
|
||||||
|
|
||||||
/* TODO: Commented out stuff */
|
// TODO: Commented out stuff
|
||||||
|
|
||||||
__noreturn
|
__noreturn
|
||||||
void kmain(void* ptr, uint32_t magic) {
|
void kmain(void* ptr, uint32_t magic) {
|
||||||
@@ -23,9 +24,10 @@ void kmain(void* ptr, uint32_t magic) {
|
|||||||
// pmm_init();
|
// pmm_init();
|
||||||
// vmm_init();
|
// vmm_init();
|
||||||
|
|
||||||
// gdt_init();
|
gdt_init();
|
||||||
// isr_init();
|
// isr_init();
|
||||||
// pag_init();
|
// pag_init();
|
||||||
|
while (1);
|
||||||
|
|
||||||
debugf("Basic initialization complete!\n");
|
debugf("Basic initialization complete!\n");
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#include <kernel.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void* memchr(const void* ptr, uint8_t val, size_t len) {
|
||||||
|
const uint8_t* p = ptr;
|
||||||
|
while (len--) if (*p++ == val) return (void*)(p - 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp(const void* ptr1, const void* ptr2, size_t len) {
|
||||||
|
const uint8_t* p1 = ptr1;
|
||||||
|
const uint8_t* p2 = ptr2;
|
||||||
|
while (len--) if (*p1++ != *p2++) return p1[-1] - p2[-1];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memcpy(void* dst, const void* src, size_t len) {
|
||||||
|
uint8_t* d = dst;
|
||||||
|
const uint8_t* s = src;
|
||||||
|
while (len--) *d++ = *s++;
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memmov(void* dst, const void* src, size_t len) {
|
||||||
|
uint8_t* d = dst;
|
||||||
|
const uint8_t* s = src;
|
||||||
|
if (d < s) while (len--) *d++ = *s++;
|
||||||
|
else while (len--) d[len] = s[len];
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset(void* dst, uint8_t val, size_t len) {
|
||||||
|
uint8_t* d = dst;
|
||||||
|
while (len--) *d++ = val;
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strbrk(char* str, const char* accept) {
|
||||||
|
while (*str) {
|
||||||
|
if (strchr(accept, *str)) return (char*)str;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strcat(char* dst, const char* src) {
|
||||||
|
char* d = dst;
|
||||||
|
while (*d) d++;
|
||||||
|
while ((*d++ = *src++));
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strchr(const char* str, char c) {
|
||||||
|
while (*str) if (*str++ == c) return (char*)(str - 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strcmp(const char* str1, const char* str2) {
|
||||||
|
while (*str1 && (*str1 == *str2)) str1++, str2++;
|
||||||
|
return (int)(*(uint8_t*)str1 - *(uint8_t*)str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strcpy(char* dst, const char* src) {
|
||||||
|
char* d = dst;
|
||||||
|
while ((*d++ = *src++));
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t strlen(const char* str) {
|
||||||
|
const char* s = str;
|
||||||
|
while (*s++);
|
||||||
|
return s - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t strspn(const char* str, const char* accept) {
|
||||||
|
const char* s = str;
|
||||||
|
while (*s && strchr(accept, *s)) s++;
|
||||||
|
return s - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strstr(const char* str1, const char* str2) {
|
||||||
|
if (!*str2) return (char*)str1;
|
||||||
|
for (; *str1; str1++) {
|
||||||
|
const char* s1 = str1;
|
||||||
|
const char* s2 = str2;
|
||||||
|
while (*s1 && *s2 && (*s1 == *s2)) s1++, s2++;
|
||||||
|
if (!*s2) return (char*)str1;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strtok(char* str, const char* delim) {
|
||||||
|
static char* next;
|
||||||
|
if (!str) str = next;
|
||||||
|
if (!str) return NULL;
|
||||||
|
str += strspn(str, delim);
|
||||||
|
if (!*str) return (next = NULL);
|
||||||
|
char* tok = str;
|
||||||
|
str = strbrk(str, delim);
|
||||||
|
if (str) *str++ = '\0';
|
||||||
|
next = str;
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user