CD Bootloader

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.
AnonymousUser
Posts: 14
Joined: Wed Jul 23, 2014 5:54 pm
Location: Bermuda Triangle

CD Bootloader

Post by AnonymousUser »

Hi all I have been working on a CD Bootloader that uses El torito format specifications and I just ran into trouble when jumping to the next stage of the bootloader I have no idea why it isn't jumping to the next stage The code looks fine but Obviously I did something wrong because It's not working. Here is the full code just in case but I jump in the READ_STAGE2 function:
EDIT: Updated the code to fix the errors that were pointed out

Code: Select all

[BITS   16]

[ORG  0x0]

start : jmp 0x7c0:main
;
; boot info block
;
times 8-($-$$) db 0
BootInfoPrimVolDescr   resd 1
BootInfoFileLoc           resd 1
BootInfoFileLength      resd  1
BootInfoChecksum       resd 1
BootInfoReserved        resd 40


;Colors for text
%DEFINE TEAL 0x03
%DEFINE RED 0x04
%DEFINE PURPLE 0x05
COL: db 0
ROW:  db 0
LOADSEG equ 0x200 ; ?
LOADOFFS equ 0 ; ?
jumptarget dw LOADOFFS, LOADSEG
;macro for print
%macro Print 2
pusha
	xor ax, ax
	xor dx, dx
	mov dh, BYTE[ROW];puts the row into the dh register
	mov dl, BYTE[COL]
	xor bx, bx
	mov bl, %2
	mov si, %1
	call cPrint
	mov BYTE[COL], dl
 ;saves the rows for the next time we need to print
popa
%endmacro

Print_ln:

pusha   
	mov dh, BYTE[ROW]          
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    inc dh            		;row 00
    mov dl, 0x00            ;col. 00    
	int 0x10
	mov BYTE[ROW], dh
	mov BYTE[COL], 0
	popa


ret

itoa:;number is passed into ax
jmp .beggining
.negate:

neg ax
push ax

mov al, '-'
mov ah, 0xe 
int 0x10
pop ax
jmp .top
.beggining:
xor bx , bx
mov cx, 10;mov into cx 10
cmp ax, 0
jl .negate


.top:
	;divide by 10 and push remainder onto stack 
	xor dx, dx;clear out remainder
	div cx ;divide ax by 10
	push dx;push the remainder onto the stack for later
	inc bx;count the number of digits
	test ax,ax;if ax = 0 then stop
jne .top

.loop:
	pop ax;restore the remainder
	add ax, '0';convert to ASCII
	mov ah, 0xe;print
	int 0x10
	dec bx;get ready for the next digit
	cmp bx, 0;if not zero then jump to .loop	
jne .loop
ret

cPrint:                   ; Routine: output string in SI to screen


 .top:
 	;Paramaters for Input 
    mov ah, 09h             ; Must be 9 to print color
    mov cx, 0x01 			;x position
    lodsb                   ; Get character from string
    test al, al
    je .done                ; If char is zero, end of string
    int 0x10                 ; Otherwise, print it

    mov ah, 0x02			;set cursor position
    mov bh, 0x00			;page
    inc dl 		;column
    int 0x10				;changes the cursor position so the next char can be written at the new location
    jmp .top

 .done:
    ret

;clears the screen and sets the cursor position to the top left 
 clear:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x01            ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10    	;set pos
	mov BYTE[ROW], DH
	mov BYTE[COL],0
ret


Read_Sectors:  
        ;/* Read the sector into memory. */
       
		.ForLoop:
			mov     ah,042h
			xor     al,al
			mov     si, DiskAddressPacket
			mov     dl, [CDDriveNumber]
			int     013h
        jnc    .Success 	; /* read error? */

        Print Read_Sector_Error_MSG, RED
		
		cli
		hlt

.Success:
		Print Progress_MSG , PURPLE
		inc WORD[DiskAddressPacket.SectorsToRead]
		
        loop    .ForLoop
		call Print_ln
ret
CHECK_DESC:
	Print CHECK_DESC_MSG, TEAL
	mov es, WORD[DiskAddressPacket.Segment]
	mov di, WORD[DiskAddressPacket.Offset]
	
	xor bx, bx
	.top:
		mov al, BYTE[ES:DI+BX]
		mov BYTE[VOLUME+BX], al
		
		inc bx
		cmp al, ' '
		je .Done
		jmp .top
	.Done:

	;see if the Volume descriptor contains the Signature
	xor BX, BX; clear out bx
	add BX, 0x01;move into bx the offset
	xor cx, cx;clear out cx
	.toploop:
	xor ax, ax
	mov al, BYTE[VOLUME+BX] 
	cmp al, BYTE[CD_Signature+BX-1]
	je .FOUND_IT; Compare the letters Byte by Byte to see if they are the same
	jmp .Done2
	inc CX;increments if even one letter is wrong
	.FOUND_IT:
	Print Progress_MSG, PURPLE
	inc BX;Increments the offset
	
	jmp .toploop
	
	.Done2:
	cmp CX, 0;if signatures don't match then stop the system and print an error Message
	jne .FAIL
	call Print_ln
	
	Print FOUND_CD, TEAL
	jmp .Done3
	.FAIL:
	Print FILE_NOT_FOUND, RED
	cli
	hlt
	.Done3:
	call Print_ln
ret
READ_STAGE2:
	Print LOADING_STAGE2_MSG, TEAL
	call Print_ln
		
	mov di, [DiskAddressPacket.Offset]
	mov es, [DiskAddressPacket.Segment]

	
    xor BX, BX;clears out bx
	xor si, si ;clears out si
	xor cx, cx
    .top:
		
		
		MOV AL,BYTE[ES:DI+BX] ;moves a byte of a possible start of a file entry
		cmp AL,BYTE[STAGE2];compares it with file I want
		je .Done;if it is then jump out of loop
		INC BX;get ready for next file entry
	jmp .top
	
	.Done:
	Print Found_Possible_FILE, TEAL;prints it found a possible file
	XOR SI, SI;Clear out for use
	;INC BX
	;INC SI
	xor cx, cx;clear out for use as counter
	.top2:;compares strings to see if they are the same
		;xor ax, ax;clears out acx
		
		;prints out a letter to the screen
		MOV AL, BYTE[ES:DI+BX]
		MOV AH, 0xE
		INT 0x010
		;;;;;;;;;;;;;;;;;;
		
		xor ax, ax
		MOV AL, BYTE [ES:DI+BX]
		cmp AL, BYTE[STAGE2+SI]
		
		je .Success
		call Print_ln
		jmp .top
		.Success:
			
			;Print Progress_MSG, PURPLE;progress message
						
			
			INC BX;get ready for next character
			INC SI;get ready for next character	
			INC CX; increment counter 
	cmp CX, WORD[STAGE_2_LEN] 
	jne .top2
	;call clear
	call Print_ln
	Print File_Found, TEAL;prints found file if found
	call Print_ln
	
	Print Reading_Sectors, TEAL;prints reading sector message
	;call clear
	SUB BX, WORD[STAGE_2_LEN];goes back to the start of the file
	ADD DI, BX;adds to the offset
	;moves in the new address ES:DI into the DAP
	MOV WORD[DiskAddressPacket.Segment], ES
	MOV WORD[DiskAddressPacket.Offset], DI
	;LEA EAX, [ES:DI]
	;MOV DWORD[DiskAddressPacket.End],EAX
	;MOV WORD[DiskAddressPacket.SectorsToRead], 4
	;read all sectors
	
	xor cx, cx;clears out cx
	mov cx, 0x01;puts in cx 0x04 for how many sectors to read
	call Read_Sectors;calls the read sectors
	Print READ_SUCCESS, TEAL;if it gets here that means it was successful
	;jump to where the file is located and run it
	
	call Print_ln
	MOV AX, ES
	call itoa
	
	
	mov AL, ':'
	MOV AH, 0xE
	INT 0x010
	
	

	MOV AX, DI
	call itoa
	
	call Print_ln
	;call clear

	mov [jumptarget], WORD 0x000
    mov [jumptarget + 2], WORD 0x200
		
    jmp far [jumptarget]
	
	;xchg bx, bx
	;jmp 000h:0000D800h
	
	
	.FAIL:;it failed so print that the file wasn't found and halt the system
	;call Print_ln
	Print FILE_NOT_FOUND, RED
	cli
	hlt
	         
ret
main:
	;first stage of bootloader is loaded at the address 0x07c0:0x0FFFF
	;second stage of bootloader is loaded at address 0x9000:0x0FFFF
	cli  
	mov ax, 0x07c0
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    ;Set up Stack
    mov ax, 0x0000
    mov ss, ax
    mov sp, 0xFFFE
	sti
	
	mov     [CDDriveNumber],dl
	call clear


	Print W_MSG, TEAL;prints the loading message in colour
	Print DOTS, PURPLE
	call Print_ln
	call Print_ln
	
	Print BOOT_MSG, TEAL
	call Print_ln
	
	
	Print BootInfoPrimVolDescr_MSG, TEAL
	MOV AX, WORD[BootInfoPrimVolDescr]
	call itoa
	call Print_ln
	
	Print BootInfoFileLoc_MSG, TEAL
	MOV AX,  WORD[BootInfoFileLoc]
	call itoa
	call Print_ln
	
	Print BootInfoFileLength_MSG, TEAL
	MOV AX, WORD[BootInfoFileLength]
	call itoa
	call Print_ln
	
	Print BootInfoChecksum_MSG, TEAL
	MOV AX, WORD[BootInfoChecksum]
	call itoa
	call Print_ln
	
	Print BootInfoReserved_MSG, TEAL
	MOV AX, WORD[BootInfoReserved]
	call itoa
	call Print_ln
	
	call Print_ln


	
	

	;First find the Signature of the CD 
	Print Reading_Sectors, TEAL
	LOAD_SIGNATURE:
	mov cx, 0x04
	call Read_Sectors
	
	Print READ_SUCCESS, TEAL
	call Print_ln
	;load the Volume descriptor to the Volume variable
	call CHECK_DESC
	;Now Load the Root Directory from the Volume Descriptor
	LOAD_ROOT:
		;Print Reading_Sectors, TEAL
		mov es, WORD[DiskAddressPacket.Segment]
		mov di, WORD[DiskAddressPacket.Offset]
		
		XOR BX, BX
		MOV BX, 40 ;move in the offset
		VolumeLabelLoop: 

			MOV CL,[ES:DI+BX]                   ; Grab a letter 
			CMP CL,' '                          ; Is it a space? (Assumes end of string is space, may run out) 
			JE .VolumeLabelDone                 ; Yes, we are done 

			MOV [VOLUME+BX-40],CL 
			INC BX 
			JMP VolumeLabelLoop                 ; Need to compare BX to length of Volume Label on CD (32?) 

			.VolumeLabelDone: 
				Print Reading_Sectors, TEAL
				MOV byte [VOLUME+BX-40],0      ; End the string 

				MOV EAX,[ES:DI+158]                 ; LBA of root directory, where all things start. 
				;MOV [DiskAddressPacket.End],EAX     ; Load packet with new address on CD of the root directory 
				MOV DWORD[DiskAddressPacket.End],EAX     ; Load packet with new address on CD of the root directory 
				xor cx, cx
				mov cx, 0x04
				call Read_Sectors
			                             
				
				Print READ_SUCCESS, TEAL;if the program gets here it means it was a success
				call Print_ln
				
LOAD_STAGE2:
		
	call READ_STAGE2
		
		
		.FAILURE:
		Print FILE_NOT_FOUND, RED
		cli
		hlt
		
		
Sector_Size: 				dw 	  	512						
CDDriveNumber: 				db 	  	0x080
CD_Signature: 			   	db    	"CD001"
CD_FILE_VER:			   	db    	0x01
CD_FileNameLength:			db	  	0x0
CD_dir_curr_size:			db 		0x0
Reading_Sectors: 			db 		"Reading sectors", 0
CHECK_DESC_MSG:				db		"Checking for CD Signature",0
LOADING_STAGE2_MSG:			db		"Loading Stage 2 of boot loader",0
STAGE_2_LEN:				DW 		0xC
File_Found:					db		"File for Stage 2 of the bootloader was found!!",0
LOADING_STAGE2_FAILED:		db  	"Failed to load Stage 2 of the boot loader !!!!!",0
Found_Possible_FILE:		db		"Found Possible File: ",0
Colon: 						db		":",0
FILE_ENTRY:					db 		0
JolietSig       			DB  	25h, 2fh, 45h                               ; this is the value of the escape sequence for a Joliet CD 
BOOT_MSG:					DB 		"Boot Info Table:", 0				
DOTS:						db 		".....",0	
					;Disk Address Packet				
DiskAddressPacket:          db 0x010,0 						  
.SectorsToRead:             dw 1                              ; Number of sectors to read (read size of OS) 
.Offset:                    dw 0                              ; Offset :0000 
.Segment:                   dw 0x0200                         ; Segment 0200
.End:                       dq 0x010                             ; Sector 16 or 10h on CD-ROM 

VOLUME: 					DW 0
BootInfoPrimVolDescr_MSG:	db "Volume Descriptor: ", 0
BootInfoFileLoc_MSG         db "File Location:     ", 0  
BootInfoFileLength_MSG		db "File Length:       ", 0
BootInfoChecksum_MSG       	db "Checksum:          ", 0
BootInfoReserved_MSG        db "Reserved:          ", 0					
W_MSG: 						db "Loading Z-Boot", 0
STAGE2: 					db "STAGE2.BIN;1"
Read_Sector_Error_MSG: 		db "Error, failed to read sector",0
READ_SUCCESS: 				db "Sectors read correctly!",0
Progress_MSG: 				db ".",0
FILE_NOT_FOUND: 			db "Error, file not found!",0
FOUND_CD: 					db "Found the CD Signature!", 0
times 2046 - ($ - $$) 		db 0; padd out the rest of the file to 0							
Stage 2 Code:

Code: Select all

[BITS 16]
[ORG 0x0]

Start:

 jmp  0x9000:main

%DEFINE TEAL 0x03
%DEFINE RED 0x04
%DEFINE PURPLE 0x05
COL: db 0
ROW:  db 0
%macro Print 2
pusha
	xor ax, ax
	xor dx, dx
	mov dh, BYTE[ROW];puts the row into the dh register
	mov dl, BYTE[COL]
	xor bx, bx
	mov bl, %2
	mov si, %1
	call cPrint
	mov BYTE[COL], dl
 ;saves the rows for the next time we need to print
popa
%endmacro

Print_ln:

pusha   
	mov dh, BYTE[ROW]  
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    inc dh            		;row 00
    mov dl, 0x00            ;col. 00    
	int 0x10
	mov BYTE[ROW], dh
	mov BYTE[COL], 0
	popa


ret
itoa:;number is passed into ax
jmp .beggining
.negate:

neg ax
push ax

mov al, '-'
mov ah, 0xe 
int 0x10
pop ax
jmp .top
.beggining:
xor bx , bx
mov cx, 10;mov into cx 10
cmp ax, 0
jl .negate


.top:
	;divide by 10 and push remainder onto stack 
	xor dx, dx;clear out remainder
	div cx ;divide ax by 10
	push dx;push the remainder onto the stack for later
	inc bx;count the number of digits
	test ax,ax;if ax = 0 then stop
jne .top

.loop:
	pop ax;restore the remainder
	add ax, '0';convert to ASCII
	mov ah, 0xe;print
	int 0x10
	dec bx;get ready for the next digit
	cmp bx, 0;if not zero then jump to .loop	
jne .loop
ret

cPrint:                   ; Routine: output string in SI to screen


 .top:
 	;Paramaters for Input 
    mov ah, 09h             ; Must be 9 to print color
    mov cx, 0x01 			;x position
    lodsb                   ; Get character from string
    test al, al
    je .done                ; If char is zero, end of string
    int 0x10                 ; Otherwise, print it

    mov ah, 0x02			;set cursor position
    mov bh, 0x00			;page
    inc dl 		;column
    int 0x10				;changes the cursor position so the next char can be written at the new location
    jmp .top

 .done:
    ret

;clears the screen and sets the cursor position to the top left 
 clear:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x01         ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10                ;set pos
	MOV BYTE[ROW], DH
	MOV BYTE[COL], DL
ret





main:		
;first stage of bootloader is loaded at the address 0x07c0:0x0FFFE
	;second stage of bootloader is loaded at address 0x9000:0x0FFFF
	cli
	mov ax, 0x9000	;adjust the segment registers
	mov ds, ax
	mov gs, ax
	mov fs, ax


Create_Stack:
	xor ax, ax
	mov es, ax
	mov ss, ax
	mov sp ,0x0FFFF
	sti
	
	
	Print LOAD_SUCCESS, TEAL
	call Print_ln



	

LOAD_SUCCESS:	db "YOU FINALLY LOADED STAGE 2!!!!!!!!!!!!!!!!",0


Assembly commands

Code: Select all

nasm Stage1.asm -o Stage1.bin
nasm Stage2.asm -o Stage2.bin
mkisofs command

Code: Select all

mkisofs -b Stage1.bin -no-emul-boot -boot-info-table  -o BootLoader.iso ./
Last edited by AnonymousUser on Fri Aug 01, 2014 3:43 pm, edited 4 times in total.
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: CD Bootloader

Post by SpyderTL »

You should probably use a far jump main to make sure that you are actually in the code segment that you think that you are in.

Have you stepped through this code in a debugger to see where things start going wrong?

Do you need to specify the boot loader memory segment to mkisofs?

Code: Select all

-boot-load-seg segment_address
              Specifies the load segment address of the boot image for no-emu-
              lation "El Torito" CDs.
http://www.linuxcommand.org/man_pages/mkisofs8.html

You may also want to specify a volume name, just to make sure it's not blank or filled with zeros.

Code: Select all

-V volid
              Specifies the volume ID (volume name or  label)  to  be  written
              into  the master block.  There is space on the disc for 32 char-
              acters of information.  This parameter can also be  set  in  the
              file  .mkisofsrc with VOLI=id.  If specified in both places, the
              command line version is used.  Note that if you assign a  volume
              ID,  this  is the name that will be used as the mount point used
              by the Solaris volume management system and  the  name  that  is
              assigned to the disc on a Microsoft Win32 or Apple Mac platform.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
AnonymousUser
Posts: 14
Joined: Wed Jul 23, 2014 5:54 pm
Location: Bermuda Triangle

Re: CD Bootloader

Post by AnonymousUser »

I have The Volume name saved in VOLUME when I load the root directory I changed the name but nothing worked so I just wen't back to the default one which is CDROM I have not really ever used a debugger before but I did get bochs to run Although I don't really know how to use it that well. I tried the far jump but nasm gave me an error saying: binary output format does not support segment base references.Is there anything else you can think of I have been stuck on this for a week and I really have no Idea how to solve this it looks like it should be jumping to the right address.
Thanks in advance, AnonymousUser
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: CD Bootloader

Post by neon »

Hello,

The boot record provided contains an error that can result in farther errors later. The boot record must contain the iso9660 boot information block at the beginning of the boot record; it will be written by the formatting software. For example,

Code: Select all

;  far jump, fix cs
start : jmp 0x7c0:main
;
; boot info block
;
times 8-($-$$) db 0
BootInfoPrimVolDescr   resd 1
BootInfoFileLoc           resd 1
BootInfoFileLength      resd  1
BootInfoChecksum       resd 1
BootInfoReserved        resd 40
;
; rest of boot code
;
times 2048 - ($ - $$)
; no boot signature required
It is highly recommend resolving this first prior to any farther testing and debugging as the provided boot record is currently invalid.

In addition, the declaration of STAGE2 should be the following; note the invisible portion of the file name including a semicolon followed by version number as required by iso9660,

Code: Select all

STAGE2:                db "STAGE2.BIN;1"
Please resolve the above first. If problems persist we can verify the provided file system code.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
AnonymousUser
Posts: 14
Joined: Wed Jul 23, 2014 5:54 pm
Location: Bermuda Triangle

Re: CD Bootloader

Post by AnonymousUser »

Ok I put the Boot info table in and I printed the information provided in the table right at the beginning of my main So I guess that's solved but Still no change in the jump I also changed it to have the ;1 at the end of my stage2 stringto identify it as a file and added a far jump in my stage2 but nothing yet. Also When I assemble the code gives me warnings not sure if I should be concerned about this but it nasm Outputs these warnings :

Code: Select all

Stage1.asm:10: warning: uninitialized space declared in .text section: zeroing
Stage1.asm:11: warning: uninitialized space declared in .text section: zeroing
Stage1.asm:12: warning: uninitialized space declared in .text section: zeroing
Stage1.asm:13: warning: uninitialized space declared in .text section: zeroing
Stage1.asm:14: warning: uninitialized space declared in .text section: zeroing
I have a Screenshot of the output in Virtual box attached Disregard the second one I forgot to move into Ax WORD[variable] earlier.
Attachments
Zeroth9.png
Zeroth9.png (7.5 KiB) Viewed 4538 times
Zeroth8.png
Zeroth8.png (7.42 KiB) Viewed 4538 times
AnonymousUser
Posts: 14
Joined: Wed Jul 23, 2014 5:54 pm
Location: Bermuda Triangle

Re: CD Bootloader

Post by AnonymousUser »

I still haven't been able to figure this out anyone see anything that might help me out???
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: CD Bootloader

Post by neon »

Hello,

We are looking into the problem and will provide our findings a little later. Please note that due to a lack of time and testing third party software it might take a little while. It is also difficult to follow the provided software due to a lack of proper structure. As of current we have confirmed that the software executes garbage code after a certain point of execution and the software does correctly load the root directory into memory.

Some of the comments are incorrect; e.g. the boot record gets loaded to 0x7c0:0 or 0:0x7c00 not 0x7c0:ffff by the BIOS or another boot loader (a process called chain loading.) This is why you should always far jump and fix CS:IP from the start and verify DL if possible since the initial system state can not be trusted.

We do plan to release an article on CD boot records and advanced boot applications a little later. In any case, if farther problems are discovered they will be provided here for review. We do recommend learning how to use the Bochs debugger in the mean time - it is what we primarily use for debugging machine level code when a kernel or boot time debugger is unavailable.

Finally, those warnings can indeed be ignored. It is just saying that those data elements are uninitialized. This is fine since they are initialized during formatting of the disc.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
AnonymousUser
Posts: 14
Joined: Wed Jul 23, 2014 5:54 pm
Location: Bermuda Triangle

Re: CD Bootloader

Post by AnonymousUser »

I have attached the disassembled code for both files if this helps I still need to look at them but I figured I should post it here first
Attachments
Stage2Disasm.asm
(4.4 KiB) Downloaded 24 times
Stage1Disasm.asm
(12.37 KiB) Downloaded 53 times
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: CD Bootloader

Post by neon »

Hello,

There appears to be two big problems with the provided code,

1. The software never updates the LBA of the file when its read from the directory structure. You have the code there but it is commented out. Why?
2. The way the software parses the root directory appears incorrect. You should be doing the following,

Code: Select all

Set ES:DI -> 0x200:0 -> location of the root directory (you already have this.)
Start loop:
   Set CL to [ES:DI+32]. This is the length of the file identifier.
   Compare CL bytes of [ES:DI+33] with your file name.
   If found
      ES:DI points to correct entry. Break;
   Else
      DI = DI + [ES:DI]. This jumps past the current directory
   End if
End loop.
LBA = [ES:DI+2] 
Please reference OSDev.org Wiki Article for the proper format of the directory structure. The current code is difficult to follow as it appears to read character by character; please make sure your software follows the above algorithm and use cmpsb.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
AnonymousUser
Posts: 14
Joined: Wed Jul 23, 2014 5:54 pm
Location: Bermuda Triangle

Re: CD Bootloader

Post by AnonymousUser »

1. The software never updates the LBA of the file when its read from the directory structure. You have the code there but it is commented out. Why?
I have the code there????? If I did I had no Idea sorry if this sounds stupid but could you please point it out? I would really appreciate it.
EDIT: Are you talking about this?

Code: Select all

LEA EAX, [ES:DI]
MOV DWORD[DiskAddressPacket.End],EAX
Because when ever I try this it won't read the sectors, I think its because mkisofs only outputs 4 sectors and even if I try to change the size to 16 it won't read above 4 sectors. Probably because that's the space that both files take up on the disk image
I'm not exactly sure though.What happens is it doesen't go past the read sectors function like it doesent get out of it and then it just executes garbage code.

I realized that I shouldn't be doing this after I find the file

Code: Select all

MOV WORD[DiskAddressPacket.Segment], ES
MOV WORD[DiskAddressPacket.Offset], DI
because that makes the adress ES:DI instead of 0x200:0x000
I should be doing (At least I think I should) the code I posted above but as I mentioned it won't work. I have a screenshot attached if you wan't to see the output
Attachments
Zeroth10.png
Zeroth10.png (7.38 KiB) Viewed 4326 times
AnonymousUser
Posts: 14
Joined: Wed Jul 23, 2014 5:54 pm
Location: Bermuda Triangle

Re: CD Bootloader

Post by AnonymousUser »

Nevermind it works if I do this:

Code: Select all

a32 
LEA EAX, [ES:DI]
MOV DWORD[DiskAddressPacket.End],EAX
a16
But It still won't jump to the file and execute the code
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: CD Bootloader

Post by Combuster »

I had a look at stage one and noticed too many things in the first lines to trust anything

Code: Select all

00000569  31DB              xor bx,bx
0000056B  B304              mov bl,0x4
0000056D  BE2A07            mov si,0x72a
00000570  E896FB            call word 0x109
1: It starts at a random address rather than zero
2: The indirect call uses a garbage stack reference and a garbage data reference.
3: The processor can now be executing anythng
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
AnonymousUser
Posts: 14
Joined: Wed Jul 23, 2014 5:54 pm
Location: Bermuda Triangle

Re: CD Bootloader

Post by AnonymousUser »

That shouldn't be happening since the origin is at 0 so maybe it's my stack alignment that's causing all of these problems, Maybe it's because my Stage2 is at 0 as well I'll try and change the origin to something else and see what happens.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: CD Bootloader

Post by neon »

Hello,

Modify the following code :

Code: Select all

   ;call clear
SUB BX, WORD[STAGE_2_LEN];goes back to the start of the file
ADD DI, BX;adds to the offset

MOV		WORD	[DiskAddressPacket.Offset], DI
MOV		WORD	[DiskAddressPacket.Segment], ES
LEA				EAX, [ES:DI]
MOV		DWORD	[DiskAddressPacket.End],EAX					; LBA
MOV		WORD	[DiskAddressPacket.SectorsToRead], 4
To the following. Note the changes were made around your design and is therefore hackish (to be explained why later.) It locates the correct LBA from the directory structure for the final read :

Code: Select all

;------------------------------------------
; NOTES
;  ES:DI -> 0x2000
;  ES:DI+BX -> 0x209d
; OUTPUT
;  ES:DI -> LBA
;  SEG:OFF remains 0x2000
;------------------------------------------

%define STAGE2_LEN 12				; STAGE2.BIN;1
%define ISO_DIRECTORY_LEN 33		; length of constant part of directory record
%define ISO_DIRECTORY_LBA_OFFSET 2  ; offset of LBA member of structure

	;
	; Set SEG:OFFSET to 0x2000 load address
	;
	mov word [DiskAddressPacket.Offset], 0
	mov word [DiskAddressPacket.Segment], 0x200
	;
	; Adjust BX
	;
	mov di, bx	; save bx and get rid of it. Only want to use ES:DI
	xor bx, bx
	;
	; Adjust ES:DI to point to LBA / Extent member of directory structure
	;
	sub di, STAGE2_LEN
	sub di, ISO_DIRECTORY_LEN
	add di, ISO_DIRECTORY_LBA_OFFSET
	;
	; Now [ES:DI] -> LBA / Extent of directory record in both endian formats; grab little endian format into EAX
	;
	mov eax, [ES:DI]
	;
	; Now EAX = LBA to start loading from. Store it
	;
	mov dword [DiskAddressPacket.End], EAX
	;
	; Should calculate this from extentSize field: sector count = (extentSize / sectorSize) + 1
	;
	mov word [DiskAddressPacket.SectorsToRead], 4
After the above modification the software correctly loads your stage 2 image to 0x200:0.

Although this modification may resolve the problem, we highly recommend a rewrite using proper string instructions and properly using structures and parsing the file system. Please reference our boot record here for an example of good boot record formatting and code structure.

It should be noted that there does appear to be errors within the provided "stage 2" boot loader as well that may prevent it from correctly displaying anything; executing garbage due to the entry point main being incomplete. Please be careful and not to take these errors as being from the boot record ("stage 1"). We have verified the image gets loaded into memory only.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
AnonymousUser
Posts: 14
Joined: Wed Jul 23, 2014 5:54 pm
Location: Bermuda Triangle

Re: CD Bootloader

Post by AnonymousUser »

Ok I did change the code but as you feared nothing printed out
It should be noted that there does appear to be errors within the provided "stage 2" boot loader as well that may prevent it from correctly displaying anything; executing garbage due to the entry point main being incomplete. Please be careful and not to take these errors as being from the boot record ("stage 1"). We have verified the image gets loaded into memory only.

So what exactly is wrong with the entry point???? Is it not executing the far jump correctly?
Post Reply