Salut a tous. Moi c'est Romain, j'approche les 20 ans, je ne fais aucune étude, et actuellement je me suis lancé un petit défi que j'ai vite beaucoup apprécié : un mini OS entièrement fait par moi.
Alors dans ce sens j'entend système de fichier fat12 ou fat16 et quelques utilitaires, ça serait niquel :p
Je suis débutant en asm mais j'aime ça
Actuellement j'ai un secteur de boot qui charge une IDT, initialise les segments, charge les secteurs suivants en 0x1000 et y saute.
Puis c'est mon noyau précédement chargé qui prend la main, il charge une GDT, rempli juste les descripteurs d'interruptions qui seront utiles au timer et au clavier (IRQ0 et IRQ1), programme les PICS (le pic maitre pointe sur mes descripteurs préalablement remlis, et je masque toutes les interruptions sauf le clavier et le timer), puis je démare les interruptions.
J'ai également fais quelques fonctions dont j'ai eu besoin. Mon driver clavier gère quelques touches de base.
Biensur le code n'a pas été revu, tout cela est assez brouillon, mais je le poste pour avoir des critiques sur ma facon de coder.
boot32.asm:
kernel32.asm :
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 %define BASE 0x100 ; 0x0100:0x0 = 0x1000 %define KSIZE 50 ; nombre de secteurs a charger [BITS 16] [ORG 0x00] jmp start %include "fn_boot.inc" 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 print16 ; 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 "Loading GDT and jumping to CS:0x1000...", 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
fn.inc :
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 %define IDTSIZE 50 ; Nombre d'interruptions %define BASE 0x1000 ; ------------------------------------------------------------- [BITS 32] [ORG 0x1000] jmp debut %include "fn.inc" debut: call clear mov esi, msgKernel call print lidt [idtptr] mov eax, int_clock ; Init IRQ0 mov word [idt+32*8], ax mov word [idt+32*8+2], 0x08 mov word [idt+32*8+4], 0x8e00 shr eax, 16 mov word [idt+32*8+6], ax mov eax, int_kbd ; Init IRQ1 mov word [idt+33*8], ax mov word [idt+33*8+2], 0x08 mov word [idt+33*8+4], 0x8e00 shr eax, 16 mov word [idt+33*8+6], ax call remap_pic sti jmp $ ; ------------------------------------------------------------- ; IRQ0 : Timer ; ------------------------------------------------------------- int_clock: mov al, 0x20 out 0x20, al iret ; ------------------------------------------------------------- ; IRQ1 : Driver Clavier A chaque fin de ligne la chaine est dans buff_cmd ; ------------------------------------------------------------- int_kbd: cli .wait: in al, 0x64 and al, 1 jz .wait in al, 0x60 cmp al, 224 je .wait cmp al, 0xf0 jl .release cmp al, 0x3f je .refresh cmp al, 0x0e je .backspace cmp al, 0x2a je .shift_enable movzx ebx, byte [shift] call convert_scan call putc .refresh: call clear jmp .end .shift_enable: mov byte [shift], 1 jmp .end .shift_disable: mov byte [shift], 0 jmp .end .release: sub al, 0x80 cmp al, 0x2a je .shift_disable jmp .end ; Backspace, seulement sur la meme ligne pour l'instant .backspace: movzx eax, byte [posx] cmp eax, 1 jl .end sub byte [posx], 1 mov esi, buff_space call putc sub byte [posx], 1 call move_cursor .end: mov al, 0x20 out 0x20, al sti iret ; ------------------------------------------------------------- msgKernel: db 'Kernel loaded...', 10, 13, 'Welcome to RomOS 0.1', 13, 10, 'Press F5 to refresh sreen.', 10, 0 buff_space: db ' ' shift: db 0 buff_cmd: times 256 db 0 buff_cmd_size: db 0 ;-------------------------------------------------------------------- idt: ; idt est la table d'interruptions times (IDTSIZE*8) db 0 ; 8 * 50 octets aloués (taille_idt_descriptor * nb_interrupt) idtptr: dw (IDTSIZE << 3) - 1 ; Nombre de vecteurs d'interruption * 8 - 1 dd (BASE+idt-$$) ; Adresse de la table ; ------------------------------------------------------------- ;; NOP jusqu'a 4096 times 4096-($-$$) db 90
fn_boot.inc :
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 ; ------------------------------------------------------------- ; Remplit la chaine ESI de ECX fois ; ------------------------------------------------------------- clear_string: pusha mov eax, 0 mov edi, esi .debut: stosb add edi, 1 loop .debut popa ret ; ------------------------------------------------------------- ; Converti scan-code en ASCII (puis l'affiche pour l'instant) ; AL = Scan-code EBX = Décalage ; ------------------------------------------------------------- convert_scan: push edi push eax dec eax shl eax, 1 ; Scancode x 2 mov edi, keyb_fr add edi, ebx add edi, eax mov esi, edi pop eax pop edi ret ; ------------------------------------------------------------- ; PUTC : Affiche le char dans ESI ; ------------------------------------------------------------- putc: pusha .debut: lodsb cmp al, 0 jz .end cmp al, 10 je .nl mov ah, 3 ; Couleur push eax ; Push le char ; Calcul: movzx eax, byte [posy] mov ebx, 160 mul ebx mov ebx, eax movzx eax, byte [posx] shl eax, 1 mov edi, 0xb8000 add edi, eax add edi, ebx ; Ecriture: pop eax ; Pop le char mov word [ds:edi], ax add byte [posx], 1 movzx eax, byte [posx] cmp eax, 80 je .nl .cont: movzx eax, byte [posy] cmp eax, 25 je .np jmp .end .end: call move_cursor popa ret ; New page: .np: call clear jmp .end ; New line .nl: add byte [posy], 1 mov byte [posx], 0 jmp .cont ; ------------------------------------------------------------- ; PRINT : Fonction d'affichage en mode protégé ; ESI = Chaine ; ------------------------------------------------------------- print: pusha .debut: lodsb cmp al, 0 jz .end cmp al, 10 je .lf cmp al, 13 je .cr mov ah, 3 push eax ; Calcul: movzx eax, byte [posy] mov ebx, 160 mul ebx mov ebx, eax movzx eax, byte [posx] shl eax, 1 mov edi, 0xb8000 add edi, eax add edi, ebx ; Ecriture: pop eax mov word [ds:edi], ax add byte [posx], 1 movzx eax, byte [posx] cmp eax, 80 je .lf .cont: movzx eax, byte [posy] cmp eax, 25 je .np call move_cursor jmp .debut .end: popa ret ; New page: .np: call clear jmp .debut ; Carriage-return .cr: mov byte [posx], 0 jmp .debut ; Line-feed: .lf: add byte [posy], 1 mov byte [posx], 0 jmp .cont ; ------------------------------------------------------------- ; PRINT_REG : Fonction d'affichage registre 32bits ; ------------------------------------------------------------- print_reg: pusha mov edi, outreg mov eax, [reg32] mov esi, hexchar mov ecx, 8 .debut: rol eax, 4 mov ebx, eax and ebx, 0x0f mov bl, [esi+ebx] mov [edi], bl inc edi dec ecx jnz .debut ; End: mov esi, outreg call print popa ret ; ------------------------------------------------------------- ; Fonction Clear ; ------------------------------------------------------------- clear: pusha mov byte [posx], 0 mov byte [posy], 0 mov ecx, 80*25 dec ecx .loop mov esi, space_buff call putc dec ecx cmp ecx, 0 jne .loop ; Clear le dernier byte de l'écran mov byte [ds:0xb8f9f], 1 mov byte [ds:0xb8fa0], ' ' mov byte [posx], 0 mov byte [posy], 0 call move_cursor popa ret ; ------------------------------------------------------------- ; Fonction qui remap les PICs ; ------------------------------------------------------------- remap_pic: pusha ; ICW1 : Séquence d'initalisation: mov al, 0x11 out 0x20, al out 0xA0, al jmp .2 ; ICW2 : On remap sur les bon vecteur .2: mov al, 0x20 out 0x21, al mov al, 0x28 out 0xA1, al jmp .3 ; ICW3 : On relie les pic entre eux .3: mov al, 0x08 out 0x21, al mov al, 0x03 out 0xA1, al jmp .4 ; ICW4 : Mode par défaut .4: mov al, 0x01 out 0x21, al out 0xA1, al ; Mask : mov al, 0xfc out 0x21, al mov al, 0xff out 0xA1, al popa ret ; ------------------------------------------------------------- ; Fonction de mise a jour du curseur ; ------------------------------------------------------------- move_cursor: pusha movzx eax, byte [posx] shl eax, 8 add al, byte [posy] mov ebx, eax and eax, 0xff mov ecx, 80 mul ecx mov ecx, ebx shr ecx, 8 add eax, ecx mov ecx, eax ; Low byte of pos mov al, 0x0f mov dx, 0x3d4 out dx, al mov eax, ecx mov dx, 0x3d5 out dx, al ; High byte of pos mov al, 0x0e mov dx, 0x3d4 out dx, al mov eax, ecx shr eax, 8 mov dx, 0x3d5 out dx, al popa ret ; ------------------------------------------------------------- hexchar: db '0123456789abcdef' outreg: db '00000000', 0 reg32: dd 0 space_buff: db ' ' posx: db 0 posy: db 0 keyb_fr: db 0, 0, '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0, '9', 0, '0', 0, ')', 0, '=', 0, 0x08, 0x08, 0, 0, 'a', 'A', 'z', 'Z', 'e', 'E', 'r', 'R', 't', 'T', 'y', 'Y', 'u', 'U', 'i', 'I', 'o', 'O', 'p', 'P', '^', '¨', '$', '£' , 10, 10, 0, 0, 'q', 'Q', 's', 'S', 'd', 'D', 'f', 'F', 'g', 'G', 'h', 'H', 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'ù', '%', 0, 0, 0, 0, 0, 0, 'w', 'W', 'x', 'X', 'c', 'C', 'v', 'V', 'b', 'B', 'n', 'N', ',', '?', ';', '.', ':', '/', '!', '§', 0, 0, 0, 0, 0, 0, ' ', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Voila Je pense que je vais faire une fonction strcmp histoire d'implementer un 'help' :p Et qui me servira pour la suite. Et surtout je me penche sur les systèmes de fichiers la...
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 ; ------------------------------------------------------------- ; Fonction d'affichage qui utilise le BIOS ; ------------------------------------------------------------- print16: push ax push bx .debut: lodsb or al, al ; zero=end of str jz .end ; get out mov ah, 0x0E mov bl, 0xff int 0x10 jmp .debut .end: pop bx pop ax ret
Edit : tout est en assembleur pour 2 raison : je voulais le faire pour m'y familiariser et étant sous windows actuelement j'ai des soucis lors du linkage... Je me pencherais la dessus quand mon OS aura une taille conséquente
Re-edit : Apparement Cygwin serait une bonne idée pour pouvoir compiler sous windows des fichiers linkables avec des binaires asm. Si quelqu'un pouvait m'en parler car je l'ai lu sur un site en anglais et je ne suis pas sur de tout comprendre.
Partager