From 6f851951d6992c84b24dd3373e994a31644651cb Mon Sep 17 00:00:00 2001 From: Cetica Marco Date: Mon, 4 Jan 2021 17:54:22 +0100 Subject: [PATCH] Added screenfetch --- Makefile | 12 +- README.md | 7 +- grub.cfg | 6 +- imgs/screenshot.png | Bin 11629 -> 13644 bytes imgs/{iceOS.iso => vulcanos.iso} | Bin 11503616 -> 11511808 bytes kernel/drivers/Makefile | 6 +- kernel/drivers/cpuid.c | 195 +++++++++++++++++++++++++++++++ kernel/drivers/cpuid.h | 36 ++++++ kernel/drivers/tty.c | 22 +++- kernel/drivers/tty.h | 1 - kernel/libc/string.c | 20 +++- kernel/libc/string.h | 2 + kernel/userspace/Makefile | 6 +- kernel/userspace/fetch.c | 65 +++++++++-- kernel/userspace/shell.c | 2 + 15 files changed, 347 insertions(+), 33 deletions(-) rename imgs/{iceOS.iso => vulcanos.iso} (98%) create mode 100644 kernel/drivers/cpuid.c create mode 100644 kernel/drivers/cpuid.h diff --git a/Makefile b/Makefile index 7c981f8..bfb2ddf 100644 --- a/Makefile +++ b/Makefile @@ -33,14 +33,14 @@ mem: cp kernel/mem/*.o obj/ link: - $(LD) $(LFLAGS) -o isodir/boot/iceOS.bin obj/*.o + $(LD) $(LFLAGS) -o isodir/boot/vulcanos.bin obj/*.o iso: - grub-mkrescue isodir -o iceOS.iso + grub-mkrescue isodir -o vulcanos.iso clean: rm -rf obj/ kernel/*.o kernel/cpu/*.o - rm -rf kernel/shell/*.o kernel/mem/*.o + rm -rf kernel/userspace/*.o kernel/mem/*.o rm -rf kernel/drivers/*.o kernel/libc/*.o rm -rf iceOS.iso bochslog.txt commands isodir @@ -48,10 +48,10 @@ bochs: bochs -f bochs_cfg -q run: - qemu-system-x86_64 -cdrom iceOS.iso + qemu-system-x86_64 -cdrom vulcanos.iso -cpu qemu32 run-debug: - qemu-system-x86_64 -cdrom iceOS.iso -d exec,cpu + qemu-system-x86_64 -cdrom vulcanos.iso -d exec,cpu run-curses: - qemu-system-x86_64 -cdrom iceOS.iso -curses + qemu-system-x86_64 -cdrom vulcanos.iso -curses diff --git a/README.md b/README.md index d5aa61c..0b7d1d7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,10 @@ # VulcanOS [![Build Status](https://travis-ci.com/ice-bit/vulcanos.svg?branch=master)](https://travis-ci.com/ice-bit/vulcanos) **VulcanOS** is a x86 monolithic kernel written in C from scratch following the UNIX philosophy. This project is just a student learning tool to know more about operating systems, do not expect nothing more than a toy. - +
+ +
VulcanOS running under QEMU
+


## Installation ### Requirements @@ -18,7 +21,7 @@ After that, you can build iceOS just by running the command listed below. 2. Type `make run` to start it in QEMU or `make bochs` to start it with bochs(only for debug purposes). You can also find a ISO file -[here](https://github.com/ice-bit/vulcanos/raw/master/imgs/vulcanos.iso)(md5sum: `5a969460e63eb5c4dcfa943dc2a3f39f`) +[here](https://github.com/ice-bit/vulcanos/raw/master/imgs/vulcanos.iso)(md5sum: `a706cdfeea573e08550e599717d3f519`) ## Features iceOS has the following features: diff --git a/grub.cfg b/grub.cfg index 38bd850..86afc3c 100644 --- a/grub.cfg +++ b/grub.cfg @@ -1,7 +1,7 @@ set timeout = 0 set default = 0 -menuentry "iceOS" { - multiboot2 /boot/iceOS.bin +menuentry "VulcanOS" { + multiboot2 /boot/vulcanos.bin boot -} \ No newline at end of file +} diff --git a/imgs/screenshot.png b/imgs/screenshot.png index cee5e04bd8a31d6335320924ac44036c7b35271f..6c367b3b901ea40742455a4af4607d117b2cc46a 100644 GIT binary patch literal 13644 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%0AiA4@CE$da#`#oXpplc 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 G`~L&Z;&aLX literal 11629 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 St2aMJ@7^}mue$m0*Z&2)9lSXJ diff --git a/imgs/iceOS.iso b/imgs/vulcanos.iso similarity index 98% rename from imgs/iceOS.iso rename to imgs/vulcanos.iso index 073eeaee7224a9e950a0afdfd6e55c1dd42f5ac3..b503130643118cff44916e423de9ad3b63b33c2d 100644 GIT binary patch delta 80274 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 diff --git a/kernel/drivers/Makefile b/kernel/drivers/Makefile index 622502f..24cd3ff 100644 --- a/kernel/drivers/Makefile +++ b/kernel/drivers/Makefile @@ -1,11 +1,11 @@ OBJS = tty.o gdt.o idt.o isr.o timer.o keyboard.o \ - fs.o + fs.o cpuid.o CC = i686-elf-gcc # cross-compiler -CFLAGS = -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c +CFLAGS = -m32 -fno-stack-protector -DDEFAULT_USER=root -DDEFAULT_HOSTNAME=vulcan -ffreestanding -Wall -Wextra -Werror -g -c all:${OBJS} %.o: %.c - $(CC) $(CFLAGS) $< -o $@ \ No newline at end of file + $(CC) $(CFLAGS) $< -o $@ diff --git a/kernel/drivers/cpuid.c b/kernel/drivers/cpuid.c new file mode 100644 index 0000000..921ccab --- /dev/null +++ b/kernel/drivers/cpuid.c @@ -0,0 +1,195 @@ +#include "cpuid.h" +#include "../libc/string.h" +#define INTEL_MAGIC_NUMBER 0x756e6547 +#define AMD_MAGIC_NUMBER 0x68747541 +#define UNRECOGNIZED_CPU 0xBADFF + +static cpuid_t get_cpuid(icpuid_t cpu); +static icpuid_t detect_cpu(void); +static icpuid_t intel_cpu(void); +static icpuid_t amd_cpu(void); +static icpuid_t generic_cpu(void); + +icpuid_t detect_cpu(void) { + uint32_t ebx, null; + icpuid_t i_cpu; + + cpuid(0, null, ebx, null, null); + + // Select CPU brand + switch(ebx) { + case INTEL_MAGIC_NUMBER: + i_cpu = intel_cpu(); + break; + case AMD_MAGIC_NUMBER: + i_cpu = amd_cpu(); + break; + default: + i_cpu = generic_cpu(); + break; + } + + return i_cpu; +} + +icpuid_t intel_cpu(void) { + uint32_t eax, ebx, null; + icpuid_t icpu; + + // Fill the structure + cpuid(1, eax, ebx, null, null); + icpu.model = (eax >> 4) & 0xF; + icpu.family = (eax >> 8) & 0xF; + icpu.type = (eax >> 12) & 0xF; + icpu.brand = INTEL_MAGIC_NUMBER; + icpu.stepping = eax & 0xF; + icpu.reserved = eax >> 14; + + return icpu; +} + +icpuid_t amd_cpu(void) { + uint32_t eax, null; + icpuid_t icpu; + + // Fill the structure + cpuid(1, eax, null, null, null); + icpu.model = (eax >> 4) & 0xF; + icpu.family = (eax >> 8) & 0xF; + icpu.stepping = eax & 0xF; + icpu.reserved = eax >> 12; + icpu.brand = AMD_MAGIC_NUMBER; + + return icpu; +} + +icpuid_t generic_cpu(void) { + icpuid_t icpu; + + icpu.brand = UNRECOGNIZED_CPU; // Magic number for unknown CPUs + + return icpu; +} + +cpuid_t get_cpuid(icpuid_t cpu) { + cpuid_t cpuid; + uint8_t model[64]; + + // Recognize CPU brand + if(cpu.brand == AMD_MAGIC_NUMBER) { + switch(cpu.family) { + case 4: + strcpy(model, (uint8_t*)"486 model "); // Set model name + strcat(model, (void*)cpu.model); // Set model version + cpuid.model = model; + break; + case 5: + switch(cpu.model) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + strcpy(model, (uint8_t*)"K6 model "); // Set model name + strcat(model, (void*)cpu.model); // Set model version + cpuid.model = model; + break; + case 8: + strcpy(model, (uint8_t*)"K6-2 model "); // Set model name + strcat(model, (void*)cpu.model); // Set model version + cpuid.model = model; + break; + case 9: + strcpy(model, (uint8_t*)"K6-III model "); // Set model name + strcat(model, (void*)cpu.model); // Set model version + cpuid.model = model; + break; + default: + strcpy(model, (uint8_t*)"K5/K6 model "); // Set model name + strcat(model, (void*)cpu.model); // Set model version + cpuid.model = model; + break; + } + break; + case 6: + switch(cpu.model) { + case 1: + case 2: + case 3: + cpuid.model = (uint8_t*)"Duron model 3"; + break; + case 4: + strcpy(model, (uint8_t*)"Athlon model "); + strcat(model, (void*)cpu.model); + cpuid.model = model; + break; + case 6: + cpuid.model = (uint8_t*)"Athlon MP/Mobile Athlon Model 6"; + break; + case 7: + cpuid.model = (uint8_t*)"Mobile Duron Model 7"; + break; + default: + strcpy(model, (uint8_t*)"Duron/Athlon model "); + strcat(model, (void*)cpu.model); + cpuid.model = model; + break; + } + break; + } + } else if(cpu.brand == INTEL_MAGIC_NUMBER) { + switch(cpu.type) { + case 0: + cpuid.type =(uint8_t*)"Original OEM"; + break; + case 1: + cpuid.type = (uint8_t*)"Overdrive"; + break; + case 2: + cpuid.type = (uint8_t*)"Dual-capable"; + break; + case 3: + cpuid.type = (uint8_t*)"Reserved"; + break; + } + + switch(cpu.family) { + case 3: + cpuid.family = (uint8_t*)"i386"; + break; + case 4: + cpuid.family = (uint8_t*)"i486"; + break; + case 5: + cpuid.family = (uint8_t*)"Pentium II Model 5/Xeon/Celeron"; + break; + case 6: + cpuid.family = (uint8_t*)"Pentium Pro"; + break; + case 15: + cpuid.family = (uint8_t*)"Pentium 4"; + break; + } + } else if(cpu.brand == UNRECOGNIZED_CPU) + cpuid.family = (uint8_t*)"Generic (x86) CPU"; + + return cpuid; +} + +uint8_t *get_cpu_type() { + icpuid_t icpu = detect_cpu(); // Detect CPU brand(Intel, AMD or generic x86) + cpuid_t cpu_type = get_cpuid(icpu); + + return (uint8_t*)cpu_type.type; +} + +uint8_t *get_cpu_family() { + icpuid_t icpu = detect_cpu(); // Detect CPU brand(Intel, AMD or generic x86) + cpuid_t cpu_family = get_cpuid(icpu); + + return (uint8_t*)cpu_family.family; + +} diff --git a/kernel/drivers/cpuid.h b/kernel/drivers/cpuid.h new file mode 100644 index 0000000..ab11068 --- /dev/null +++ b/kernel/drivers/cpuid.h @@ -0,0 +1,36 @@ +/************************************** + * VulcanOS Kernel * + * Developed by Marco 'icebit' Cetica * + * (c) 2019-2021 * + * Released under GPLv3 * + * https://github.com/ice-bit/iceOS * + ***************************************/ +#ifndef CPUID_H +#define CPUID_H + +#include +#define cpuid(in, a, b, c, d) __asm__("cpuid": "=a" (a), "=b"(b), "=d" (d) : "a" (in)); + +typedef struct { + uint32_t model; + uint32_t family; + uint32_t type; + uint32_t brand; + uint32_t stepping; + uint32_t reserved; +} icpuid_t; + +typedef struct { + uint8_t *model; + uint8_t *family; + uint8_t *type; + uint8_t *brand; + uint8_t *stepping; + uint8_t *reserved; +} cpuid_t; + +// return type and family processor +uint8_t *get_cpu_type(); +uint8_t *get_cpu_family(); + +#endif diff --git a/kernel/drivers/tty.c b/kernel/drivers/tty.c index f95fce1..b24b7af 100644 --- a/kernel/drivers/tty.c +++ b/kernel/drivers/tty.c @@ -5,6 +5,8 @@ #define VGA_PTR ((uint8_t*) VIDEO_MEM_ADDR) // Pointer to frame buffer // Also define a 2 byte pointer because cells are 16 bits wide #define UVGA_PTR ((uint16_t *)VIDEO_MEM_ADDR) +#define STRINGIZE(x) #x +#define STRINGIZE_VALUE_OF(x) STRINGIZE(x) static uint32_t fb_col = 1; // X static uint32_t fb_row = 0; // Y @@ -95,8 +97,24 @@ void kprint_dec(uint32_t num) { } void init_prompt() { - uint8_t *prompt = (uint8_t*)"\nring0@iceOS-$ "; - kprint_c(prompt, strlen(prompt), LIGHT_RED, BLACK); + uint8_t user[64], hostname[64]; +#ifdef DEFAULT_USER + strcpy(user, (uint8_t*)STRINGIZE_VALUE_OF(DEFAULT_USER)); +#else + #error "-DDEFAULT_USER flag not set" +#endif + +#ifdef DEFAULT_HOSTNAME + strcpy(hostname, (uint8_t*)STRINGIZE_VALUE_OF(DEFAULT_HOSTNAME)); +#else + #error "-DDEFAULT_HOSTNAME flag not set" +#endif + + newline(); + kprint_c(user, strlen(user), LIGHT_GREEN, BLACK); + kprint_c((uint8_t*)"@", 1, BROWN, BLACK); + kprint_c(hostname, strlen(hostname), CYAN, BLACK); + kprint_c((uint8_t*)" #> ", 4, LIGHT_BROWN, BLACK); } void clear_prompt() { diff --git a/kernel/drivers/tty.h b/kernel/drivers/tty.h index 5bc294e..9aec33a 100644 --- a/kernel/drivers/tty.h +++ b/kernel/drivers/tty.h @@ -46,7 +46,6 @@ enum TTY_COLORS { #define VGA_LOW_BYTE 15 /* Kernel's VGA API */ -// FIXME: Set these functions to static void write_cell(int16_t i, uint8_t c, uint8_t fg, uint8_t bg); void move_cursor(uint16_t pos); void cursor_adv(); diff --git a/kernel/libc/string.c b/kernel/libc/string.c index 959edcd..0a30117 100644 --- a/kernel/libc/string.c +++ b/kernel/libc/string.c @@ -82,7 +82,7 @@ uint8_t *uitoa(uint32_t val, uint8_t *buf, uint32_t radix) { } size_t strlen(const uint8_t *buf) { - unsigned int i = 0; + uint32_t i = 0; while(buf[i] != 0) i++; return i; @@ -95,6 +95,13 @@ uint8_t *strcpy(uint8_t *dst, const uint8_t *src) { return dst_p; } +void strcat(void *dest, const void *src) { + uint8_t *end = (uint8_t*)dest + strlen(dest); + memcpy((uint8_t*)end, (uint8_t*)src, strlen((uint8_t*)src)); + end += strlen((uint8_t*)src); + *end = '\0'; +} + /* Worst memset implementation * i could find on the net. * however it works so... */ @@ -107,6 +114,17 @@ void *memset(void *s, uint32_t c, size_t n) { return s; } +void *memcpy(void *dst, void const *src, uint32_t n) { + uint8_t *ret = dst; + uint8_t *p = dst; + const uint8_t *q = src; + + while(n--) + *p++ = *q++; + + return ret; +} + void *memmove(void *dst, const void *src, size_t len) { char *dstmem = (char*)dst; char *srcmem = (char*)src; diff --git a/kernel/libc/string.h b/kernel/libc/string.h index ab341d7..fc50891 100644 --- a/kernel/libc/string.h +++ b/kernel/libc/string.h @@ -16,8 +16,10 @@ uint8_t *itoa(int32_t val, uint8_t *buf, uint32_t radix); uint8_t *uitoa(uint32_t val, uint8_t *buf, uint32_t radix); size_t strlen(const uint8_t *buf); uint8_t *strcpy(uint8_t *dst, const uint8_t *src); +void strcat(void *dest, const void *src); void *memset(void *s, uint32_t c, size_t n); void *memmove(void *dst, const void *src, size_t len); +void *memcpy(void *dst, void const *src, uint32_t n); void strupper(uint8_t *str); void strlower(uint8_t *str); diff --git a/kernel/userspace/Makefile b/kernel/userspace/Makefile index ac1b288..bf4f717 100644 --- a/kernel/userspace/Makefile +++ b/kernel/userspace/Makefile @@ -1,10 +1,10 @@ OBJS = shell.o fetch.o +VER := $(shell git rev-parse --short HEAD) CC = i686-elf-gcc # cross-compiler -CFLAGS = -DDEFAULT_USER=root -DDEFAULT_HOSTNAME=vulcan -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c +CFLAGS = -DDEFAULT_USER=root -DDEFAULT_HOSTNAME=vulcan -DVULCAN_VERSION=$(VER) -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c - -all:${OBJS} +all:${OBJS} %.o: %.c $(CC) $(CFLAGS) $< -o $@ diff --git a/kernel/userspace/fetch.c b/kernel/userspace/fetch.c index 95532ba..e461b6b 100644 --- a/kernel/userspace/fetch.c +++ b/kernel/userspace/fetch.c @@ -3,19 +3,16 @@ #include "../libc/string.h" #include "../libc/time.h" #include "../drivers/tty.h" - - - -void system_fetcher() { - /*uint8_t *logo = (uint8_t*)" \n \ - __ __ ___ ___ \n \ - \\ \\ / / / _ \\/ __| \n \ - \\ V / | (_) \\__ \\ \n \ - \\_/ \\___/|___/";*/ - - uint8_t user[64], hostname[64]; +#include "../drivers/cpuid.h" #define STRINGIZE(x) #x #define STRINGIZE_VALUE_OF(x) STRINGIZE(x) + +static void get_date(); +static void get_cpuid(); +static void get_version(); + +void system_fetcher() { + uint8_t user[64], hostname[64]; #ifdef DEFAULT_USER strcpy(user, (uint8_t*)STRINGIZE_VALUE_OF(DEFAULT_USER)); #else @@ -27,8 +24,52 @@ void system_fetcher() { #else #error "-DDEFAULT_HOSTNAME flag not set" #endif - printf_color("\n__ __ ___ ___ ", LIGHT_RED, BLACK); + // print first line + printf_color("\n __ __ ___ ___ ", LIGHT_RED, BLACK); printf_color((char*)user, LIGHT_CYAN, BLACK); printf_color("@", LIGHT_RED, BLACK); printf_color((char*)hostname, LIGHT_CYAN, BLACK); + // print second line + printf_color("\n \\ \\ / / / _ \\/ __| ", LIGHT_RED, BLACK); + printf_color("-----------", LIGHT_RED, BLACK); + // print third line + printf_color("\n \\ V / | (_) \\__ \\ ", LIGHT_RED, BLACK); + printf_color("Date: ", LIGHT_CYAN, BLACK); + get_date(); + // print fourth line + printf_color("\n \\_/ \\___/|___/ ", LIGHT_RED, BLACK); + get_cpuid(); + // print VulcanOS version + get_version(); +} + +// Date format is D/M/YY +void get_date() { + printf("%d", get_time(TIME_R_DAY)); // Day + printf_color("/", LIGHT_BLUE, BLACK); + + printf("%d", get_time(TIME_R_MONTH)); // Month + printf_color("/", LIGHT_BLUE, BLACK); + + printf("%d", get_time(TIME_R_YEAR)); // Year +} + + +void get_cpuid() { + printf_color("CPU type: ", LIGHT_CYAN, BLACK); + printf("%s", (char*)get_cpu_type()); // Print CPU type + printf("%s%s%c", " (", (char*)get_cpu_family(), ')'); +} + + +void get_version() { + uint8_t version[64]; +#ifdef VULCAN_VERSION + strcpy(version, (uint8_t*)STRINGIZE_VALUE_OF(VULCAN_VERSION)); +#else + #error "-DVULCAN_VERSION flag not set" +#endif + + printf_color("\n\t\t\t\t\t Version: ", LIGHT_CYAN, BLACK); + printf_color((char*)version, LIGHT_GREEN, BLACK); } diff --git a/kernel/userspace/shell.c b/kernel/userspace/shell.c index 467a2b1..73cde48 100644 --- a/kernel/userspace/shell.c +++ b/kernel/userspace/shell.c @@ -115,6 +115,8 @@ void processCommand(uint8_t *cmd) { system_fetcher(); else if(strcmp(cmd, (uint8_t*)"reboot") == 0) reboot(); + else if(strcmp(cmd, (uint8_t*)"") == 0) + puts(""); else puts("\nCommand not found!"); }