[Asm] Mon système d'exploitation

Discussion dans 'Web, design' créé par neku, 5 Octobre 2006.

Statut de la discussion:
Fermée.
  1. Offline
    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.
    neku, 5 Octobre 2006
    #1
  2. Offline
    Arnpsyke Charlatan
    bonne chance à toi !
    Arnpsyke, 5 Octobre 2006
    #2
  3. Offline
    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 ;)
    Froggy, 5 Octobre 2006
    #3
  4. Online
    belzebuth_666 ex membre
    je ni connais pas grand chose en programmation (enfaite je ni connai rien :p)

    mais je te souhaite bonne chance quand meme ;)
    belzebuth_666, 5 Octobre 2006
    #4
  5. Offline
    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 ^
    neku, 5 Octobre 2006
    #5
  6. Offline
    k o D Belge !
    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 :p)
    k o D, 5 Octobre 2006
    #6
  7. Offline
    neku Codeur roumain
    Merci du conseil, mais j'avais déjà prévu de faire le noyau en C.
    Je ne suis pas maso :p
    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 ,)
    neku, 5 Octobre 2006
    #7
  8. Offline
    Jereck Procrastinateur
    Equipe GamerZ.be
    Comment faire appel à des interruptions si tu n'a pas d'OS sous-jacent ?
    Jereck, 5 Octobre 2006
    #8
  9. Offline
    gl0b ▇ ▅ █ ▅ ▇ ▂ ▃ ▁ ▁ ▅ ▃ ▅ ▅ ▄ ▅ ▇
    les IRQ's attribués par le BIOS nah?

    gros boulot que de se pondre un OS, t'es courageux :-D
    gl0b, 5 Octobre 2006
    #9
  10. Offline
    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.
    neku, 5 Octobre 2006
    #10
  11. Offline
    Jereck Procrastinateur
    Equipe GamerZ.be
    Ok
    Jereck, 5 Octobre 2006
    #11
  12. Offline
    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
    Ahava, 5 Octobre 2006
    #12
  13. Online
    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 ???
    jb_jb, 5 Octobre 2006
    #13
  14. Offline
    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:
    ImMorT4L, 5 Octobre 2006
    #14
  15. Offline
    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
    null, 5 Octobre 2006
    #15
  16. Offline
    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
    neku, 5 Octobre 2006
    #16
  17. Offline
    Froggy fake geek
    quoi ? tu va même pas mettre au point ton propre FS ? :-9

    quelle honte :D

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

    merci ! :)
    Froggy, 6 Octobre 2006
    #17
  18. Offline
    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
    neku, 6 Octobre 2006
    #18
  19. Offline
    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
    jeff69, 6 Octobre 2006
    #19
  20. Offline
    neku Codeur roumain
    Pour le noyau, je partirai de rien.
    C'est plus glorifiant :D

    (J'ai mis à jour les fichiers du premier post)
    neku, 6 Octobre 2006
    #20
Statut de la discussion:
Fermée.