2018-09-28 20:35:51 +02:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
|
|
|
/* */
|
2018-09-17 18:17:11 +02:00
|
|
|
#include "vga.h"
|
|
|
|
#include "video.h"
|
|
|
|
#include "interrupts.h"
|
|
|
|
#include "asm.h"
|
|
|
|
#include "cpu.h"
|
|
|
|
#include "string.h"
|
|
|
|
#include "2d.h"
|
|
|
|
#include "gdt.h"
|
|
|
|
#include "shell.h"
|
2018-09-27 21:01:02 +02:00
|
|
|
#include "multiboot2.h"
|
2018-09-17 18:17:11 +02:00
|
|
|
|
|
|
|
static command commands[] = {
|
2018-10-02 13:49:10 +02:00
|
|
|
{"REBOOT" , "", &rebootnow},
|
|
|
|
{"CLEAR" , "", &clear},
|
|
|
|
{"MODE" , "", &mode},
|
|
|
|
{"DETECTCPU" , "", &detectcpu},
|
|
|
|
{"TEST2D" , "", &test2d},
|
2018-10-02 17:16:23 +02:00
|
|
|
{"REGS" , "", ®s},
|
2018-10-02 13:49:10 +02:00
|
|
|
{"GDT" , "", &readgdt},
|
|
|
|
{"IDT" , "", &readidt},
|
|
|
|
{"INFO" , "", &info},
|
2018-10-03 22:50:54 +02:00
|
|
|
{"PGFAULTW" , "", &pgfaultw},
|
|
|
|
{"PGFAULTR" , "", &pgfaultr},
|
|
|
|
{"DIVZERR" , "", &divzerr}
|
|
|
|
|
2018-09-17 18:17:11 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Shell, traite les commandes */
|
|
|
|
|
2018-09-27 17:47:27 +02:00
|
|
|
void shell()
|
|
|
|
{
|
|
|
|
static u8 field[] =
|
|
|
|
" \000";
|
|
|
|
static u8 item[] = " \000";
|
|
|
|
int i;
|
|
|
|
bool found;
|
|
|
|
while (true) {
|
|
|
|
print("\r\n# ");
|
|
|
|
getstring(&field);
|
|
|
|
print("\r\n");
|
|
|
|
if (strgetnbitems(&field, ' ') < 1)
|
|
|
|
continue;
|
|
|
|
strgetitem(&field, &item, ' ', 0);
|
|
|
|
strtoupper(&item);
|
|
|
|
found = false;
|
|
|
|
for (i = 0; i < sizeof(commands); i++) {
|
|
|
|
if (strcmp(&item, &commands[i].name) == 0) {
|
|
|
|
(*commands[i].function) ();
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found)
|
|
|
|
printf("Commande inconnue !\r\n\000");
|
2018-09-17 18:17:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 22:50:54 +02:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Génère une erreur de division par 0 */
|
|
|
|
int divzerr()
|
|
|
|
{
|
|
|
|
print("Creation d'une erreur de division par 0 !\r\n");
|
|
|
|
asm("movl $0x0,%ecx; divl %ecx");
|
|
|
|
}
|
|
|
|
|
2018-09-17 18:17:11 +02:00
|
|
|
/*******************************************************************************/
|
2018-10-02 13:49:10 +02:00
|
|
|
/* Génère une erreur de page à l'adresse 0xE0000000 */
|
2018-10-03 22:50:54 +02:00
|
|
|
int pgfaultw()
|
|
|
|
{
|
|
|
|
print("Creation d'une erreur de page !\r\n");
|
|
|
|
asm("movl $0x66666666,(0xE0000000)");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Génère une erreur de page à l'adresse 0xD0000000 */
|
|
|
|
int pgfaultr()
|
2018-10-02 13:49:10 +02:00
|
|
|
{
|
2018-10-02 17:16:23 +02:00
|
|
|
print("Creation d'une erreur de page !\r\n");
|
2018-10-03 22:50:54 +02:00
|
|
|
asm("movl (0xD0000000),%eax");
|
2018-10-02 13:49:10 +02:00
|
|
|
}
|
2018-09-17 18:17:11 +02:00
|
|
|
|
2018-10-02 13:49:10 +02:00
|
|
|
/*******************************************************************************/
|
2018-09-27 21:01:02 +02:00
|
|
|
/* Information sur le démarrage */
|
|
|
|
int info()
|
|
|
|
{
|
|
|
|
getbootinfo();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-09-17 18:17:11 +02:00
|
|
|
/* Affiche les registres */
|
|
|
|
|
2018-09-27 17:47:27 +02:00
|
|
|
int regs()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
save_stack dump;
|
|
|
|
dump_cpu(&dump);
|
|
|
|
show_cpu(&dump);
|
2018-09-27 17:47:27 +02:00
|
|
|
return 0;
|
2018-09-17 18:17:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Change le mode */
|
2018-09-27 17:47:27 +02:00
|
|
|
int mode()
|
|
|
|
{
|
|
|
|
setvmode(0x84);
|
|
|
|
return 0;
|
2018-09-17 18:17:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Efface l'écran */
|
|
|
|
|
2018-09-27 17:47:27 +02:00
|
|
|
int clear()
|
|
|
|
{
|
|
|
|
fill(0x00);
|
|
|
|
gotoscr(0, 0);
|
|
|
|
return 0;
|
2018-09-17 18:17:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Redemarre */
|
|
|
|
|
2018-09-27 17:47:27 +02:00
|
|
|
int rebootnow()
|
|
|
|
{
|
|
|
|
print("<Appuyer sur une touche pour redemarrer>");
|
|
|
|
waitascii();
|
|
|
|
reboot();
|
|
|
|
return 0;
|
2018-09-17 18:17:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Test les fonctionnalité 2D graphiques */
|
|
|
|
|
2018-09-27 17:47:27 +02:00
|
|
|
int test2d()
|
|
|
|
{
|
|
|
|
setvmode(0x89);
|
|
|
|
fill(0x00);
|
|
|
|
struct vertex2d a, b, c;
|
|
|
|
randomize();
|
|
|
|
for (int i = 0; i < 3200; i++) {
|
|
|
|
a.x = random(0, 800);
|
|
|
|
a.y = random(0, 600);
|
|
|
|
b.x = random(0, 800);
|
|
|
|
b.y = random(0, 600);
|
|
|
|
c.x = random(0, 800);
|
|
|
|
c.y = random(0, 600);
|
|
|
|
trianglefilled(&a, &b, &c, random(0, 16));
|
|
|
|
triangle(&a, &b, &c, 2);
|
|
|
|
}
|
|
|
|
return 0;
|
2018-09-17 18:17:11 +02:00
|
|
|
}
|
2018-09-27 17:47:27 +02:00
|
|
|
|
2018-09-17 18:17:11 +02:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Lit l'IDT et l'affiche */
|
|
|
|
|
|
|
|
int readidt()
|
|
|
|
{
|
2018-09-27 17:47:27 +02:00
|
|
|
u32 index, i = 0;
|
|
|
|
idtdes *desc;
|
|
|
|
struct idtr idtreg;
|
|
|
|
sidt(&idtreg);
|
|
|
|
printf("Information sur l'IDT\r\nAdresse:%X Limite:%hX", idtreg.base,
|
|
|
|
(u32) idtreg.limite);
|
|
|
|
desc = idtreg.base;
|
|
|
|
for (index = 0; index < idtreg.limite / sizeof(idtdes); index++) {
|
|
|
|
u32 select = desc[index].select;
|
|
|
|
u32 offset =
|
|
|
|
desc[index].offset0_15 + (desc[index].offset16_31 << 16);
|
|
|
|
u32 type = desc[index].type;
|
|
|
|
printf("\r\nInterruption % d Selecteur %hX: offset:%X type:",
|
|
|
|
i++, select, offset, type);
|
|
|
|
if (type == INTGATE)
|
|
|
|
print("INTGATE");
|
|
|
|
else if (type == TRAPGATE)
|
|
|
|
print("TRAPGATE");
|
|
|
|
else if (type == TASKGATE)
|
|
|
|
print("TASKGATE");
|
|
|
|
else if (type == CALLGATE)
|
|
|
|
print("CALLGATE");
|
|
|
|
else if (type == LDTDES)
|
|
|
|
print("LDTDES");
|
|
|
|
else
|
|
|
|
print("inconnu");
|
|
|
|
if (i % 32 == 0) {
|
|
|
|
print("\r\n<Appuyez sur une touche>\r\n");
|
|
|
|
waitascii();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
2018-09-17 18:17:11 +02:00
|
|
|
}
|
2018-09-27 17:47:27 +02:00
|
|
|
|
2018-09-17 18:17:11 +02:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Lit les descripteurs GDT et les affiche */
|
|
|
|
|
|
|
|
int readgdt()
|
|
|
|
{
|
2018-09-27 17:47:27 +02:00
|
|
|
u32 index;
|
|
|
|
gdtdes *desc;
|
|
|
|
struct gdtr gdtreg;
|
|
|
|
sgdt(&gdtreg);
|
2018-10-02 02:16:14 +02:00
|
|
|
printf("Information sur la GDT\r\nAdresse:%X Limite:%hX", gdtreg.base,
|
2018-09-27 17:47:27 +02:00
|
|
|
(u32) gdtreg.limite);
|
|
|
|
desc = gdtreg.base;
|
|
|
|
for (index = 0; index < gdtreg.limite / sizeof(gdtdes); index++) {
|
|
|
|
u32 acces = desc[index].acces;
|
|
|
|
if (acces >> 7 == 1) {
|
|
|
|
u32 flags = desc[index].flags;
|
|
|
|
u32 limit =
|
|
|
|
desc[index].lim0_15 + (desc[index].lim16_19 << 16);
|
|
|
|
u32 base =
|
|
|
|
desc[index].base0_15 +
|
|
|
|
(desc[index].base16_23 << 16) +
|
|
|
|
(desc[index].base24_31 << 24);
|
|
|
|
printf
|
|
|
|
("\r\nSelecteur %hX: base:%X limit:%X access:%hX flags:%hX\r\n -> ",
|
|
|
|
index * sizeof(gdtdes), base, limit, acces, flags);
|
|
|
|
if ((acces >> 4) & 1 == 1)
|
2018-10-02 13:49:10 +02:00
|
|
|
print("System ");
|
2018-09-27 17:47:27 +02:00
|
|
|
else {
|
|
|
|
if (acces & 1 == 1)
|
2018-10-02 13:49:10 +02:00
|
|
|
print("Access ");
|
2018-09-27 17:47:27 +02:00
|
|
|
}
|
|
|
|
if ((acces >> 3) & 1 == 1) {
|
|
|
|
print("Code.");
|
|
|
|
if ((acces >> 1) & 1 == 1)
|
|
|
|
print("Readable ");
|
|
|
|
if ((acces >> 2) & 1 == 1)
|
|
|
|
print("Conforming ");
|
|
|
|
else
|
|
|
|
print("Normal ");
|
|
|
|
} else {
|
|
|
|
print("Data.");
|
2018-10-02 02:16:14 +02:00
|
|
|
if ((acces >> 2) & 1 == 1)
|
2018-09-27 17:47:27 +02:00
|
|
|
print("Down ");
|
|
|
|
else
|
|
|
|
print("up ");
|
|
|
|
if ((acces >> 1) & 1 == 1)
|
|
|
|
print("writeable ");
|
|
|
|
}
|
|
|
|
if (flags & 1 == 1)
|
|
|
|
print("Dispo ");
|
|
|
|
if ((flags >> 2) & 1 == 1)
|
2018-10-02 13:49:10 +02:00
|
|
|
print("32bits ");
|
2018-09-27 17:47:27 +02:00
|
|
|
else
|
2018-10-02 13:49:10 +02:00
|
|
|
print("16bits ");
|
2018-09-27 17:47:27 +02:00
|
|
|
if ((flags >> 3) & 1 == 1)
|
|
|
|
print("4k ");
|
|
|
|
else
|
|
|
|
print("1b ");
|
2018-09-27 21:01:02 +02:00
|
|
|
u8 dpl = (acces >> 5) & 0b11;
|
2018-09-27 17:47:27 +02:00
|
|
|
printf("DPL:%d", dpl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
2018-09-17 18:17:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Detecte et affiche les information sur le CPU */
|
|
|
|
|
|
|
|
int detectcpu()
|
|
|
|
{
|
2018-09-27 17:47:27 +02:00
|
|
|
cpuinfo cpu;
|
|
|
|
u8 noproc[] = "\033[31mInconnu\033[0m\000";
|
|
|
|
strcpy(&noproc, &cpu.detectedname);
|
2018-09-17 18:17:11 +02:00
|
|
|
getcpuinfos(&cpu);
|
2018-09-27 17:47:27 +02:00
|
|
|
printf
|
|
|
|
("\r\nDetection du processeur\r\033[1m Revision \t:%d\r Modele \t:%d\r Famille \t:%d\r Nom cpuid\t:%s\rJeux d'instruction\t:%s\033[0m\r\n\000",
|
|
|
|
cpu.stepping, cpu.models, cpu.family, &cpu.detectedname,
|
|
|
|
&cpu.techs);
|
|
|
|
return 0;
|
2018-09-17 18:17:11 +02:00
|
|
|
}
|
2018-09-28 20:35:51 +02:00
|
|
|
|
|
|
|
/*******************************************************************************/
|