Added screenfetch

This commit is contained in:
Cetica Marco 2021-01-04 17:54:22 +01:00
parent f13837f6f8
commit 6f851951d6
15 changed files with 347 additions and 33 deletions

View File

@ -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

View File

@ -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.
<div align="center">
<img src="imgs/screenshot.png" />
<h6><i>VulcanOS running under QEMU</h6></i>
</div><br /><br />
## 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:

View File

@ -1,7 +1,7 @@
set timeout = 0
set default = 0
menuentry "iceOS" {
multiboot2 /boot/iceOS.bin
menuentry "VulcanOS" {
multiboot2 /boot/vulcanos.bin
boot
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

View File

@ -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 $@
$(CC) $(CFLAGS) $< -o $@

195
kernel/drivers/cpuid.c Normal file
View File

@ -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;
}

36
kernel/drivers/cpuid.h Normal file
View File

@ -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 <stdint.h>
#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

View File

@ -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() {

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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 $@

View File

@ -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);
}

View File

@ -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!");
}