[Asm] Mon système d'exploitation

Statut
N'est pas ouverte pour d'autres réponses.

neku

Codeur roumain
Voici, j'ai commencé à écrire mon système d'exploitation
Si comme moi vous êtes intéressé par la création d'un OS, je posterai régulièrement; Des tutos, des explications, les codes sources ...
J'ai donc actuellement commencé l'écriture du bootsector (secteur de démarrage)
512octets max ;)
Ecrit pour NASM

bootsect.asm
Code:
;Ce secteur de démarrage à été réalisé par Neku
;rb_neku@hotmail.com
;Ce secteur de démarrage est sous license GPL

[ORG 0]
	jmp 07C0h:start	;On se déplace au segment 0700 (la ou le bios charge le bootsector)
	
%include "fat12.asm"

%define buffer 0x7e00
%define file 0x8000

setup	db	'NEKU32',0
kernelname	db	'SETUP   BIN',0
loadk	db	'Starting...',10,13,0
knf	db	'Kernel not found !',10,13,0
mpause	db	'Presse any key to continue !',10,13,0

%define bootdrive 0

LOAD_ADDR DW 9020h

start:

	cli
	mov    AX,9000h
	mov    SS,AX
	mov    SP,0h
	sti
	
	;mov es, ax
	;push ax
	;xor ax, ax
	;mov ds, ax

	;mov ax, 7c00h
	;mov si, ax
	;mov di, ax

	;mov cx, 0100h
	;rep movsw

	;mov ax, go
	;push ax

	;retf
	
	jmp go

go:
	;Mise à jour des registres de segments
	mov ax, cs
	mov ds, ax
	mov es, ax
	
	;call detect_cpu
.386	;A partir d'ici ou utilisera les instruction 386
	jmp load
	
load:
	mov si, loadk
	call print
	
	mov ax, 19	;Premier secteur de la FAT

lo1:
	push ax
	mov bx, buffer
	
	call readsector
	mov cx, 16
	mov dl, 1

lo2:
	push cx
	mov di, file
	mov bx, buffer
	
	call buf2file
	
	mov bx, file
	
	call decompfile
	
	mov si, filename
	mov di, kernelname
	mov cx, 11
	repe cmpsb
	jz kfound
	
next1:
	inc dl
	
	pop cx
	loop lo2
	pop ax
	cmp ax, 32
	jge NotFound
	
	inc ax
	jmp lo1
	
kfound:
	mov si, kernelname
	call print

	pop cx
	pop ax
	
	mov ax, 1
	call sl2p
	mov bx, buffer
	mov ah, 02
	mov al, 9
	mov dl, bootdrive
	int 13h
	
	mov bx, 0
	push bx
	
	mov ax, [LOAD_ADDR]
	mov es, ax
	
lo:
	mov ax, [cluster]
	pop bx
	add ax, 31
	call readsector
	add bx, 512
	push bx
	
	mov bx, buffer
	mov ax, [cluster]
	call getnextcluster
	
	cmp ax, 0x0FF8
	jb lo
	
	cmp word [LOAD_ADDR], 9020h
	jne finish
	
	mov ax, ds
	mov es, ax
	mov si, setup
	mov di, kernelname
	mov cx, 8
	rep movsb
	mov [LOAD_ADDR], word 100h
	jmp load
	
finish:
	mov ax, word 0x9020
	jmp 0x9020:0
	
NotFound:
	mov si, knf
	call print
	call keywait
	
	int 19h
	jmp $
	
;===============
;Reset_Drive
;===============
;reset_drive:
;	mov ax, 0
;	mov dl, 0
;	int 13h
;	jc reboot	;Si il y a une erreur on reboot ;)
;===============
;/Reset_Drive
;===============
	
;===============
;Keywait
;===============
keywait:	;On attend que l'utilisateur appuye sur une touche
	mov si, mpause
	call print
	mov ah, 0	;Attende d'une touche
	int 016h
	ret
;===============
;/Keywait
;===============

;===============
;Reboot
;===============
reboot:	;On redemarre la machine
	call keywait	;On attend que l'utilisateur appuye sur une touche
	db 0eah	;saut à FFFF:0000 (reboot)
	dw 0000h
	dw 0FFFFh
;===============
;/Reboot
;===============

;===============
;Print
;===============
print:	;Fonction permettant l'affichage de message à l'écran
	lodsb	;en utilisant l'interruption 10h
	
	or al, al	;Si al = 0
	jz done	;Done
	
	mov ah, 0Eh
	mov bx, 0007
	int 0x10
	
	jmp print
done:
	ret
;===============
;/Print
;===============
	
;hang:
;	jmp hang	;Hang !

times 510-($-$$) db 0
dw 0AA55h

[SEGMENT .bss]
filename resb 8
ext resb 3
fat12.asm
Code:
;driver permettant au secteur de boot de gerer la fat12
;Merci à Alaa eddine KADDOURI

%define cluster 0xFF0

;=============
;sl2p
;Conversion Secteur logique -> Physique
;Entrée : AX = numéro logique du secteur (0..2879)
;Sotie:
;cl = numéro du secteur (1..18)
;dh = numéro de la piste (0..79)
;ch = numéro de la face (0 ou 1)
;=============
sl2p:
	xor dx, dx	;Préparation d'un division
	push ax		;Sauvegarde de AX
	push bx		;Sauvegarde de BX
	mov bx, 18	;18 Secteurs/Piste
	div bx		;On divise le n° de secteur par le nombre de secteurs/piste pour récupérer
				;le nombre de secteurs sur la piste
	
	mov cx, dx	;On place le reste la division dans cx (pour int 13h)
	xor dx, dx	;Préparation de la division
	
	mov bx, 2	;On divise le reste par 2 de la division précédente
	div bx		;pour récupérr sur quelle tête se trouve le secteur
	pop bx		;restauration de bx
	mov dh, dl	;on place le numéro de tête dans dh (pour int 13h)
	
	ror ah, 2	;On décale 2 fois à droite ah
	xchg al, ah	;et on échange ah et al
	mov dl, 18	;18 secteurs/piste
	sub dl, cl	;On soustrait le reste de la division qui permet d'obtenir
				;le numéro de secteur sur la piste
	inc cl		;et en ajoutant 1 on obtient le n° de piste
	or cx, ax	;sans oublier d'ajouteur les bits de AX
	mov dl, al	;On a le n° de tête dans AL
	pop ax		;On restaure AX
	
	ret
;=============
;/sl2p
;=============

;=============
;readsector
;Lecture d'un secteur
;Entrée :
;AX = numéro logique du secteur (0..2879)
;BX = le buffer qui recevra les données
;Sortie : Aucune
;=============
readsector:
	push ax	;On sauvegarde AX
	push dx	;On sauvegarde DX
	
	call sl2p	;Conversion secteur logique -> secteur physique
	
	mov ah, 02h	;Fonction de lecture
	mov al, 01h	;d'un secteur
	int 13h
	
	pop dx	;On restaure DX
	pop ax	;On restaure AX
	ret
;=============
;/readsector
;=============

;=============
;buf2file
;Extraction d'une entrée du répertoire principale depuis un buffer
;Entrée :
;BX = buffer source 512 octets
;DL = Numéro de l'entrée (1..16)
;DI = buffer cible 32 octets
;Sortie : Aucune
;=============
buf2file:
	push ax		;On sauvegarde AX
	push bx		;On sauvegarde BX
	push cx		;On sauvegarde CX
	push si		;On sauvegarde SI
	
	mov al, 32	;On calcule le rang de l'entrée qu'on veut extraire
	mul dl
	sub ax, 32
	add bx, ax	;On ajoute le rang au buffer
	
	mov si, bx	;Puis on affectue notre copie
	mov cx, 16	;Chaque entrée contient 32 octets
	
.getfile:
	movsw
	loop .getfile
	
.fin
	pop si		;On restaure SI
	pop cx		;On restaure CX
	pop bx		;On restaure BX
	pop ax		;On restaure AX
	
	ret
;=============
;/buf2file
;=============

;=============
;decompfile
;Décomposition des entrées du répertoire principal
;Entrée:
;BX = le buffer qui contient l'entrée à décomposée (32 octets)
;DI = le buffer du nom de fichier
;Sortie:
;filename = nom du fichier
;attr = contient les attributs
;cluster = contient le 1er cluster du fichier
;=============
decompfile:
	push ax
	push bx
	push cx
	
	mov si, bx
	mov di, filename
	mov cx, 11
	
.getfilename:
	lodsb
	cmp cx, 11
	jne .stock
	cmp al, 31
	jg .stock
	mov al, 0
	stosb
	jmp .nofile

.stock:
	stosb
	loop .getfilename
	
	add bx, 26
	mov si, bx
	mov di, cluster
	mov cx, 3
	rep movsw
	
.nofile:
	pop cx
	pop bx
	pop ax
	
	ret
;=============
;/decompfile
;=============

;=============
;getnextcluser
;Lecture du prochain cluster dans AX
;Entrée :
;BX = buffer source 512 octets
;AX = numéro du cluster courant (0..2879)
;Sortie:
;AX = numéro du cluster suivant
;REMARQUE : La formule pour connaître le secteur correspondant à un cluster :
;numsecteur = 33 + numcluster - 2
;33 = n° du premier secteur dans une FAT12
;2 = le nombre d'élément de 12 bits utilisés pour distingué une FAT2
;La table FAT12 commence par : F0F FFF
;=============
getnextcluster:
	push bx
	push bx
	
	add ax, 1
	
	mov bx, 12
	mul bx
	mov bx, 8
	div bx
	
	pop bx
	add bx, ax
	
	cmp dx, 4
	je .R4
	
.R0:
	sub dx, 2
	mov ax, word [bx]
	sar ax, 4
	and ax, 0000111111111111b
	jmp .endr
	
.R4:
	sub bx, 1
	mov ax, word [bx]
	and ax, 0000111111111111b
	
.endr:
	pop bx
	
	ret
;=============
;/getnextcluster
;=============
setup.asm
Code:
[BITS 16]

%include "a20.asm"

msg_loadk	db	'Launching Kernel ...',10,13,0
errproc	db	'386+ Require !',10,13,0

_start:
	cli
	mov    AX,9000h
	mov    SS,AX
	mov    SP,0h
	sti

	mov ax, cs
	mov es, ax
	mov ds, ax
	
	mov si, msg_loadk
	call print
	
	call detect_cpu	;On vérifie le processeur
	call A20Active	;On active la porte A20

;===============
;Print
;===============
print:	;Fonction permettant l'affichage de message à l'écran
	lodsb	;en utilisant l'interruption 10h
	
	or al, al	;Si al = 0
	jz done	;Done
	
	mov ah, 0Eh
	mov bx, 0007
	int 0x10
	
	jmp print
done:
	ret
;===============
;/Printf
;===============

;===============
;CPU Detect
;===============
detect_cpu:	;On verifie que le processeur est un 386+
	;Pour savoir si le processeur est un 386+ les flags 12-15 sont définits
	push si
	pushf	;On sauvegarde la valeur d'origine des flags
	xor ah, ah	;ah = 0
	push ax
	popf
	
	pushf
	pop ax
	
	and ah, 0x0f	;vérification des bits 12-15
	cmp ah, 0x0f
	je no386	;-> Processeur = 8088/8086
	;286 ? (bits 12-15 vide)
	mov ah, 0x0f
	push ax
	popf
	
	pushf
	pop ax
	and ah, 0x0f
	jz no386	;-> Processeur = 80286
	
	popf
	pop si
	ret	;-> Processeur != 8088/8086 ou 286
no386:
	mov si, errproc
	call print
	jmp reboot	;Reboot !
;===============
;/CPU Detect
;===============
a20.asm
Code:
;----------------------------------------------
; Procédures pour l'activation de la porte A20
;----------------------------------------------
A20Active:
	push ax
	mov ah, 0dfh
	call GateA20
	or al, al
	jz A20Active_ok
	stc
	
A20Active_ok:
	pop ax
	ret
	
GateA20:
	pushf
	cli
	call Empty8042
	jnz GateA20_fail
	out 0edh, ax
	mov al, 0D1h
	out 64h, al
	call Empty8042
	jnz GateA20_fail
	mov al, ah
	out 60h, al
	call Empty8042
	push cx
	mov cx, 14h
	
GateA20_loop:
	out 0edh, ax
	loop GateA20_loop
	pop cx
	
GateA20_fail:
	popf
	ret
	
Empty8042:
	push cx
	xor cx, cx
	
Empty8042_try:
	out 0edh, ax
	in al, 64h
	and al, 2
	loopnz Empty8042_try
	pop cx
	ret
J'éditerai prochainement ce poste pour donner des liens expliquant comment une machine démarre et dans quel état elle se trouve au moment de son démarrage.
 

Arnpsyke

Charlatan
bonne chance à toi !
 

Froggy

fake geek
oulaaaaaaaaaaa très très gros projet dans lequel tu te lance ... :)

j'ai déjà une petite question : comment vas-tu faire pour que ce soit ton OS qui soit charger et pas un autre ? Et pour l'installer ? =]

je te conseil déjà de mettre un caractère style '$' à la fin de toute tes "Strings", il est plus facile de l'afficher ensuite ;)
 
B

belzebuth_666

ex membre
je ni connais pas grand chose en programmation (enfaite je ni connai rien ^^)

mais je te souhaite bonne chance quand meme ;)
 
1er
OP
neku

neku

Codeur roumain
Pour que ce soit le mien et pas un autre qui soit chargé, c'est le secteur de démarrage qui s'en charge.
Et plutard j'intégrerai un système de multi-boot dans mon secteur de démarrage.
Pour le moment il est sur disquette :p
Donc je sais ou mon kernel ce trouve et donc ou je dois aller le chercher ^
 

k o D

Elite
Je ne serai que trop te conseiller de ne pas le faire en ASM mais bien en C ou autre.

(note c'est la mode de faire son propre OS actuellement ^^)
 
1er
OP
neku

neku

Codeur roumain
Merci du conseil, mais j'avais déjà prévu de faire le noyau en C.
Je ne suis pas maso ^^
Le secteur de boot, lui y a pas le choix il doit être en ASM.
Et non je ne suis pas une mode particulière, ca fait déjà quelques années que j'ai envie.
J'avais déjà fais un secteur de boot mais je l'ai pas retrouvé donc j'en ai fait un nouveau ,)
 

Jereck

Α & Ω
Staff
Comment faire appel à des interruptions si tu n'a pas d'OS sous-jacent ?
 

gl0b

▇ ▅ █ ▅ ▇ ▂ ▃ ▁ ▁ ▅ ▃ ▅ ▅ ▄ ▅ ▇
les IRQ's attribués par le BIOS nah?

gros boulot que de se pondre un OS, t'es courageux :-D
 
1er
OP
neku

neku

Codeur roumain
Lorsque la machine démarre, elle est en mode "réel" (16bit), et toute les intérruptions du BIOS sont accessible.
L'inconvénient du mode réel c'est que l'on à droit que à 1mo de mémoire ... même si on à 2Go :p
Puis une fois le Kernel chargé ont peut passer en mode protégé (32 bit) et là ont peu allouer jusqu'a 4go de mémoire, c'est déjà mieux, mais on perd les interruption :/
Alors la solution est de faire une porte sur la ligne A20.
 

Ahava

Revenant
Hé ben :pfiou:

T'es bien courageux hein, bravo ! Moi jamais je me lancerai dans une telle aventure, y en a déja assez qui s'arrachent les cheveux là dessus pour que je garde les miens :D

Puis entre Win, Mac OS X, et toutes les distributions de Linux y a de quoi faire déjà.

Enfin, bravo et bonne continuation :D
 
J

jb_jb

ex membre
C'est une belle initiative.

Je pense que pour mettre un prgramme sous licence GPL, tu dois mettre ceci en entête :

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Voilà, sinon si ton programme fait plusieurs fichiers, c'est encore autre chose, tu auras plus d'info au lien suivant GNU GPL

Sur ce bonne chance.

PS: Tu veux utiliser du FAT12 ???
 

ImMorT4L

Touriste
OMG, ste truc de fou... :-D Dis moi pas que t'es de la famille à Linus twa ??? Ou à Bill peut être ??? :D

Juste comme ça, tu vas le baptiser comment ton OS ??? nekux, ça le fait :cool:
 

null

ose();
Hé bin :gne: Je m'étais posé la même question que Jereck mais tu as l'air d'être vachement doué donc je te souhaite de réussir.

N'hésite vraiment pas à poster les avancées car je vais suivre ton projet avec grand intérêt !

Bonne chance
 
1er
OP
neku

neku

Codeur roumain
Pour le moment oui, j'ai juste fais un Driver FAT12, qui est le système de fichier utilisé sur une disquette (généralement).
Plutard dans le développement je mettrai au point un Driver pour la FAT 16 et 32
Je dois mettre à jour dans mon premier post le secteur de démarrage que j'ai terminé, la j'ai commencé à coder le noyau en C
 

Froggy

fake geek
quoi ? tu va même pas mettre au point ton propre FS ? :-9

quelle honte :mrgreen:

en tout cas on risque tous de beaucoup apprendre en regardant régulièrement ici ;)

merci ! :)
 
1er
OP
neku

neku

Codeur roumain
Faire mon propre système de fichier : c'est une idée qui m'est passée par la tête mais je ne le fais pas pour pouvoir échanger par après facilement des fichiers avec windows et linux.
Car on but (si j'y arrive) serais de faire un OS hybride entre windows et linux donc pouvans exécuter les applications des deux ;)
C'est pourquoi j'ai choisi la FAT32 malgré c'est limitation :
- Partition max 32Go
- Fichier le plus grand 3,99Go
 

jeff69

Elite
Pour le noyau tu vas partir de 0 ou modifier quelque chose de déjà existant ?

Et bon courage pour ton os tu en auras grandement besoin :p
 
1er
OP
neku

neku

Codeur roumain
Pour le noyau, je partirai de rien.
C'est plus glorifiant :D

(J'ai mis à jour les fichiers du premier post)
 
Statut
N'est pas ouverte pour d'autres réponses.
Haut