Some strange problem (16 bit)

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
j.vimal_

Some strange problem (16 bit)

Post by j.vimal_ »

Hi
As an improvement of my previous project, I wanted to make a full fledged kernel loader, that would present a prompt (Linux like :)) in the beginning and allow me to browse through a FAT32 file system, and tell it what to load.

For that, I wrote a decent MBR, with all details pertaining to a FAT file system embedded on it, like the Bios parameter block etc, that corresponds to a 124 MB USB disk. (Stole it from my previous MBR :))

Secondly, I put my program at sector 12, (zero based index), just after some wierd info ...
My program is 2 KB long.
The MBR would load this sector 12 at 0x0:7E00 (just below the MBR) and jump to it.
Everything goes fine till this point.

The program also loads successfully. While executing, I just wanted to load 512 bytes of the FAT into the memory.
(see code).
It too loads successfully.
I type 'd' at the prompt (just one command that I have added) to dump the FAT on to the screen. I should be getting values ... I got some. Fine till now...
The problem is:

the next time I press 'd', it dumps some values and gets stuck.

I think this is some stack related problem. or, it doesnt return to the executing code properly. Could you please check it for me?

Thanks
Vimal
j.vimal_

Re:Some strange problem (16 bit)

Post by j.vimal_ »

Code: Select all

[ORG 0x7E00]
[BITS 16]

start:

   mov si,msg1
   call printf
   
   ;*************************************
   ;Now copy the FAT variables, important
   ;*************************************
   cld          ;Clear Direction flags
   xor ax,ax ;Copy FAT Variables
   mov ds,ax
   mov es,ax
   mov si,0x7C00
   mov di,fat_var
   ;Copy DS:SI to ES:DI
   mov cx,0x5A         ;Counter. 90 bytes
   rep movsb
   ;*************************************
   
   mov si,msg_done
   call printf
   
      
   ;Debug Now display OEMID for testing purposes
   mov si,OEMID
   call printf
      
   call load_fat         ;Loads the FAT into memory
   
   mov si,msg_disp_hello
   call printf
   
   call _terminal_loop ;The main loop function
   
   hlt   ;Stop
   
;****************************************
;_terminal_loop
;****************************************
_terminal_loop:
   
__loop:
   mov si,prompt
   call printf
   mov si,msg_buffer
   mov byte [ds:si],0   ;Flush out the previous input
   call gets            ;gets a string into the buffer 
   
   mov si,msg_buffer
   cmp byte [ds:si],'d'
   je dump
   jmp __loop
   
   ret
;****************************************
;dump function
;****************************************
dump:
   ;Dumps the FAT Cache
   call endl
   mov si,FS_Type
   call printf
   ret
   ;mov cx,[Size_Of_FAT_Cache]
   ;mov si,FAT_Cache
;_dump_loop:
   ;mov al,byte [ds:si]
   ;mov ah,0x0e
   ;int 0x10
   ;inc si
   ;dec cx
   ;or cx,cx
   ;jz dump_end
   ;jmp _dump_loop
   ;call printf
   
dump_end:
   ret
   
Contd...
j.vimal_

Re:Some strange problem (16 bit)

Post by j.vimal_ »

Code: Select all

;****************************************
;endl function
;****************************************
endl:
   mov al,0x0d
   call putch
   mov al,0x0a
   call putch
   ret
   
;****************************************
;gets function
;****************************************
gets:
   call getch
   cmp al,0x0d      ;enter?
   je gets_end
   mov [ds:si],al
   inc si
   jmp gets
gets_end:
   ret
   
;****************************************
;getch function
;****************************************   
getch:
   mov ah,0
   int 0x16
   call putch
   ret
   
;****************************************
;putch
;****************************************
putch:
   mov ah,0x0e
   int 0x10

   ret

;****************************************
;Cache_FAT
;Caches the FAT, given the cluster number
;****************************************
Function_Cache_FAT:
   ;The FileEntry has a cluster.
   ;Cluster starts at Sector    
;****************************************
;load_fat function.
;****************************************

load_fat:
   ;pushad
   ;First, we get the sector in which
   ;the FAT resides, then, tell int 0x13 to load it
   mov si,load_fat_msg1
   call printf
   
   cld
   mov ah,0x02
   mov al,0x01            ;No. of sectors
   mov cx,[No_Of_Boot_Sectors] ;Starting sector
   inc cx   ;Since the above is the relative sector number
   mov dh,0
   mov dl,[BIOS_Drive_Number]
   mov bx,FAT_Cache
   int 0x13
   
   mov si,load_fat_msg2
   call printf
   ;popad

   ret
;****************************************
;Cluster_To_Sector conversion
;call with eax = Cluster number.
;return with eax = Sector number
;Remember: Cluster 1 is the reserved region
;Cluster 2 is the root directory region. So, DATA starts from here
;****************************************
Cluster_To_Sector:
   mul byte [Sectors_Per_Cluster]
   add eax,No_Of_Boot_Sectors
   ret   
;****************************************
;printf function.
;****************************************
printf:
   lodsb
   or al,al
   jz printf_done
   mov ah,0x0e
   int 0x10
   jmp printf
printf_done:
   ret
;****************************************
;----------------------------------------
;Data part below
msg_disp_hello:
   db 0x0d,0x0a,'Welcome to the Kernel Loader. ',0x0d,0x0a
   db 'Supports loading from FAT32 file system',0x0d,0x0a,0
   
msg1:
   db 'Loading ...',0
msg2:
   db 'Complete.',0
msg_done: 
db 'Done copying values ... ',0
load_fat_msg1: db 0x0d,0x0a,'Loading 2 sectors of FAT ... ',0
load_fat_msg2: db 'Done!',0x0d,0x0a,0

fat_var:
   Jump_Code TIMES 3 db 0
   OEMID      TIMES 8 db 0
   Bytes_Per_Sector         dw 0
   Sectors_Per_Cluster         db 0
   No_Of_Boot_Sectors   dw 0 ;AKA No_Of_Reserved_Sectors
   No_Of_FATs dw 0
   No_Of_Root_Dir_Entries db 0
   Total_Sectors_16  dw 0
   Media_ID db 0
   No_Of_Sectors_Per_FAT dw 0
   No_Of_Sectors_Per_Track dw 0
   No_Of_Heads   dw 0
   No_Of_Hidden_Sectors dd 0
   Total_Sectors_32 dd 0
fat32_BPB: ;Bios Parameter Block
   No_Of_Sectors_Per_FAT32 dd 0
   Extension_Flags dw 0
   FS_Version dw 0 ;FS = FileSystem
   Start_Root_Cluster dd 0
   FS_Info dw 0
   Sector_Backup_Bootsector dw 0
   Reserved TIMES 12 db 0
   BIOS_Drive_Number db 0
   Reserved1 db 0
   Boot_Signature db 0
   Volume_ID dd 0
   Volume_Label TIMES 11 db 0
   FS_Type TIMES 8 db 0
db 0
Directory_Entry: ;DOS Format. 8.3 Names
   Entry_Name TIMES 8 db 0
   Entry_Extension TIMES 3 db 0
   Entry_Attribute db 0
   Entry_Create_Time TIMES 24 db 0
   Entry_Create_Date TIMES 16 db 0
   Entry_Last_Date TIMES 16 db 0
   Entry_Mod_Time TIMES 24 db 0
   Entry_Mod_Date TIMES 16 db 0
   Entry_Start_Cluster dd 0
   Entry_File_Size dd 0 

Directory_Entry_LFN: ;Long File Name format. Really nice hack, still maintains
                               ;compatibility with drivers that read only normal file names
   LFN_Ordinal_Field db 0
   LFN_Name TIMES 5 dw 0
   LFN_Attribute db 0
   LFN_Reserved1 db 0
   LFN_Checksum db 0 ;Simple Checksum algorithm. Calc using the DOS File name
   LFN_Name2 TIMES 6 db 0
   LFN_Cluster dw 0
   LFN_Name3 TIMES 4 db 0

;Checksum:
;Base = array[0]
;i = 1 to n
;Base += Base >> 1 + array[i]

FAT_Value dd 0      ;Each entry is a 32 bit value. 
Size_Of_FAT_Cache dw 0x200
prompt db 0x0d,0x0a,'#:',0

msg_buffer TIMES 255 db 0

;Variables_To_Calculate:
;   Sector_FAT1 dw 0 
   ;DATA Region IMMEDIATELY follows FAT copies

align 4
;*********************************************
FAT_Cache: ;Small cache to speed up operations. Stores 1 sectors of the FAT => .5 KB
   TIMES 512 db 0
;*********************************************

TIMES 2048-($-$$)-5 db 0   
db 'VIMAL' ;Just a small signature :)
JAAman

Re:Some strange problem (16 bit)

Post by JAAman »

mabey i'm missing something, but i cannot find anywhere where you set the stack? you cannot rely on the BIOS stack, as it may be very small (some BIOS may not even use the stack since returning from PMode -- leaving it completely invalid -- or UMode segment -- don't specifically know of any that do this, but it is quite possible)
j.v

Re:Some strange problem (16 bit)

Post by j.v »

Yes, I am setting the stack variables up right in the beginning of the code.

Code: Select all

xor ax,ax
mov ss,ax
mov ds,ax
mov es,ax
I ran it with Bochs, ...
Stopped with this:

eip = 0x7E31
and instruction corresponding to that is:
mov si,prompt in the function _terminal_loop

also, the prompt character '#:' was not displaying, and the program stopped execution. What could this possibly mean?
Rob

Re:Some strange problem (16 bit)

Post by Rob »

In that code you are setting the segment registers, including the stack segment (ss), but not sp (stack pointer)....
j.vimal_

Re:Some strange problem (16 bit)

Post by j.vimal_ »

But, again
I am not accessing the stack at all using 'sp'.
Only through si, di etc... I am using it.
paulbarker

Re:Some strange problem (16 bit)

Post by paulbarker »

You're accessing it thru call and ret instructions.
Vimal

Re:Some strange problem (16 bit)

Post by Vimal »

I got it right. Got some help from another forum too...

See, I had 'jumped' to the dump. So, the next instruction: jmp __loop will NOT be executed. But, it will return and go to the hlt instruction... Thats why.

Now I added this code

Code: Select all

mov si,msg_buffer
   cmp byte [ds:si],'d'
   jne __loop
   call dump
   jmp __loop
   ret
Now its working fine.
Thanks for the time though :)
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:Some strange problem (16 bit)

Post by bubach »

you better set that sp to something anyway, mov sp, 0xffff just to be safe..
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Some strange problem (16 bit)

Post by Solar »

Mmmmmhhh... trial-and-error bugfixing, yummy... 8)

Honest. You're using [tt]call[/tt] and [tt]ret[/tt] without setting up a proper stack, and you are not in a mind to fix it because right now your code works OK?

Uh, oh...
Every good solution is obvious once you've found it.
j.vimal_

Re:Some strange problem (16 bit)

Post by j.vimal_ »

Well, I am setting the sp to be safe :D

No probs... Actually, in the 'bootloader code', i DID have my sp set, to 7Bf4, just below the 7C00. And technically, that should be existent ... till I change it... and it did... :)

Thanks!
Vimal
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Some strange problem (16 bit)

Post by Candy »

Solar wrote: Mmmmmhhh... trial-and-error bugfixing, yummy... 8)
Usually reminds me of what dinosaur poking would be like, and what could have been the reason no human from that age is known ;)

"What if I jam this stick in there?" <prod> <run> <chomp chomp> <burp>
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Re:Some strange problem (16 bit)

Post by df »

dont just set SP to a safe (0xfffe/0xffff) value.. reserve some space for it else before you know it, your SP will be inside some memory your using and corrupt stuff without you knowing whats going on...

random reboots.. yum.
-- Stu --
Post Reply