FAT12 bootSector

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
spiner900
Member
Member
Posts: 26
Joined: Mon Mar 09, 2009 10:47 am

FAT12 bootSector

Post by spiner900 »

Hey every body, I'M make a FAT12 boot sector but a have not enought space to do every thing i would. When a error is detected, I would print a message like "Press a key to reboot !" and use the INT 0x16 and after reboot the PC. But, presently, I have only one free byte. Then I need you to help me to save space in my code (bootStrap section).

** Sorry for my English **

Code: Select all

;--------------------------------------------------------------------------------------------
;	But	:  	Ce fichier contient un secteur d'amorcage ( Disquette 1.44 )
;		  	qui utilise un système de fichier  FAT12
;			
;
;	Attention : 
;		-Ce secteur d'amorcage est écrit avec la syntaxe de NASM ( version 0.99.06 ).
;		-L'osLoader doit être la première entrée dans le répertoire racine
;--------------------------------------------------------------------------------------------

;[=====================================================================================]
;
;								Directive spécial pour NASM
;
;[=====================================================================================]

; Lorsque l'ordinateur démarre, leprocesseur est en mode réel 16 bits. Alors on indique 
; à NASM que ce programme doit être assemblé en 16 bits. 
[BITS 16]

;	Le secteur d'amorcage est chargé en mémoire par le BIOS ou un Master Boot Record (MBR) 
;	standare à l'adresse physique 0x7C00. Alors, il faut indiquer à NASM que le programme 
;	ce déroule à cette adresse pour qu'il ajuste les offset des instructions et des 
;	données en conséquence. C'est à dire, qu'il va ajoute à l'offset de chaque instructions 
;	ou données la valeur 0x7C00.
[ORG 0x7C00]

start:
;[=====================================================================================]
;
;						L'entête du système de fichier FAT12
;					Cette entête est divisé en plusieurs sections
;	
;		1. Le saut (JMP)
;		2. OEM ID
;		3. Le block de paramètre du BIOS ( BIOS parameter block ( BPB))
;		4. Le block de paramètre du BIOS étendu ( extended BIOS parameter block ( EBPB))
;
;[=====================================================================================]

	;-----------------------------------------------------
	;  				Section 1 :  Le saut (JMP)
	;-----------------------------------------------------
	; Offset 0 - 2
	;
	; Saute par dessus l'entête du système de fichier FAT12
	; pour se rendre directement au code exécutable sans
	; provoquer d'erreur.
	JMP  bootStrapCode		 
	
	;-----------------------------------------------------
	;  				Section 2 : OEM ID
	;-----------------------------------------------------
	; Offset 3 - 10
	; Le nom du système qui à formater le disque
	EOM_Name			DB 'B.O.S OS'

	;-------------------------------------------------------------------------------------
	; 		Section 3 : Le block de paramètre du BIOS ( BIOS parameter block ( BPB))
	;-------------------------------------------------------------------------------------
	; Offset 11 - 12  	
	; Le nombre d'octets par secteur
	;
	; Les valeur autorisé sont 512, 1024, 2048 et 4096
	; Pour un meilleur compatibilité avec de vieu
	; système, utilisé 512
	NB_OCTET_PAR_SECTEUR	DW 512

	; Offset 13       	
	; Le nombre de secteur par clusteur
	;
	; Doit être un multiplie de 2, excepter 0
	; Les valeurs supportées sont : 1, 2, 4, 8, 16, 32, 64, 128
	;
	; Pour le FAT12
	;
	; Drive size  Secs/clusteur  Clusteur size
	;   360 KB        2              1 Ko
	;   720 KB        2              1 Ko
	;   1.2 MB        1           512 octets
	;  1.44 MB        1           512 octets
	;  2.88 MB        2              1 Ko
	;
	; ATTENTION, si BYTE_PER_SECRTOR * SECTOR_PER_CLUSTER (nombre d'octet par cluster) est 
	; plus grand que 32 KB, des erreurs de disque et de logiciel
	; peuvent survenir.
	NB_SECTEUR_PAR_CLUSTEUR	DB 1 

	; Offset 14 - 15
	; Le nombre de secteur réservé dans la section réservé
	; à partir du premier secteur.
	; (incluant le secteur d'amorcage)
	; 
	; Pour FAT12 cette valeur doit toujours être 1.
	;
	NB_SECTEUR_RESERVE	 	DW 1

	; Offset 16
	; Le nombre de FATs sur le disque.
	;
	; Cette valeur est toujours 2 peut 
	; importe le type de FAT pour garder une compatibilité.
	; Cependant, les système Microsoft suporte d'autre valeur.
	NB_FAT		       		DB 2

	; Offset 17 - 18
	; Le nombre maximal de dossier/fichier qui peuvent 
	; être stocker à la racine du volume.
	; Les entrées sont sur 32 octets
	;
	; Cette valeur multiplier par 32 doit être un multiple de BYTE_PER_SECRTOR
	;
	; Pour une plus grande compatibilité, une disquette (FAT12) utilise 224 entrées.
	;
	; Si un nom de dossier/fichier utilise plus de 32 bits, cette entrée
	; utilisera plusieur entrée ce qui diminue le nombre maximal d'entrée disponible.
	;
	; ATTENTION : Sous Windows, une entrée est utilisé pour le nom du volume.
	NB_ENTREE_REPERTOIR_RACINE 	DW 224

	; Offset 19 - 20  	
	; La taille de la disquette en secteur (tous les secteurs)
	;
	NB_TOTAL_SECTEUR16   		DW 2880

	; Offset 21
	; Spécifie le type de volume utilisé.
	;
	; Les valeur autorisé sont : 
	; 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
	; Peut impote la valeur, elle doit se retrouver dans
	; dans l'octet de poid faible de les FAT[0]
	;
	; F0 : 2,88 Mo 3,5  pouces, 2 face, 36 secteurs
	; F0 : 1,44 Mo 3,5  pouces, 2 face, 18 secteurs
	; F9 :  720 Ko 3,5  pouces, 2 face,  9 secteurs
	; F9 :  1,2 Mo 5,25 pouces, 2 face, 15 secteurs
	; FD :  360 Ko 5,25 pouces, 2 face,  9 secteurs
	; FF :  320 Ko 5,25 pouces, 2 face,  8 secteurs
	; FC :  180 Ko 5,25 pouces, 1 face,  9 secteurs
	; FE :  160 Ko 5,25 pouces, 1 face,  8 secteurs
	; F8 : ------- 		Disque dur
	;
	; ATTENTION : Un descripteur de média peut être associé
	;			  à plusieurs média.
	NO_MEDIA			    	DB 0xF0

	; Offset 22 - 23
	; Le nombre de secteur occupé par chaque des FATs sur le volume
	; 
	; Avec cette données, le nombre de FATs (NUMBER_OF_FATs) et le nombre
	; de secteur réservé (RESERVED_SECTORS), on peut calculer où commence le
	; répertoire racine du volume (SECTOR_PER_FAT * NUMBER_OF_FATs + RESERVED_SECTORS).
	;
	; Par la suite, on peut calculer où commence la zone de données du volume
	; avec le nombre d'entrée du répertoire racine (ROOT_ENTRIES_TAB_TAB).
	;
	;	( Q * ( T - R - D + 2A ) )
	; INT	-------------------------------------
	;	( Q * N + ( A * S ) ) + .5
	;
	; INT= nombre entier
	; Q= 1,5 pour des FAT 12 bits et 2,0 pour des FATS 16 bits
	; T=nombre total de secteurs du disque
	; R=nombre de secteurs réservés
	; D=nombre de secteurs du répertoire principal
	; A=nombre de secteurs par cluster
	; N=nombre de FAT
	; S=nombre d'octets par secteur
	NB_SECTEUR_PAR_FAT      	DW 9

	; Offset 24 - 25
	; Le nombre de secteur
	;
	; Fait partie de la géométrie du disque et
	; est utilisé lors avec INT 0x13
	NB_SECTEUR_PAR_CYLINDRE DW  18

	; Offset 26 - 27
	; Le nombre de tête
	;
	; Fait partie de la géométrie du disque et
	; est utilisé lors avec INT 0x13
	NB_TETE     			DW 2

	; Offset 28 - 31
	; Le nombre de secteur sur le disque physique 
	; qui se situe avant ce secteur de d'amorcage ( pour les partitions )
	NB_SECTEUR_CACHE      	DD 0

	; Offset 32 - 35
	; Contient le nombre de secteur du disque/partition (tous les secteurs du disque) s'il 
	; est trop grand pour être stocker dans TOTAL_SECTOR16.
	; Le champ TOTAL_SECTOR16 doit être à 0. Si ce n'est pas le cas, ce champ doit 
	; être à 0.
	NB_TOTAL_SECTEUR32       	DD 0

	;--------------------------------------------------------------------------------------
	; 						Section 4 : Le block de paramètre du BIOS étendu 
	;							( extended BIOS parameter block( EBPB))
	;--------------------------------------------------------------------------------------

	; Offset 36
	; Ce nombre dépend du numéro de lecteur physique du BIOS.
	; 
	; Les lecteurs de disquette sont numéroté à partir de 0x0
	; et les disques dur commence à 0x80.
	;
	; Est normalement définit avant un apeller BIOS INT 13 pour spécifier
	; quel périphérique il faut accèder.
	;
	; La valeur enregistré sur le disque est généralement 0x0 ou 0x80.
	;
	; Cette valeur est importante seulement si
	; le volume est un périphérique d'amorcage.
	PHYSICAL_DRIVE      	DB 0

	; Offset 37
	; Il s'agit d'un autre champ généralement utilisé lors des appels BIOS INT 13.
	; À l'origine, sa valeur indiquait sur quel piste si trouvait l'enregistrement de 
	; démarrage mais, cette valeur n'est plus utilisé comme tel. 
	;
	; Window NT active le premier bit de poid faible pour indiquer que autochk doit 
	; être exécuté sur le volume au prochain démarrage.  
	; Window NT active le deuxième bit de poid faible pour indiquer qu'un examen de 
	; la surface doit être exécuter sur le volume au prochain démarrage.
	;
	; Ce champ peut donc être à 0 au formatage.
	RESERVED        		DB 0

	; Offset 38
	; Ce champ doit contenir 0x28 ou 0x29 pour être reconnu par window NT
	; 0x29 indique que les trois prochian champs sont présent
	SIGNATURE           	DB 0x29

	; Offset 39 - 42
	; Un nombre qui permet de différencier des autres volumes.
	; Généralement la date combiner avec le temps
	NO_SERIE				DD 0

	; Offset 43 - 53
	; Ce champ contient le nom du volume
	;
	; Window ne l'utilise plus. Il place le nom du volume dans une entrée
	; du répertoire racine.
	;
	; Linux lui, semble l'utiliser encore.
	;
	NOM_VOLUME	        	DB 'B.O.S OS   '

	; Offset 54 - 61
	; Ce champ doit contenir soit FAT12 ou FAT16, selon
	; le système de fichier utilisé.
	; Ce champ ne doit pas être utilisé pour déterminer 
	; le système de fichier utilisé.
	TYPE_SYSTEME_FICHIER 	DB 'FAT12   '



;[======================================================================================]
;			Définitions de quelques variables pour le préprocesseur de NASM
;[======================================================================================]

; Adresse où sera sauvegardé le 
; numéro du phériphérique d'amorcage ( 1 Octets )
%define	BOOT_DEVICE_ADR		 	bootStrapCode	

; Adresse où sera sauvegardé les 2 octets de 
; poid faible de l'adresse LBA du premier 
; secteur de la zone de données ( 2 Octets )
%define LBA_FISRT_DATA_SECTEUR_LOW	BOOT_DEVICE_ADR + 1

; Adresse où sera sauvegardé les 2 octets de 
; poid fort de l'adresse LBA du premier 
; secteur de la zone de données ( 2 Octets )
%define LBA_FISRT_DATA_SECTEUR_HIGH   LBA_FISRT_DATA_SECTEUR_LOW + 2	

; Adresse de l'adresse LBA de la premiere FATs
%define FIRST_FATS_ADR_LOW			( LBA_FISRT_DATA_SECTEUR_HIGH + 2 )
%define FIRST_FATS_ADR_HIGH			( FIRST_FATS_ADR_LOW + 2 )

%define OS_LOADER_ADR_PTR       FIRST_FATS_ADR_HIGH + 2

; L'adresse où sera chargé les secteur de la ROOT_DIR_TAB et de la FATs
%define FAT_BUFFER_ADR			(magicWord + 2)


%define OS_LOADER_SEG			0x900

;[======================================================================================]
;
;										Le bootStrap
;
;	Ceci est la zone exécutable du secteur d'amorcage. Elle se divise en plusieurs étapes.
;
;	1. Inisialisation
;
;	
;
;[======================================================================================]
bootStrapCode:
	;[*************************************************************************]
	;				1. Inisialisation et sauvegarde d'information
	;[*************************************************************************]
	CLD						; Désactive le flag de direction
							; Quand ce flag est désactivé, 
							; les opération de chaîne de caractère
							; incrémente (E)SI/(E)DI 
	
	; Inisialisation des segments et de la pile
	CLI									; Désactive les interrupteurs
	
	XOR AX, AX							; AX = 0
	MOV DS, AX							; DS = 0
	MOV ES, AX							; ES = 0
	MOV SS, AX							; SS = 0
	MOV SP, start						; Le pointeur de pile se décrémente durant l'exécution
	
	STI									; Active les interrupteurs
	
	
	; Sauvegarde le numéro de l'unité de stockage sur lequel l'ordinateur à été amorcé et 
	; que le BIOS ou le MBR à mis dans DL.
	MOV BYTE [BOOT_DEVICE_ADR],DL
	
	
	; Réinisialise le controleur de disque
	; 
	; Entrées :
	; 	AH = 00h
	;	DL = drive (Si le bit 7 est activé, les 
	;				disquettes et les disque sont affectés)
	;
	; Sortie :
	; 	AH = status (see #00234) 
	; 	CF clear if successful (returned AH=00h) 
	;	CF set on error 
	INT 0x13							; AX est déjas à 0 et DL contient déjà
										; le numéro du disque à réinisialiser
	JNC step1.5
		MOV SI, szErrorDisk
		CALL bootError
		
	step1.5:
	;*******************************************************************************
	; Copy le nombre total de secteur dans situé dans le champ NB_TOTAL_SECTEUR16
	; dans le champ NB_TOTAL_SECTEUR32 s'il n'est pas à 0
	;*******************************************************************************
	CMP WORD [NB_TOTAL_SECTEUR16], 0				
	JZ .noCopyTotalSector16
		MOV CX, WORD [NB_TOTAL_SECTEUR16]
		MOV WORD [NB_TOTAL_SECTEUR32], CX
	.noCopyTotalSector16:
	
	
	; Affichage du message de chargement
	MOV SI, szLoadingSystem
	CALL printSZ
	


	calcFirstLBAFATs:
	;[**********************************************************************************]
	;					2. Calcule l'adresse de la première FATs
	;
	;	Calcule :
	;		LBA = NB_SECTEUR_RESERVE + NB_SECTEUR_CACHE
	;
	;[**********************************************************************************]
	MOV AX, WORD [NB_SECTEUR_RESERVE]
	ADD AX, WORD [NB_SECTEUR_CACHE]
	ADC DX, WORD [NB_SECTEUR_CACHE + 2]
	; DX:AX -> l'adresse de la première FATs
	MOV WORD [FIRST_FATS_ADR_LOW], AX
	MOV WORD [FIRST_FATS_ADR_HIGH], DX
	
	;[**********************************************************************************]
	;				3. Calculer l'adresse LBA de la du répertoire racine
	;
	;	Calcule :
	;		LBA = NB_SECTEUR_RESERVE + NB_SECTEUR_CACHE + 
	;					(NB_SECTEUR_PAR_FAT * 2 )
	;
	;
	;		
	;[**********************************************************************************] 
	MOV BX, WORD [NB_SECTEUR_PAR_FAT]
	SHL BX, 1
	ADD AX, BX
	ADC DX, 00
	; DX:AX -> l'adresse LBA de la du répertoire racine
	PUSH DX
	PUSH AX
	
	
	;[**********************************************************************************]
	;				4. Lecture du premier secteur du répertoire racine
	;
	;	** DX:AX conteint déjà l'adresse LBA du répertoire racine ( voir étape 2 et 3)
	;
	;[**********************************************************************************]
	MOV BX, FAT_BUFFER_ADR
	MOV CX, 0x0301
	CALL readSector
	
	
	;[**********************************************************************************]
	;		5. Recherche l'osLoader dans la première entrée du répertoire racine
	;
	;
	;		** Chaque entrée est sur 32 octets
	;[**********************************************************************************]
	MOV SI, FAT_BUFFER_ADR
	MOV DI, szOsLoaderName
	MOV CX, 11
	REPZ CMPSB
	JZ osLoaderFound
	
		; L'osLoader est manquant
		MOV SI, szFileMissing
		CALL bootError
		
	osLoaderFound:
	MOV DI, WORD [SI + 15]
	
	;[**********************************************************************************]
	; 					6. Calcule la taile du répertoire racine
	;
	; Calcule :
	;		tailleEnSecteur	=  (NB_ENTREE_REPERTOIR_RACINE * 32 + 
	;								NB_OCTET_PAR_SECTEUR - 1) / NB_OCTET_PAR_SECTEUR
	;
	;[**********************************************************************************]
	XOR DX, DX
	MOV AX, WORD [NB_ENTREE_REPERTOIR_RACINE]
	SHL AX, 5
	MOV BX, WORD [NB_OCTET_PAR_SECTEUR]
	ADD AX, BX
	DEC AX
	DIV BX
	; DX:AX -> taile du répertoire racine
	
	
	
	;[**********************************************************************************]
	;			7. Calculer l'adresse LBS du premier secteur de la zone de donnée
	; Calcule :
	;	LBA	=  tailleRootDirEnSecteur + LBARootDir
	;
	;
	;[**********************************************************************************]
	POP BX
	POP DX
	ADD AX, BX
	ADC DX, 00
	MOV WORD [LBA_FISRT_DATA_SECTEUR_LOW], AX
	MOV WORD [LBA_FISRT_DATA_SECTEUR_HIGH], DX
	
	
	MOV WORD [OS_LOADER_ADR_PTR], 0
	XOR SI, SI
	readFileSector:
	;[**********************************************************************************]
	;						8. Lire un cluster de l'osLoader
	;
	;	DX:AX -> L'adresse LBA du début de la zone de données
	;	DI    -> Le numéro du prochain cluster à lire ( index dans la FATs )
	;
	;[**********************************************************************************]
		PUSH DI										; Le numéro du clusteur courrant ( index dans la FATs )
		PUSH SI										; Le numéro du dernier secteur de la FATs chargé									
		
		XOR DX, DX
		DEC DI
		DEC DI
		XCHG AX, DI
		MUL BYTE [NB_SECTEUR_PAR_CLUSTEUR]
		XCHG AX, DI
		
		MOV AX, WORD [LBA_FISRT_DATA_SECTEUR_LOW]
		MOV DX, WORD [LBA_FISRT_DATA_SECTEUR_HIGH]
		ADD AX, DI
		ADC DX, 00
		MOV CH, 03
		MOV BX, (OS_LOADER_SEG * 0x10)
		ADD BX, WORD [OS_LOADER_ADR_PTR]
		MOV CL, BYTE [NB_SECTEUR_PAR_CLUSTEUR]
		CALL readSector
		
		; Calcule le nombre d'octet lu
		XOR DX, DX
		MUL WORD [NB_OCTET_PAR_SECTEUR]
		MOV WORD [OS_LOADER_ADR_PTR], AX
		
		; Calcule le numéro de cluster maximal
		XOR DX, DX
		POP SI										; Le numéro du dernier secteur de la FATs chargé	
		MOV AX, SI
		MUL WORD [NB_OCTET_PAR_SECTEUR]
		MOV CX, 3
		DIV CX
		
		POP DI										; Le numéro du clusteur courrant ( index dans la FATs )
		CMP DI, AX
		JB .skipReadFATs
			MOV AX, WORD [FIRST_FATS_ADR_LOW]
			ADD AX, SI
			MOV DX, WORD [FIRST_FATS_ADR_HIGH]
			ADC DX, 00
			MOV CX, 0x0303
			MOV BX, FAT_BUFFER_ADR
			CALL readSector
			ADD SI, AX
		.skipReadFATs:	
		
		
		; Calcule l'offset dans la FATs
		MOV AX, DI
		MOV BX, 3
		MUL BX
		SHR AX, 1
		MOV BX, AX
		
		MOV CX, WORD [FAT_BUFFER_ADR + BX]
		
		TEST DI, 1
		JZ .clusterPaire
			SHR CX, 4
		.clusterPaire:
			AND CX, 0xFFF
		
		MOV DI, CX
	CMP DI, 0xFF8
	JB readFileSector
		
	;[**********************************************************************************]
	;						9. Passe le contrôle à l'osLoader
	;
	;[**********************************************************************************]
	MOV DL, BYTE [BOOT_DEVICE_ADR]
	JMP OS_LOADER_SEG:0
	
;[=====================================================================================]
;
;									Les routines
;
;[=====================================================================================]



;****************************************************************
;
; 	Routine printSZ
;
;	BUT : Permet d'afficher à l'écran une chaîne de caractères
;		  qui ce termine par 0.
;
;	Entrée :
;		SI : L'adresse de la chaîne à afiche.
;			 ( Attention :  Modifier à la sortie de la routine )
;
;	Spécification : 
;		- Utilise la fonction 0xE de l'interrupteur 0x10 du BIOS
;		- La chaîne est afficher en blanc sur un fond noir.
;
;****************************************************************
printSZ:
	PUSH AX
	PUSH DX
	
	MOV AH, 0x0E			; Fonction de l'interrupteur

	.print:
		LODSB				; Met [DS:SI] dans AL et incrément SI
	
		OR AL, AL			; Test si AL est égal à 0
		JZ .fin
		INT 0x10
		JMP .print
	.fin:
		POP DX
		POP AX
RET




;****************************************************************
;
; 	Routine bootError
;
;	BUT : 
;
;	Entrée :
;		SI : L'adresse de la chaîne à afiche.
;			 ( Attention :  Modifier à la sortie de la routine )
;
;
;****************************************************************
bootError:
	CALL printSZ
	;MOV SI, szReset
	;CALL printSZ
	;XOR AH, AH
	;INT 0x16
	;MOV WORD [0x472], 1234
	;JMP 0xFFFF0
	JMP $
RET


;****************************************************************
;
; 	Routine readSector
;
;	BUT :  Permet de lire des secteurs d'un disque avec 
;		   une adresse de type LBA
;
;
;	Entrées :
;		AX 		: Les 2 octets de poid faible de l'adresse LBA
;		DX 		: Les 2 octets de poid fort de l'adresse LBA
; 		CL 		: Le nombre de secteur à lire
;		CH		: Le nombre de tentative de lecture
;		ES:BX 	: L'adresse du buffer
;
;	Sortie :
;		AH : Le nombre de secteur lu
;		CF activé si une erreur est survenue 
;
;****************************************************************
readSector:
	PUSH SI
	PUSH DI
	PUSH CX	
	
	;************************************************************************
	; Convertie l'adresse LBA en CHS selon le format que le BIOS 
	; utilise pour les interrupteurs
	;
	;	Formule
	;		Sector   = (LBA/SectorsPerTrack) Remainder value + 1
	; 		Head 	 = (LBA/SectorsPerTrack)/NumHeads (Take Remainder value)
	; 		Cylindre = (LBA/SectorsPerTrack)/NumHeads (Take quotient value)
	;
	; 		CH = Les 8 bits de poid faible du numéro de cylindre
	; 		CL = Le numéro du secteur (bits 0-5)
	;      	 	 Les 2 bits de poid fort du numéro de cylindre (bits 6-7, 
	;			 disque dure seulement)
	; 		DH = Le numéro de tête
	;*************************************************************************

	; Si DX ( retenue ) est plus grand ou égal au nombre de 
	; secteur par cylindre, la division (LBA/SectorsPerTrack) 
	; va provoqué une retenue alors on perdra de l'information.
	CMP DX, WORD [NB_SECTEUR_PAR_CYLINDRE]
	JAE	.error
	
	; Divise DX:AX par [NB_SECTEUR_PAR_CYLINDRE]
	DIV WORD [NB_SECTEUR_PAR_CYLINDRE]
	MOV CL, DL
	INC CL				; Numéro du secteur

	XOR DX, DX
	DIV WORD [NB_TETE]
	
	SHL AH, 6			
	OR  CL, AH
	MOV CH, AL
	
	SHL DX, 8			; Numéro de tête
	
	
	;******************************************************************
	;						Lire des secteurs
	;
	; AH = 02h
	; AL = Le nombre de secteur à lire
	; CH = Les 8 bits de poid faible du numéro de cylindre
	; CL = Le numéro du secteur (bits 0-5)
	;      Les 2 bits de poid fort du numéro de cylindre 
	;		(bits 6-7, disque dure seulement)
	; DH = Le numéro de tête
	; DL = Le numéro du disque (bit 7 activé pour les disque dur)
	; ES:BX -> Le buffer de lecture
	;*******************************************************************
	XOR SI, SI			; Compteur de tentative
	POP AX				; AL -> Le nombre de secteur à lire
						; AH -> Nombre maximum de tentative
	PUSH AX
	SHR AX, 8				
	MOV DI, AX
	POP AX

	.retry:
		MOV AH, 2
		MOV DL, [BOOT_DEVICE_ADR]
		INT 0x13
		JNC .noError
		INC SI
		CMP DI, SI
	JNZ .retry

	.error
		CALL bootError
	.noError
		XOR AH, AH
		POP DI
		POP SI
RET

;[=====================================================================================]
;
;							Les chaines de caractaire
;
;[=====================================================================================]
szLoadingSystem		DB 10,13,"Chargement...",10,13,0
szErrorDisk 		DB "Erreur de disque !",0
szFileMissing 		DB "BOSLDR manquant !",0
szOsLoaderName		DB "BOSLDR     ",0


; Permet de s'assurer que le secteur d'amorcage soit bien de 512 octets
TIMES 510 - ( $ - $$ ) DB 0

magicWord:			DW 0xAA55				; 0x55 puis 0xAA
giszo
Member
Member
Posts: 124
Joined: Tue Nov 06, 2007 2:37 pm
Location: Hungary

Re: FAT12 bootSector

Post by giszo »

There are a few places where you can optimize your code.

For example you can replace the following:

Code: Select all

   PUSH AX
   SHR AX, 8            
   MOV DI, AX
   POP AX
with this:

Code: Select all

   MOV DI, AX
   SHR DI, 8
giszo
spiner900
Member
Member
Posts: 26
Joined: Mon Mar 09, 2009 10:47 am

Re: FAT12 bootSector

Post by spiner900 »

OK giszo thank you but I not save enough space ...
User avatar
imate900
Member
Member
Posts: 80
Joined: Sat Feb 28, 2009 11:43 am

Re: FAT12 bootSector

Post by imate900 »

Many messages there are for debugging. Remove them and the code that prints them.
Current work on a OS: SauOS (project homepage: http://code.google.com/p/sauos/)
Image
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: FAT12 bootSector

Post by 01000101 »

a good way to save a few bytes is to remove unnecessary loading messaging like ". . . " and such as each ASCII character takes a byte. I reviewed the code and I didn't see any big space-saving methods I could think of.
User avatar
b.zaar
Member
Member
Posts: 294
Joined: Wed May 21, 2008 4:33 am
Location: Mars MTC +6:00
Contact:

Re: FAT12 bootSector

Post by b.zaar »

Hi, with only 512 bytes in the boot sector (510 usable) youre gonna have to rip out anything & everything that you dont use to boot.

I had a quick look thru the code and spotted these 2 fixes would save a few bytes but youre gonna have to apply this kinda thinking to the rest of the code to get more memory.
spiner900 wrote:

Code: Select all

;****************************************************************
;
;    Routine printSZ
;
;   BUT : Permet d'afficher à l'écran une chaîne de caractères
;        qui ce termine par 0.
;
;   Entrée :
;      SI : L'adresse de la chaîne à afiche.
;          ( Attention :  Modifier à la sortie de la routine )
;
;   Spécification :
;      - Utilise la fonction 0xE de l'interrupteur 0x10 du BIOS
;      - La chaîne est afficher en blanc sur un fond noir.
;
;****************************************************************
printSZ:
   PUSH AX
   PUSH DX
 
   MOV AH, 0x0E         ; Fonction de l'interrupteur

   .print:
      LODSB            ; Met [DS:SI] dans AL et incrément SI
   
      OR AL, AL         ; Test si AL est égal à 0
      JZ .fin
      INT 0x10
      JMP .print
   .fin:
      POP DX
      POP AX
RET

Youre not using DX here so dont save it and you know AX is changed so dont rely on in before the call. Also you dont set up BX so you might get a random color or page occasionally.

Code: Select all

;****************************************************************
;
;    Routine bootError
;
;   BUT :
;
;   Entrée :
;      SI : L'adresse de la chaîne à afiche.
;          ( Attention :  Modifier à la sortie de la routine )
;
;
;****************************************************************
bootError:
   CALL printSZ
   ;MOV SI, szReset
   ;CALL printSZ
   ;XOR AH, AH
   ;INT 0x16
   ;MOV WORD [0x472], 1234
   ;JMP 0xFFFF0
   JMP $
RET
You dont need a JMP and a RET here

I'm sure theres more like this to optimise but these were small routines that I spotted easily.
"God! Not Unix" - Richard Stallman

Website: venom Dev
OS project: venom OS
Hexadecimal Editor: hexed
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: FAT12 bootSector

Post by Brendan »

Hi,
spiner900 wrote:Hey every body, I'M make a FAT12 boot sector but a have not enought space to do every thing i would. When a error is detected, I would print a message like "Press a key to reboot !" and use the INT 0x16 and after reboot the PC. But, presently, I have only one free byte. Then I need you to help me to save space in my code (bootStrap section).
Shouldn't be too hard to fix...

Code: Select all

	; Offset 14 - 15
	; Le nombre de secteur réservé dans la section réservé
	; à partir du premier secteur.
	; (incluant le secteur d'amorcage)
	; 
	; Pour FAT12 cette valeur doit toujours être 1.
	;
	NB_SECTEUR_RESERVE	 	DW 1
Use "NB_SECTEUR_RESERVE DW (end - start + SECTOR_SIZE - 1) / SECTOR_SIZE" instead.

Then, near the end, use:

Code: Select all

; Permet de s'assurer que le secteur d'amorcage soit bien de 512 octets
TIMES 510 - ( $ - $$ ) DB 0

magicWord:			DW 0xAA55				; 0x55 puis 0xAA

; *** LOTS MORE CODE AND DATA HERE! ****

end:
The only thing your code needs to do in the first 512 bytes is load the rest of the boot loader from the rest of the reserved sectors.

Also, you could also do half of your calculations when the boot sector is being installed on the disk, rather than doing them when the boot sector is being booted. For example, the installation utility calculates parameters for the starting sector and stores the results somewhere in the first 512 bytes, and the boot sector uses these values instead of doing the calculation itself.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Re: FAT12 bootSector

Post by Dex »

You have too many comments, taking up space, take some out :lol:
And please take it as a joke.
spiner900
Member
Member
Posts: 26
Joined: Mon Mar 09, 2009 10:47 am

Re: FAT12 bootSector

Post by spiner900 »

ok evetybody I will look what I could do.
Thanks
Post Reply