From 4a4886886e2402512a1f55b0e4ad9cdf8c209c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Hord=C3=A9?= Date: Thu, 27 Sep 2018 21:01:02 +0200 Subject: [PATCH] feat: creation d'une commande multiboot et ajout gestion arithematique sur 64 bits, amelioration de printf --- include/math.h | 2 + include/multiboot2.h | 3 + include/shell.h | 1 + include/types.h | 2 +- include/video.h | 2 +- lib/math.c | 214 +++++++++++++++++++++++++++++++------------ lib/multiboot.c | 153 +++++++++++++++++++++++++++++++ lib/shell.c | 14 ++- lib/video.c | 70 ++++++++++---- makefile | 4 +- system/system.c | 29 +++--- 11 files changed, 401 insertions(+), 93 deletions(-) create mode 100644 lib/multiboot.c diff --git a/include/math.h b/include/math.h index 7c559ae..7ee9f78 100755 --- a/include/math.h +++ b/include/math.h @@ -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); diff --git a/include/multiboot2.h b/include/multiboot2.h index 1d65843..1b07850 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -382,4 +382,7 @@ u32 size; u32 load_base_addr; }; + +void getbootinfo(void); +void initmultiboot(const u32 addr); diff --git a/include/shell.h b/include/shell.h index 32c527e..45f23e1 100644 --- a/include/shell.h +++ b/include/shell.h @@ -13,3 +13,4 @@ int detectcpu(); int mode(); int clear(); int dump_regs(); +int info(); diff --git a/include/types.h b/include/types.h index 347bafe..da8656f 100755 --- a/include/types.h +++ b/include/types.h @@ -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; diff --git a/include/video.h b/include/video.h index 4803b8f..c5af8d5 100755 --- a/include/video.h +++ b/include/video.h @@ -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); diff --git a/lib/math.c b/lib/math.c index ea2a9c3..cc21eb7 100755 --- a/lib/math.c +++ b/lib/math.c @@ -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; + +} + diff --git a/lib/multiboot.c b/lib/multiboot.c new file mode 100644 index 0000000..0fa3914 --- /dev/null +++ b/lib/multiboot.c @@ -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; + } + + } + } +} + diff --git a/lib/shell.c b/lib/shell.c index c9995e1..06637fa 100644 --- a/lib/shell.c +++ b/lib/shell.c @@ -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); } } diff --git a/lib/video.c b/lib/video.c index 806f939..134f452 100755 --- a/lib/video.c +++ b/lib/video.c @@ -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; diff --git a/makefile b/makefile index 8d3c248..51eb030 100755 --- a/makefile +++ b/makefile @@ -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 &) diff --git a/system/system.c b/system/system.c index b704769..2edf954 100755 --- a/system/system.c +++ b/system/system.c @@ -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();