Added screenfetch
This commit is contained in:
parent
f13837f6f8
commit
6f851951d6
12
Makefile
12
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
|
||||
|
@ -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:
|
||||
|
6
grub.cfg
6
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
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 13 KiB |
Binary file not shown.
@ -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
195
kernel/drivers/cpuid.c
Normal 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
36
kernel/drivers/cpuid.h
Normal 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
|
@ -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() {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 $@
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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!");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user