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-10-07 14:17:37 +02:00
# include "math.h"
2018-10-08 21:50:40 +02:00
# include "debug.h"
2018-10-14 16:18:51 +02:00
# include "VGA/ansi.c"
2018-09-17 18:17:11 +02:00
static command commands [ ] = {
2018-10-07 14:17:37 +02:00
{ " reboot " , " " , & rebootnow } ,
{ " clear " , " " , & clear } ,
{ " mode " , " " , & mode } ,
{ " detectcpu " , " " , & detectcpu } ,
{ " test2d " , " " , & test2d } ,
{ " regs " , " " , & regs } ,
{ " gdt " , " " , & readgdt } ,
{ " idt " , " " , & readidt } ,
{ " info " , " " , & info } ,
{ " err " , " " , & err } ,
{ " test " , " " , & test } ,
2018-10-07 14:53:48 +02:00
{ " view " , " " , & view } ,
2018-10-14 09:58:34 +02:00
{ " disasm " , " " , & disas } ,
2018-10-09 18:13:04 +02:00
{ " bpset " , " " , & bpset } ,
{ " bpclr " , " " , & bpclr } ,
{ " help " , " " , & help } ,
2018-10-14 16:18:51 +02:00
{ " logo " , " " , & logo } ,
2018-10-14 19:14:19 +02:00
{ " font " , " " , & sfont } ,
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 ) ;
2018-10-07 14:17:37 +02:00
strtolower ( & item ) ;
2018-09-27 17:47:27 +02:00
found = false ;
2018-10-09 18:13:04 +02:00
for ( i = 0 ; i < sizeof ( commands ) / sizeof ( commands [ 0 ] ) ; i + + ) {
2018-09-27 17:47:27 +02:00
if ( strcmp ( & item , & commands [ i ] . name ) = = 0 ) {
2018-10-07 14:17:37 +02:00
( * commands [ i ] . function ) ( & field ) ;
2018-09-27 17:47:27 +02:00
found = true ;
break ;
}
}
if ( ! found )
printf ( " Commande inconnue ! \r \n \000 " ) ;
2018-09-17 18:17:11 +02:00
}
}
2018-10-07 14:17:37 +02:00
int test ( void )
2018-10-04 16:29:54 +02:00
{
print ( " Fonction de test ! \r \n " ) ;
2018-10-09 18:13:04 +02:00
return ;
}
2018-10-14 19:14:19 +02:00
/*******************************************************************************/
/* Change la police courante */
int sfont ( u8 * commandline )
{
if ( strgetnbitems ( commandline , ' ' ) < 2 )
{
print ( " Syntaxe de la commande FONT \r \n font \33 [32mpolice \r \n \r \n \33 [32mpolice \33 [0m \33 [0m \33 [25D \33 [10C - \33 [Nom de la police de caractere \r \n " ) ;
return ;
}
setfont ( strgetpointeritem ( commandline , ' ' , 1 ) ) ;
}
2018-10-14 16:18:51 +02:00
/*******************************************************************************/
/* Affiche le logo */
int logo ( )
{
print ( ansilogo ) ;
return ;
}
2018-10-09 18:13:04 +02:00
/*******************************************************************************/
/* Renvoie les commandes disponibles */
int help ( )
{
print ( " Commandes disponibles : \r \n \r \n " ) ;
for ( u32 i = 0 ; i < sizeof ( commands ) / sizeof ( commands [ 0 ] ) ; i + + ) {
printf ( " %s \r \n " , & commands [ i ] . name ) ;
}
return 0 ;
}
/*******************************************************************************/
/* Met un breakpoint */
int bpset ( u8 * commandline )
{
u8 arg [ ] = " \000 " ;
u8 * numero ;
u8 * pointer ;
u8 type = DBG_EXEC ;
if ( strgetnbitems ( commandline , ' ' ) < 3 )
{
print ( " Syntaxe de la commande BPSET \r \n bpset \33 [32mnumero address [type] \r \n \r \n \33 [32mnumero \33 [0m \33 [0m \33 [25D \33 [10C - numero du breakpoint (0-3) \r \n \33 [32madresse \33 [0m \33 [25D \33 [10C - adresse du breakpoint \r \n \33 [32mtype \33 [0m \33 [25D \33 [10C - type de breakpoint (0-3) \r \n " ) ;
return ;
}
strgetitem ( commandline , & arg , ' ' , 1 ) ;
numero = strtoint ( & arg ) ;
if ( numero > 3 ) {
print ( " numero incorrect " ) ;
return ;
}
strgetitem ( commandline , & arg , ' ' , 2 ) ;
pointer = strtoint ( & arg ) ;
if ( strgetnbitems ( commandline , ' ' ) = = 4 )
{
strgetitem ( commandline , & arg , ' ' , 3 ) ;
type = strtoint ( & arg ) ;
}
if ( type > DBG_READWRITE )
{
print ( " type incorrect " ) ;
return ;
}
setdebugreg ( numero , pointer , type ) ;
}
/*******************************************************************************/
/* Retire un breakpoint */
int bpclr ( u8 * commandline )
{
u8 arg [ ] = " \000 " ;
u8 * numero ;
if ( strgetnbitems ( commandline , ' ' ) < 2 )
{
print ( " Syntaxe de la commande BPCLR \r \n bpclr \33 [32mnumero \r \n \r \n \33 [32mnumero \33 [0m \33 [0m \33 [25D \33 [10C - numero du breakpoint (0-3) \r \n " ) ;
return ;
}
strgetitem ( commandline , & arg , ' ' , 1 ) ;
numero = strtoint ( & arg ) ;
if ( numero > 3 ) {
print ( " numero incorrect " ) ;
return ;
}
setdebugreg ( numero , 0x0 , DBG_CLEAR ) ;
2018-10-04 16:29:54 +02:00
}
2018-10-08 21:50:40 +02:00
/*******************************************************************************/
/* Desassemble une zone de mémoire donnée */
2018-10-14 09:58:34 +02:00
int disas ( u8 * commandline )
2018-10-08 21:50:40 +02:00
{
u8 arg [ ] = " \000 " ;
u8 * size ;
u8 * pointer ;
if ( strgetnbitems ( commandline , ' ' ) < 3 )
{
print ( " Syntaxe de la commande DISASM \r \n disasm \33 [32madresse taille \r \n \r \n \33 [32madresse \33 [0m \33 [0m \33 [25D \33 [10C - Adresse a visualiser \r \n \33 [32mtaille \33 [0m \33 [25D \33 [10C - nombre d'octets a desassembler <256 \r \n " ) ;
return ;
}
strgetitem ( commandline , & arg , ' ' , 1 ) ;
2018-10-09 18:13:04 +02:00
pointer = strtoint ( & arg ) ;
size = pointer ;
2018-10-08 21:50:40 +02:00
strgetitem ( commandline , & arg , ' ' , 2 ) ;
size + = strtoint ( & arg ) ;
while ( pointer < size )
{
2018-10-14 09:58:34 +02:00
pointer + = disasm ( pointer , NULL , true ) ;
2018-10-08 21:50:40 +02:00
}
}
2018-10-04 16:29:54 +02:00
/*******************************************************************************/
2018-10-07 14:17:37 +02:00
/* Génère des exceptions */
2018-10-04 14:55:41 +02:00
2018-10-07 14:53:48 +02:00
int view ( u8 * commandline )
{
u8 arg [ ] = " \000 " ;
u32 address ;
u8 size ;
2018-10-08 21:50:40 +02:00
u8 * pointerb ;
u16 * pointerw ;
u32 * pointerd ;
u8 format ;
u8 nbligne ;
2018-10-07 14:53:48 +02:00
if ( strgetnbitems ( commandline , ' ' ) < 3 )
{
2018-10-08 21:50:40 +02:00
print ( " Syntaxe de la commande VIEW \r \n view \33 [32madresse taille [size] [nbligne] \r \n \r \n \33 [32madresse \33 [0m \33 [0m \33 [25D \33 [10C - Adresse a visualiser \r \n \33 [32mtaille \33 [0m \33 [25D \33 [10C - nombre d'octets a visualiser <256 \r \n \33 [32mformat \33 [0m \33 [25D \33 [10C - c (ascii) b (octet) w (mot) d (double mot) \r \n \33 [32mnbligne \33 [0m \33 [25D \33 [10C - nombre d'octets a visualiser par ligne \r \n " ) ;
2018-10-07 14:53:48 +02:00
return ;
}
strgetitem ( commandline , & arg , ' ' , 1 ) ;
address = strtoint ( & arg ) ;
strgetitem ( commandline , & arg , ' ' , 2 ) ;
size = strtoint ( & arg ) ;
2018-10-08 21:50:40 +02:00
if ( strgetnbitems ( commandline , ' ' ) < 4 )
format = ' b ' ;
else {
strgetitem ( commandline , & arg , ' ' , 3 ) ;
format = arg [ 0 ] ;
}
switch ( format ) {
case ' c ' :
pointerb = address ;
nbligne = 12 ;
break ;
case ' b ' :
pointerb = address ;
nbligne = 22 ;
break ;
case ' w ' :
pointerw = address ;
nbligne = 13 ;
break ;
case ' d ' :
pointerd = address ;
nbligne = 7 ;
break ;
}
if ( strgetnbitems ( commandline , ' ' ) = = 5 )
{
strgetitem ( commandline , & arg , ' ' , 4 ) ;
nbligne = strtoint ( & arg ) ;
}
2018-10-07 14:53:48 +02:00
printf ( " Adresse %Y - % hhu " , address , size ) ;
2018-10-08 21:50:40 +02:00
for ( u32 i = 0 ; i < size ; i + + )
switch ( format ) {
case ' c ' :
if ( i % nbligne = = 0 )
printf ( " \r \n :%Y - " , pointerb ) ;
printf ( " %hhY \33 [40C%c \33 [41D " , * ( pointerb ) , * ( pointerb + + ) ) ;
break ;
case ' b ' :
if ( i % nbligne = = 0 )
printf ( " \r \n :%Y - " , pointerb ) ;
printf ( " %hhY " , * ( pointerb + + ) ) ;
break ;
case ' w ' :
if ( i % nbligne = = 0 )
printf ( " \r \n :%Y - " , pointerw ) ;
printf ( " %hY " , * ( pointerw + + ) ) ;
break ;
case ' d ' :
if ( i % nbligne = = 0 )
printf ( " \r \n :%Y - " , pointerd ) ;
printf ( " %Y " , * ( pointerd + + ) ) ;
break ;
}
2018-10-07 14:53:48 +02:00
}
/*******************************************************************************/
/* Génère des exceptions */
2018-10-07 14:17:37 +02:00
int err ( u8 * commandline )
2018-10-04 14:55:41 +02:00
{
2018-10-07 14:17:37 +02:00
u8 arg [ ] = " \000 " ;
u32 argint ;
if ( strgetnbitems ( commandline , ' ' ) < 2 )
{
2018-10-08 21:50:40 +02:00
print ( " Syntaxe de la commande ERR \r \n err \33 [32mexception \r \n \r \n exception \33 [0m \33 [25D \33 [10C - code de l'exception \r \n " ) ;
2018-10-07 14:17:37 +02:00
return ;
}
strgetitem ( commandline , & arg , ' ' , 1 ) ;
argint = strtoint ( & arg ) ;
switch ( argint )
{
case 0 :
print ( " Creation d'une erreur de division par 0 ! \r \n " ) ;
asm ( " movl $0x0,%ecx; divl %ecx " ) ;
break ;
case 1 :
print ( " Creation d'un breakpoint ! \r \n " ) ;
2018-10-09 18:13:04 +02:00
setdebugreg ( 0 , & test , DBG_EXEC ) ;
test ( ) ;
2018-10-07 14:17:37 +02:00
break ;
case 2 :
print ( " NON GERE! \r \n " ) ;
break ;
case 3 :
print ( " Creation d'une erreur interruption 3 ! \r \n " ) ;
asm ( " int $0x3 " ) ;
break ;
case 4 :
print ( " NON GERE! \r \n " ) ;
break ;
case 5 :
print ( " NON GERE! \r \n " ) ;
break ;
case 6 :
print ( " Creation d'une erreur d'opcode invalide ! \r \n " ) ;
asm ( " mov %cr7, %eax " ) ;
break ;
case 7 :
print ( " NON GERE! \r \n " ) ;
break ;
case 8 :
print ( " NON GERE! \r \n " ) ;
break ;
case 9 :
print ( " NON GERE! \r \n " ) ;
break ;
case 10 :
print ( " NON GERE! \r \n " ) ;
break ;
case 11 :
print ( " Creation d'une erreur segment non present ! \r \n " ) ;
setidt ( & err , SEL_KERNEL_CODE , INTGATE , 104 ) ;
asm ( " int $0x68 " ) ;
break ;
case 12 :
print ( " NON GERE! \r \n " ) ;
break ;
case 13 :
print ( " Creation d'une erreur general fault ! \r \n " ) ;
asm ( " mov $0x666, %ax; ltr %ax " ) ;
break ;
case 14 :
if ( random ( 0 , 100 ) > 50 ) {
print ( " Creation d'une erreur de page en ecriture ! \r \n " ) ;
asm ( " movl $0x66666666,(0xE0000000) " ) ;
}
else {
print ( " Creation d'une erreur de page en lecture ! \r \n " ) ;
asm ( " movl (0xD0000000),%eax " ) ;
}
break ;
case 15 :
print ( " NON GERE! \r \n " ) ;
break ;
case 16 :
print ( " NON GERE! \r \n " ) ;
break ;
case 17 :
print ( " NON GERE! \r \n " ) ;
break ;
case 18 :
print ( " NON GERE! \r \n " ) ;
break ;
default :
print ( " Exception qui n'existe pas !!! \r \n " ) ;
break ;
}
return 0 ;
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 ;
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-10-07 14:17:37 +02:00
int mode ( u8 * commandline )
2018-09-27 17:47:27 +02:00
{
2018-10-07 14:17:37 +02:00
u8 arg [ ] = " \000 " ;
u32 argint ;
if ( strgetnbitems ( commandline , ' ' ) < 2 )
{
2018-10-08 21:50:40 +02:00
print ( " Syntaxe de la commande MODE \r \n mode \33 [32mmodevideo \r \n \r \n modevideo \33 [0m \33 [25D \33 [10C - mode video a initialiser (>0x80 = graphique) \r \n " ) ;
2018-10-07 14:17:37 +02:00
return ;
}
strgetitem ( commandline , & arg , ' ' , 1 ) ;
argint = strtoint ( & arg ) ;
2018-10-13 13:42:13 +02:00
changemode ( argint ) ;
2018-09-27 17:47:27 +02:00
return 0 ;
2018-09-17 18:17:11 +02:00
}
/*******************************************************************************/
/* Efface l'écran */
2018-09-27 17:47:27 +02:00
int clear ( )
{
2018-10-07 14:53:48 +02:00
clearscreen ( ) ;
2018-09-27 17:47:27 +02:00
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 ( )
{
2018-10-13 17:17:40 +02:00
videoinfos * vinfo = getvideo_info ( ) ;
2018-10-16 21:56:39 +02:00
if ( ! vinfo - > isgraphic ) {
print ( " Mode graphique necessaire afin de lancer ce programme \r \n " ) ;
return 1 ;
}
2018-09-27 17:47:27 +02:00
struct vertex2d a , b , c ;
randomize ( ) ;
2018-10-16 21:56:39 +02:00
u32 color ;
2018-10-13 17:17:40 +02:00
for ( int i = 0 ; i < 3000 ; i + + ) {
a . x = random ( 0 , vinfo - > currentwidth ) ;
a . y = random ( 0 , vinfo - > currentheight ) ;
b . x = random ( 0 , vinfo - > currentwidth ) ;
b . y = random ( 0 , vinfo - > currentheight ) ;
c . x = random ( 0 , vinfo - > currentwidth ) ;
c . y = random ( 0 , vinfo - > currentheight ) ;
2018-10-16 21:56:39 +02:00
if ( vinfo - > currentdepth > 24 )
color = egatorgb ( random ( 0 , 16 ) ) ;
else if ( vinfo - > currentdepth = = 8 )
color = random ( 0 , 256 ) ;
else
color = random ( 0 , 16 ) ;
trianglefilled ( & a , & b , & c , color ) ;
2018-10-17 14:09:01 +02:00
waitascii ( ) ;
triangle ( & a , & b , & c , egatorgb ( 4 ) ) ;
2018-09-27 17:47:27 +02:00
}
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 ) ;
2018-10-04 14:55:41 +02:00
printf ( " Information sur l'IDT \r \n Adresse:%X Limite:%hX \r \n " , idtreg . base ,
2018-09-27 17:47:27 +02:00
( 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 ) ;
2018-10-04 14:55:41 +02:00
u32 type = desc [ index ] . type & 0x0F00 ;
2018-10-07 12:57:38 +02:00
u8 * typestr1 , * typestr2 ;
2018-10-04 14:55:41 +02:00
if ( i > = 32 & i < = 39 )
2018-10-07 12:57:38 +02:00
typestr1 = " IRQ master " ;
2018-10-04 14:55:41 +02:00
else if ( i > = 96 & i < = 103 )
2018-10-07 12:57:38 +02:00
typestr1 = " IRQ slave " ;
2018-10-04 14:55:41 +02:00
else if ( i < 19 )
2018-10-07 12:57:38 +02:00
typestr1 = " EXCEPTION " ;
2018-10-04 14:55:41 +02:00
else
2018-10-07 12:57:38 +02:00
typestr1 = " INTERRUPT " ;
2018-09-27 17:47:27 +02:00
if ( type = = INTGATE )
2018-10-07 12:57:38 +02:00
typestr2 = " INTGATE " ;
2018-09-27 17:47:27 +02:00
else if ( type = = TRAPGATE )
2018-10-07 12:57:38 +02:00
typestr2 = " TRAPGATE " ;
2018-09-27 17:47:27 +02:00
else if ( type = = TASKGATE )
2018-10-07 12:57:38 +02:00
typestr2 = " TASKGATE " ;
2018-09-27 17:47:27 +02:00
else if ( type = = CALLGATE )
2018-10-07 12:57:38 +02:00
typestr2 = " CALLGATE " ;
2018-09-27 17:47:27 +02:00
else if ( type = = LDTDES )
2018-10-07 12:57:38 +02:00
typestr2 = " LDTDES " ;
2018-09-27 17:47:27 +02:00
else
print ( " inconnu " ) ;
2018-10-07 12:57:38 +02:00
printf ( " %s % hu %hY:%Y - %s \r \n " , typestr1 , i + + , select , offset , typestr2 ) ;
2018-09-27 17:47:27 +02:00
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 ;
struct gdtr gdtreg ;
sgdt ( & gdtreg ) ;
2018-10-04 14:55:41 +02:00
printf ( " Information sur la GDT \r \n Adresse:%X Limite:%hX \r \n " , gdtreg . base , gdtreg . limite ) ;
for ( index = 0 ; index < gdtreg . limite ; index + = sizeof ( gdtdes ) ) {
if ( ! isdesvalid ( index ) )
printf ( " \033 [31m " ) ;
printf ( " SEL =%hY %Y %Y DPL=%d %cS%d [%c%c%c] %h ub \033 [0m \r \n " , index , getdesbase ( index ) , getdeslimit ( index ) , getdesdpl ( index ) , getdestype ( index ) , getdessize ( index ) , getdesbit3 ( index ) , getdesbit2 ( index ) , getdesbit1 ( index ) , getdesalign ( index ) ) ;
2018-09-27 17:47:27 +02:00
}
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 \n Detection du processeur \r \033 [1m Revision \t :%d \r Modele \t :%d \r Famille \t :%d \r Nom cpuid \t :%s \r Jeux 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
/*******************************************************************************/