Bonjour a tous pour approfondire mais connaissance j'aimerai démarre un mini noyau en asm C/C++ j'ai passer 2 ans sur le C et 8 mois sur Asm
donc je suis aller sur se site pour Débuter se projet :
http://a.michelizza.free.fr/pmwiki.php
donc j'ai bien compris le bootloader en Asm et le kernel qui affiche un message
mon soucis c'est au passage du kernel en C donc voici le bootloader :
puis le kernel en C
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 %define BASE 0x1000 ; 0x0100:0x0 = 0x1000 %define KSIZE 50 ; nombre de secteurs a charger [BITS 16] [ORG 0x0] jmp start afficher: push ax push bx .debut: lodsb ; ds:si -> al cmp al, 0 ; fin chaine ? jz .fin mov ah, 0x0E ; appel au service 0x0e, int 0x10 du bios mov bx, 0x07 ; bx -> attribut, al -> caractere ascii int 0x10 jmp .debut .fin: pop bx pop ax ret start: ; initialisation des segments en 0x07C0 mov ax, 0x07C0 mov ds, ax mov es, ax mov ax, 0x8000 ; stack en 0xFFFF mov ss, ax mov sp, 0xf000 ; recuparation de l'unite de boot mov [bootdrv], dl ; affiche un msg mov si, msgDebut call afficher ; charger le noyau xor ax, ax int 0x13 push es mov ax, BASE mov es, ax mov bx, 0 mov ah, 2 mov al, KSIZE mov ch, 0 mov cl, 2 mov dh, 0 mov dl, [bootdrv] int 0x13 pop es ; initialisation du pointeur sur la GDT mov ax, gdtend ; calcule la limite de GDT mov bx, gdt sub ax, bx mov word [gdtptr], ax xor eax, eax ; calcule l'adresse lineaire de GDT xor ebx, ebx mov ax, ds mov ecx, eax shl ecx, 4 mov bx, gdt add ecx, ebx mov dword [gdtptr+2], ecx ; passage en modep cli lgdt [gdtptr] ; charge la gdt mov eax, cr0 or ax, 1 mov cr0, eax ; PE mis a 1 (CR0) jmp next next: mov ax, 0x10 ; segment de donne mov ds, ax mov fs, ax mov gs, ax mov es, ax mov ss, ax mov esp, 0x9F000 jmp dword 0x8:0x1000 ; reinitialise le segment de code ;-------------------------------------------------------------------- bootdrv: db 0 msgDebut: db "Chargement du kernel", 13, 10, 0 ;-------------------------------------------------------------------- gdt: db 0, 0, 0, 0, 0, 0, 0, 0 gdt_cs: db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10011011b, 11011111b, 0x0 gdt_ds: db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10010011b, 11011111b, 0x0 gdtend: ;-------------------------------------------------------------------- gdtptr: dw 0 ; limite dd 0 ; base ;-------------------------------------------------------------------- ;; NOP jusqu'a 510 times 510-($-$$) db 144 dw 0xAA55
le screen.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 extern void scrollup(unsigned int); extern void print(char *); extern kY; extern kattr; void _start(void) { kY = 18; kattr = 0x5E; print("un message\n"); kattr = 0x4E; print("un autre message\n"); scrollup(2); while (1); }
et le type.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 #include "types.h" #define RAMSCREEN 0xB8000 /* debut de la memoire video */ #define SIZESCREEN 0xFA0 /* 4000, nombres d'octets d'une page texte */ #define SCREENLIM 0xB8FA0 char kX = 0; /* position courante du curseur a l'ecran */ char kY = 17; char kattr = 0x0E; /* attributs video des caracteres a afficher */ /* * 'scrollup' scrolle l'ecran (la console mappee en ram) vers le haut * de n lignes (de 0 a 25). */ void scrollup(unsigned int n) { unsigned char *video, *tmp; for (video = (unsigned char *) RAMSCREEN; video < (unsigned char *) SCREENLIM; video += 2) { tmp = (unsigned char *) (video + n * 160); if (tmp < (unsigned char *) SCREENLIM) { *video = *tmp; *(video + 1) = *(tmp + 1); } else { *video = 0; *(video + 1) = 0x07; } } kY -= n; if (kY < 0) kY = 0; } void putcar(uchar c) { unsigned char *video; int i; if (c == 10) { /* CR-NL */ kX = 0; kY++; } else if (c == 9) { /* TAB */ kX = kX + 8 - (kX % 8); } else if (c == 13) { /* CR */ kX = 0; } else { /* autres caracteres */ video = (unsigned char *) (RAMSCREEN + 2 * kX + 160 * kY); *video = c; *(video + 1) = kattr; kX++; if (kX > 79) { kX = 0; kY++; } } if (kY > 24) scrollup(kY - 24); } /* * 'print' affiche a l'ecran, a la position courante du curseur, une chaine * de caracteres terminee par \0. */ void print(char *string) { while (*string != 0) { /* tant que le caractere est different de 0x0 */ putcar(*string); string++; } }
donc avec se boot.asm kernel.c screen.c type.h je compile le tous avec cette commande :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #ifndef _I386_TYPE_ #define _I386_TYPE_ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned char uchar; #endif
nasm -f bin boot.asm -o boot.c
gcc -c kernel.c -o kernel.o
gcc -c screen.c -o kernel.o
ld --oformat binary -Ttext 1000 kernel.o screen.o -o kernel
donc je me retrouve avec un boot.bin et un fichier kernel
j'installe Grub4dos sur usb et je démarre mon boot.bin et la j'ai chargement du kernel puis il charge mon noyau et reboot directement je suis perdu ici merci de votre aide
Partager