feat: creation d'une commande multiboot et ajout gestion arithematique sur 64 bits, amelioration de printf

This commit is contained in:
Nicolas Hordé 2018-09-27 21:01:02 +02:00
parent cd9129dc15
commit 4a4886886e
11 changed files with 401 additions and 93 deletions

View File

@ -6,3 +6,5 @@ u32 rand();
void randomize();
u8 log2(u32 n);
u8 log10(u32 n);
unsigned long long __udivdi3 (unsigned long long num, unsigned long long den);
unsigned long long __umoddi3 (unsigned long long n, unsigned long long d);

View File

@ -382,4 +382,7 @@
u32 size;
u32 load_base_addr;
};
void getbootinfo(void);
void initmultiboot(const u32 addr);

View File

@ -13,3 +13,4 @@ int detectcpu();
int mode();
int clear();
int dump_regs();
int info();

View File

@ -25,7 +25,7 @@ typedef unsigned long long UQWORD;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long int u64;
typedef unsigned long long int u64;
typedef char s8;
typedef short s16;
typedef int s32;

View File

@ -16,6 +16,6 @@ void putchar(u8 thechar);
u32 print(u8* string);
u32 printf (const u8 *string, ...);
void changevc(u8 vc);
u8* itoa(u32 num, u8* str, u8 base, u32 dim, u8 achar);
u8* itoa(u64 num, u8* str, u8 base, u64 dim, u8 achar);
u8* sitoa(int num, u8* str, u32 dim);

View File

@ -1,83 +1,179 @@
#include "types.h"
#include "timer.h"
unsigned long long __udivdi3 (unsigned long long num, unsigned long long den)
{
unsigned long long quot, qbit;
quot = 0;
qbit = 1;
if (den == 0)
{
return 0;
}
while ((long long) den >= 0)
{
den <<= 1;
qbit <<= 1;
}
while (qbit)
{
if (den <= num)
{
num -= den;
quot += qbit;
}
den >>= 1;
qbit >>= 1;
}
return quot;
}
unsigned long long __umoddi3 (unsigned long long n, unsigned long long d)
{
return n - d * __udivdi3 (n, d);
}
/******************************************************************************/
/* Fonction qui retourne le logarithme 2 */
u8 log2(u32 n)
{
if (n == 0)
return 0;
int logValue = -1;
while (n) {
logValue++;
n >>= 1;
}
return logValue + 1;
}
u8 log2(u64 n)
{
if (n == 0)
return 0;
int logValue = -1;
while (n) {
logValue++;
n >>= 1;
}
return logValue + 1;
}
/******************************************************************************/
/* Fonction qui retourne le logarithme 10 */
u8 log10(u32 n)
{
return (n >= 1000000000u) ? 9 : (n >= 100000000u) ? 8 :
u8 log10(u64 n)
{
return (n >= 10000000000000000000u) ? 19 : (n >= 100000000000000000u) ? 18 :
(n >= 100000000000000000u) ? 17 : (n >= 10000000000000000u) ? 16 :
(n >= 1000000000000000u) ? 15 : (n >= 100000000000000u) ? 14 :
(n >= 10000000000000u) ? 13 : (n >= 1000000000000u) ? 12 :
(n >= 100000000000u) ? 11 : (n >= 10000000000u) ? 10 :
(n >= 1000000000u) ? 9 : (n >= 100000000u) ? 8 :
(n >= 10000000u) ? 7 : (n >= 1000000u) ? 6 :
(n >= 100000u) ? 5 : (n >= 10000u) ? 4 :
(n >= 1000u) ? 3 : (n >= 100u) ? 2 : (n >= 10u) ? 1u : 0u;
}
(n >= 1000u) ? 3 : (n >= 100u) ? 2 : (n >= 10u) ? 1u : 0u;
}
/******************************************************************************/
/* Fonction qui retourne la valeur absolue */
u32 abs(int x)
{
if (x < 0)
x = -x;
return (u32) x;
}
u32 abs(int x)
{
if (x < 0)
x = -x;
return (u32) x;
}
/******************************************************************************/
/* Fonction qui initialise le générateur de nombre aléatoire */
static u32 seed = 0x12341234;
void randomize()
{
seed = gettimer();
}
static u32 seed = 0x12341234;
void randomize()
{
seed = gettimer();
}
/******************************************************************************/
/* Fonction qui renvoie un nombre aléatoire */
u32 rand()
{
u32 next = seed;
int result;
next *= 1103515245;
next += 12345;
result = (unsigned int)(next / 65536) % 2048;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int)(next / 65536) % 1024;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int)(next / 65536) % 1024;
seed = next;
return result;
}
u32 rand()
{
u32 next = seed;
int result;
next *= 1103515245;
next += 12345;
result = (unsigned int)(next / 65536) % 2048;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int)(next / 65536) % 1024;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int)(next / 65536) % 1024;
seed = next;
return result;
}
/******************************************************************************/
/* Fonction qui renvoie un nombre aléatoire borné */
u32 random(u32 lower, u32 upper)
{
return (rand() % (upper - lower + 1)) + lower;
}
u32 random(u32 lower, u32 upper)
{
return (rand() % (upper - lower + 1)) + lower;
}

153
lib/multiboot.c Normal file
View File

@ -0,0 +1,153 @@
#include "multiboot2.h"
static u32 infobloc;
void initmultiboot(const u32 addr)
{
infobloc=addr;
}
void getbootinfo(void)
{
u32 addr=infobloc;
struct multiboot_tag *tag;
unsigned size = *(unsigned *) addr;
if (addr & 7) print("Non aligne...");
printf(" Taille :%X\r\n", (u32)size);
for (tag = (struct multiboot_tag *) (addr + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct multiboot_tag *) ((u8 *) tag + ((tag->size + 7) & ~7)))
{
printf ("Tag 0x%x, Taille 0x%x\r\n", tag->type, tag->size);
switch (tag->type)
{
case MULTIBOOT_TAG_TYPE_CMDLINE:
printf ("line de lancement : %s\r\n",
((struct multiboot_tag_string *) tag)->string);
break;
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
printf ("Chargeur de boot : %s\r\n",
((struct multiboot_tag_string *) tag)->string);
break;
case MULTIBOOT_TAG_TYPE_MODULE:
printf ("Module %x-%x. Command line %s\r\n",
((struct multiboot_tag_module *) tag)->mod_start,
((struct multiboot_tag_module *) tag)->mod_end,
((struct multiboot_tag_module *) tag)->cmdline);
break;
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
printf ("Memoire basse : %uKB, memoire haute = %uKB\r\n",
((struct multiboot_tag_basic_meminfo *) tag)->mem_lower,
((struct multiboot_tag_basic_meminfo *) tag)->mem_upper);
break;
case MULTIBOOT_TAG_TYPE_BOOTDEV:
printf ("Peripherique de demarrage : %x,%u,%u\r\n\r\n",
((struct multiboot_tag_bootdev *) tag)->biosdev,
((struct multiboot_tag_bootdev *) tag)->slice,
((struct multiboot_tag_bootdev *) tag)->part);
break;
case MULTIBOOT_TAG_TYPE_MMAP:
{
multiboot_memory_map_t *mmap;
printf ("*** Plan de memoire ***\r\n");
for (mmap = ((struct multiboot_tag_mmap *) tag)->entries;(u8 *) mmap < (u8 *) tag + tag->size; mmap = (multiboot_memory_map_t *)
((unsigned long) mmap + ((struct multiboot_tag_mmap *) tag)->entry_size))
printf (" adresse: %lx,"" taille:%lx, type:%x\r\n",
(u64) (mmap->addr),
(u64) (mmap->len),
(u32) (mmap->type));
}
break;
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
{
u32 color;
unsigned i;
struct multiboot_tag_framebuffer *tagfb
= (struct multiboot_tag_framebuffer *) tag;
void *fb = (void *) (unsigned long) tagfb->common.framebuffer_addr;
switch (tagfb->common.framebuffer_type)
{
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
{
unsigned best_distance, distance;
struct multiboot_color *palette;
palette = tagfb->framebuffer_palette;
color = 0;
best_distance = 4*256*256;
for (i = 0; i < tagfb->framebuffer_palette_num_colors; i++)
{
distance = (0xff - palette[i].blue)
* (0xff - palette[i].blue)
+ palette[i].red * palette[i].red
+ palette[i].green * palette[i].green;
if (distance < best_distance)
{
color = i;
best_distance = distance;
}
}
}
break;
case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
color = ((1 << tagfb->framebuffer_blue_mask_size) - 1)
<< tagfb->framebuffer_blue_field_position;
break;
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
color = '\\' | 0x0100;
break;
default:
color = 0xffffffff;
break;
}
for (i = 0; i < tagfb->common.framebuffer_width
&& i < tagfb->common.framebuffer_height; i++)
{
switch (tagfb->common.framebuffer_bpp)
{
case 8:
{
u8 *pixel = fb
+ tagfb->common.framebuffer_pitch * i + i;
*pixel = color;
}
break;
case 15:
case 16:
{
u16 *pixel
= fb + tagfb->common.framebuffer_pitch * i + 2 * i;
*pixel = color;
}
break;
case 24:
{
u32 *pixel
= fb + tagfb->common.framebuffer_pitch * i + 3 * i;
*pixel = (color & 0xffffff) | (*pixel & 0xff000000);
}
break;
case 32:
{
u32 *pixel
= fb + tagfb->common.framebuffer_pitch * i + 4 * i;
*pixel = color;
}
break;
}
}
break;
}
}
}
}

View File

@ -7,6 +7,7 @@
#include "2d.h"
#include "gdt.h"
#include "shell.h"
#include "multiboot2.h"
static command commands[] = {
{"REBOOT", "", &rebootnow},
@ -17,6 +18,7 @@ static command commands[] = {
{"REGS", "", &dump_regs},
{"GDT", "", &readgdt},
{"IDT", "", &readidt},
{"INFO", "", &info}
};
/*******************************************************************************/
@ -53,6 +55,16 @@ void shell()
/*******************************************************************************/
/* Information sur le démarrage */
int info()
{
getbootinfo();
return 0;
}
/*******************************************************************************/
/* Affiche les registres */
int regs()
@ -216,7 +228,7 @@ int readgdt()
print("4k ");
else
print("1b ");
u8 dpl = (acces >> 5) & 0 b11;
u8 dpl = (acces >> 5) & 0b11;
printf("DPL:%d", dpl);
}
}

View File

@ -309,10 +309,10 @@ u32 print(u8 * string)
u32 printf(const u8 * string, ...)
{
va_list args;
u32 sizes[] = { 0xFF, 0xFFFF, 0xFFFFFFFF };
u8 strbase2[] = "b\000";
u8 strbase8[] = "o\000";
u8 strbase16[] = "h\000";
u64 sizes[] = { 0xFF, 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFFFFFFFFFF };
u8 strbase2[] = "0xb\000";
u8 strbase8[] = "0xo\000";
u8 strbase16[] = "0x\000";
u8 hexadecimal[] = "*0x\000";
u8 achar, temp;
u8 asize, charadd;
@ -320,7 +320,7 @@ u32 printf(const u8 * string, ...)
u8 *str = string;
u8 *strtemp;
u32 i = 0, counter = 0;
u32 num;
u64 num;
bool flag = false;
va_start(args, string);
@ -345,14 +345,23 @@ u32 printf(const u8 * string, ...)
break;
case 'h':
asize--;
if (asize<0) asize=0;
flag = true;
break;
case 'l':
asize++;
if (asize>3) asize=3;
flag = true;
break;
case 'u':
num = (u32) va_arg(args, int);
if (asize==0)
num = (u64) va_arg(args, u8);
else if (asize==1)
num = (u64) va_arg(args, u16);
else if (asize==2)
num = (u64) va_arg(args, u32);
else
num = (u64) va_arg(args, u64);
if (charadd == 0xFF)
charadd = '0';
itoa(num, &buffer, 10, sizes[asize], charadd);
@ -360,12 +369,19 @@ u32 printf(const u8 * string, ...)
flag = false;
break;
case 'o':
num = (u32) va_arg(args, int);
if (asize==0)
num = (u64) va_arg(args, u8);
else if (asize==1)
num = (u64) va_arg(args, u16);
else if (asize==2)
num = (u64) va_arg(args, u32);
else
num = (u64) va_arg(args, u64);
if (charadd == 0xFF)
charadd = '0';
itoa(num, &buffer, 8, sizes[asize], charadd);
counter += print(&buffer) + 1;
print(&strbase8);
counter += print(&buffer) + 1;
flag = false;
break;
case 'c':
@ -376,7 +392,14 @@ u32 printf(const u8 * string, ...)
break;
case 'd':
case 'i':
num = (int)va_arg(args, int);
if (asize==0)
num = (u64) va_arg(args, u8);
else if (asize==1)
num = (u64) va_arg(args, u16);
else if (asize==2)
num = (u64) va_arg(args, u32);
else
num = (u64) va_arg(args, u64);
if (charadd == 0xFF)
charadd = ' ';
sitoa(num, &buffer, sizes[asize]);
@ -399,23 +422,37 @@ u32 printf(const u8 * string, ...)
break;
case 'x':
case 'X':
num = (u32) va_arg(args, int);
if (asize==0)
num = (u64) va_arg(args, u8);
else if (asize==1)
num = (u64) va_arg(args, u16);
else if (asize==2)
num = (u64) va_arg(args, u32);
else
num = (u64) va_arg(args, u64);
if (charadd == 0xFF)
charadd = '0';
itoa(num, &buffer, 16, sizes[asize], charadd);
if (achar == 'X')
strtoupper(&buffer);
counter += print(&buffer) + 1;
print(&strbase16);
counter += print(&buffer) + 1;
flag = false;
break;
case 'b':
num = (u32) va_arg(args, int);
if (asize==0)
num = (u64) va_arg(args, u8);
else if (asize==1)
num = (u64) va_arg(args, u16);
else if (asize==2)
num = (u64) va_arg(args, u32);
else
num = (u64) va_arg(args, u64);
if (charadd == 0xFF)
charadd = '0';
itoa(num, &buffer, 2, sizes[asize], charadd);
counter += print(&buffer) + 1;
print(&strbase2);
counter += print(&buffer) + 1;
flag = false;
break;
default:
@ -431,11 +468,10 @@ u32 printf(const u8 * string, ...)
/* converti un entier non signé en chaine de caractère */
u8 *itoa(u32 orignum, u8 * str, u8 base, u32 dim, u8 achar)
u8 *itoa(u64 orignum, u8 * str, u8 base, u64 dim, u8 achar)
{
u32 sizes[] = { 0xFF, 0xFFFF, 0xFFFFFFFF };
u8 *pointer = str, i, size = 0;
u32 num = orignum;
u64 num = orignum;
num &= dim;
if (num == 0 && (achar == 0)) {
*(pointer++) = '0';
@ -457,7 +493,7 @@ u8 *itoa(u32 orignum, u8 * str, u8 base, u32 dim, u8 achar)
break;
}
for (i = 0; i < size; i++) {
u32 result = num % (u32) base;
u64 result = num % (u32) base;
*(pointer++) =
(result > 9) ? (result - 10) + 'a' : result + '0';
num = num / (u32) base;

View File

@ -50,6 +50,8 @@ retest64: littleclean test64
floppytest: bits32 floppy qemu-floppy
refloppytest: littleclean floppytest
view:
(hexdump -C ./final/harddisk.img.final|head -c10000)
@ -76,7 +78,7 @@ qemu-debug64:
(killall qemu-system-x86_64;qemu-system-x86_64 -m 1G -drive format=raw,file=./final/harddiskuefi.img.final --bios /usr/share/qemu/OVMF.fd -s -S &)
qemu:
(killall qemu-system-i386;qemu-system-i386 -m 1G -drive format=raw,file=./final/harddisk.img.final --enable-kvm -cpu host -s &)
(killall qemu-system-i386;qemu-system-i386 -m 5G -drive format=raw,file=./final/harddisk.img.final --enable-kvm -cpu host -s &)
qemu64:
(killall qemu-system-x86_64;qemu-system-x86_64 -m 1G -drive format=raw,file=./final/harddiskuefi.img.final --bios /usr/share/qemu/OVMF.fd --enable-kvm -cpu host -s &)

View File

@ -15,11 +15,11 @@
#include "multiboot2.h"
static u8 warnmsg[] =
"\033[99C\033[8D\033[37m\033[1m[ \033[36mNON\033[37m ]\033[0m\000";
"\033[99C\033[8D\033[37m\033[1m[ \033[36mNON\033[37m ]\033[0m";
static u8 okmsg[] =
"\033[99C\033[8D\033[37m\033[1m[ \033[32mOK\033[37m ]\033[0m\000";
"\033[99C\033[8D\033[37m\033[1m[ \033[32mOK\033[37m ]\033[0m";
static u8 errormsg[] =
"\033[99C\033[8D\033[37m\033[1m[\033[31mERREUR\033[37m]\033[0m\000";
"\033[99C\033[8D\033[37m\033[1m[\033[31mERREUR\033[37m]\033[0m";
static u8 key = 0;
void ok()
@ -40,7 +40,7 @@ void error()
return;
}
int main(unsigned long magic, unsigned long addr)
int main(u32 magic, u32 addr)
{
cli();
setvmode(0x02);
@ -49,42 +49,45 @@ int main(unsigned long magic, unsigned long addr)
print("\033[2J\000");
printf(ansilogo);
print("\033[37m\033[0m -Chargement noyaux\000");
print("\033[37m\033[0m -Chargement noyaux");
ok();
printf("\033[37m\033[0m -Nombre magique multiboot2 : %X\000",
printf("\033[37m\033[0m -Nombre magique multiboot2 : %X",
(u32) magic);
if (magic == MULTIBOOT2_BOOTLOADER_MAGIC)
{
initmultiboot(addr);
ok();
}
else
error();
print("\033[37m\033[0m -Initilisation de la memoire (GDT)\000");
print("\033[37m\033[0m -Initilisation de la memoire (GDT)");
initgdt(&&next);
next:
ok();
print("\033[37m\033[0m -Initilisation des taches (TSR)\000");
print("\033[37m\033[0m -Initilisation des taches (TSR)");
inittr();
ok();
print("\033[37m\033[0m -Initilisation des interruptions (IDT/PIC)\000");
print("\033[37m\033[0m -Initilisation des interruptions (IDT/PIC)");
initidt();
initpic();
sti();
ok();
print(" -Installation du handler timer (IRQ 0)\000");
print(" -Installation du handler timer (IRQ 0)");
setidt((u32) timer, SEL_KERNEL_CODE, INTGATE, 32);
enableirq(0);
ok();
print(" -Installation du handler clavier (IRQ 1)\000");
print(" -Installation du handler clavier (IRQ 1)");
setidt((u32) keyboard, SEL_KERNEL_CODE, INTGATE, 33);
enableirq(1);
ok();
print(" -Installation du handler souris (IRQ12+Cascade IRQ2)\000");
print(" -Installation du handler souris (IRQ12+Cascade IRQ2)");
setidt((u32) mouse, SEL_KERNEL_CODE, INTGATE, 100);
enableirq(2);
enableirq(12);
@ -93,7 +96,7 @@ int main(unsigned long magic, unsigned long addr)
else
ok();
print(" -Installation des appels systemes utilisateur\000");
print(" -Installation des appels systemes utilisateur");
initsyscall();
ok();