|
Page 1 of 1
|
[ 5 posts ] |
|
There's something wrong with my boot code
Author |
Message |
prinzrainer
Joined: Sat Sep 26, 2009 4:29 am Posts: 15 Location: Philippines
|
There's something wrong with my boot code
School vacation, a great time to continue my osdev!! So I'll bother you again with questions and bugs =). There's something wrong with int 0x13 fn 42 in my boot code. Loading sectors was fine until loading the cluster chain on fat(see sys_loadclusterchain16). At first, fat[0] or sector 4 is loaded w/o errors, but when it comes the need to load another fat sector (fat[1]) an error occurs. I used bochsdbg in viewing mem & regs during execution. I tried to check the DAP (@0x7c3e) before I loaded fat[1] (sector 5) using int 0x13 and it seemed to be ok. DAP was also pointed correctly by ds:si. But error ocurred ( Error 01..what does it mean? My BIOS Enhanced Disk Drive Specification Version 3.0 Rev 0.8 March 12, 1998... doesn't show me what it is). Never mind the unused functions and tables. I will use it in future development. Also SAJIAXXX.BIN is my second stage bootloader w/c is responsible for searching my OS in any drives installed in your pc. But it is not yet finished. I'll continue making it after this problem solved. Here's my code: Code: bits 16 org 0x7c00 jmp short boot nop SystemVersion db "SAJIA OS" BytesPerSector dw 0x200 SectorsPerCluster db 2 ReservedSector dw 4 FATCount db 2 RootDirCount dw 0x40 SectorCount16 dw 19728 ;19728 19642 for data(9821 cluster) MediaDescriptor db 0xF8 FATsz16 dw 40 ; 10240 clusters SectorsPerTrack dw 63 HeadCount dw 1 HiddenSectorCount dd 0 SectorCount32 dd 0
;FAT16 FAT16_Drive db 0x80 FAT16_FlagNT db 0 FAT16_Signature db 0x29 FAT16_SerialNumber dd 0x01020304 FAT16_VolumeLabel db "NO NAME " FAT16_SystemID db "FAT16 "
;FAT32 FATsz32 equ 0x200+36 FAT32_extflg equ 0x200+40 FAT32_fsver equ 0x200+42 FAT32_rootcluster equ 0x200+44 FAT32_fsinfo equ 0x200+48 FAT32_ReservedSector equ 0x200+50 FAT32_drv equ 0x200+64 FAT32_Signature equ 0x200+66 FAT32_SerialNumber equ 0x200+67 FAT32_VolumeLabel equ 0x200+71 FAT32_SystemID equ 0x200+82 ;DAP dap: db 0x10 db 0 dap_count db 0 db 0 dap_bfr dd 0 dap_lba dq 0 ;PT
;datax datax equ 0x100
;Drive drv equ datax ;byte
;FS param fs_rdirsect equ drv + 1 ;byte
;divx data divx_nbits equ fs_rdirsect+1 ;byte nbits divx_d equ divx_nbits+1 ;dword d divx_t equ divx_d+4 ;dword t divx_i equ divx_t+4 ;byte i
;check_fs data fs_totalsector equ divx_i+1 ;dword fs_datastart equ fs_totalsector+4 ;dword, relative to fs_vrbase fs_fatsize equ fs_datastart+4 ;dword, fs_vrbase equ fs_fatsize+4 ;qword fs_fatentsz equ fs_vrbase+8 ;dword fs_SectorsPerCluster equ fs_fatentsz+4 ;dword fs_dirstart equ fs_SectorsPerCluster+4;dword relative to fs_vrbase fs_bytespersector equ fs_dirstart+4 ;dword fs_rsvdsector equ fs_bytespersector+4 ;dword fs_bpc equ fs_rsvdsector+4 ;dword ;sys_loadclusterchain data lcc_latestsectloaded equ fs_bpc+4 ;dword lcc_entrypersector equ lcc_latestsectloaded+4;dword sectortmp equ 0x200 datax2 equ 0x400 datax3 equ 0x8400
boot: cli xor ax,ax mov ds,ax mov es,ax ;mov ax,0x9FE0 ; mov ss,ax mov sp,0x7c00 ;I'll make sure that stack doesn't meet the cluster chain ;mov sp,0x200 ;stack top @ 0xA0000 mov si,msg_load call sys_print mov [drv],dl call sys_int13ext mov al,3 ; Load 3 sectors mov edi,0x7e00 ; to 0x7e00 mov ebx,0x0001 ; from lba 1 xor edx,edx ; call sys_read mov edi,sectortmp xor ebx,ebx xor edx,edx mov al,1 call sys_read xor eax,eax mov [fs_vrbase],eax mov [fs_vrbase+4],eax call sys_checkfs ;return ax, 1->fat16, 2->fat32 cmp ax,1 je sys_loadfat16root jmp sys_unfs
sys_read: push esi push ecx ;edi - buffer address [segment:offset; 16:16] ;ebx - lower dword lba, al-number of sectors ;edx - upper dword lba, cf - on error mov cx,03 sys_read_retry: mov byte[dap_count],al mov dword[dap_bfr],edi mov dword[dap_lba+4],edx mov dword[dap_lba],ebx mov ah,0x42 pusha ;makes the parameters unhurt mov dl,[drv] mov esi,dap int 0x13 popa jnc sys_read_loadok loop sys_read_retry sys_read_loadok: pop ecx pop esi ret
sys_int13ext: ; check if int 0x13 ext is present mov ah,0x41 mov bx,0x55aa int 0x13 jnc int13extok mov si,msg_noint13ext call sys_print jmp $ int13extok: ret
divx: ; memory efficient than a macro (btw how can I make a macro on nasm?)
; eax-dividend ; ebx-divisor ; eax-qoutient ; edx-remainder xor edx,edx cmp ebx,0 je divxz cmp eax,0 je divxz div ebx ret divxz: xor edx,edx xor eax,eax ret
sys_findstr: ;0:si - data start search offset address ;0:di - data to be searched offset address ;cx - length of data to be searched ;bx - data limit (bx+si) size ; found cl=1 push bp push ax add bx,si mov bp,di mov ax,cx cmpnext: push ax mov al,[si] cmp al,[bp] pop ax je nextchar inc si mov ax,cx mov bp,di cmp si,bx jb cmpnext jmp strnotfound nextchar: inc si inc bp dec ax cmp ax,0 je strfound jmp cmpnext strnotfound: xor cx,cx jmp strxt strfound: sub si,cx mov cl,1 strxt: pop ax pop bp ret
sys_print: ;si - msg address pusha cld mov ah, 0x0e ; int 0x10 teletype function sys_printx: lodsb ; Get char from string cmp al, 0 je sys_printxt ; If char is zero, end of string int 0x10 ; Otherwise, print it jmp short sys_printx sys_printxt: popa ret
sys_printint: ;eax-int to print push cx mov cl,32 prntint_cnv: push eax sub cl,4 shr eax,cl and al,0xF cmp al,9 ja prntintx1 add al,0x30 jmp prntintx2 prntintx1: add al,0x37 prntintx2: mov ah,0x0e int 0x10 cmp cl,0 pop eax jne prntint_cnv mov ax,0x0e20 int 0x10 pop cx ret
sys_unfs: mov si,msg_unfs call sys_print trap:;0x7d7c mov si,msg_trap call sys_print jmp $ ;7d85 msg_load db "...",0x0a,0x0d,0 msg_trap db "X",0 msg_noint13ext db "Ur systm s 2 old",0 msg_unfs db "Unsupported FS!",0x0a,0x0d,0 msg_liner db 0x0a,0x0d,0
times 446-($-$$) db 0 ; ;PTentry partbase: db 0x80 ; active marker db 0 ;start C db 0 ;H db 0 ;S db 0 ;part type db 0 ;end C db 0 ;H db 0 ;S dd 0x00000000 ; Start lba dd 0x00000000 ; size ;---------------------------- db 0x80 ; active marker db 0 ;start C db 0 ;H db 0 ;S db 0 ;part type db 0 ;end C db 0 ;H db 0 ;S dd 0x00000000 ; Start lba dd 0x00000000 ; size ;----------------------------- db 0x80 ; active marker db 0 ;start C db 0 ;H db 0 ;S db 0 ;part type db 0 ;end C db 0 ;H db 0 ;S dd 0x00000000 ; Start lba dd 0x00000000 ; size ;-------------------------------- db 0x80 ; active marker db 0 ;start C db 0 ;H db 0 ;S db 0 ;part type db 0 ;end C db 0 ;H db 0 ;S dd 0x00000000 ; Start lba dd 0x00000000 ; size dw 0xAA55 ;boot signature sys_loadfat16root: xor edx,edx mov eax,[fs_datastart] ;load (fs_datastart-fs_dirstart) sectors sub eax,[fs_dirstart] ;from mov ebx,[fs_dirstart] ;LBA fs_dirstart+fs_vrbase add ebx,[fs_vrbase] ; adc edx,[fs_vrbase+4] ; mov edi,datax3 ;to memory 0x8400 ;edi - buffer address [segment:offset; 16:16] ;ebx - lower dword lba, al-number of sectors,edx - upper dword lba, cf - on error call sys_read jmp FindSaiOnRoot16 commonret: jmp $ ;until here for now call sys_eA20 lgdt [GDTr]
mov eax,cr0 or eax,1 mov cr0,eax mov ax,0x10 mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ss,ax
mov esp,0xFFFF jmp 0x8:0x8400 ;[(index(13-bit),TI,RPL(2-bit)]:offset
sys_loadclusterchain16: ;eax-relative cluster offset pusha xor edi,edi mov esi,datax2 and eax,0xFFFF mov [esi],ax lcc_getnextcluster: mov ebx,[lcc_entrypersector] call divx mov ecx,eax mov edi,edx shl edi,1 add ecx,[fs_rsvdsector] cmp ecx,[lcc_latestsectloaded] je lcc_loadskip mov [lcc_latestsectloaded],ecx mov eax,1 ;number of sector to load xor edx,edx ;LBA = fatsector+fatstart+vrbase mov ebx,ecx ; add ebx,[fs_vrbase] ; adc edx,[fs_vrbase+4] ; ;; cmp bx,5 ; I also tried this one ;; je xzxc ; ---------->> push edi ;to memory mov edi,sectortmp ;sectortmp=0x200 ;edi - buffer address [segment:offset; 16:16]; ebx - lower dword lba, al-number of sectors,edx - upper dword lba, cf - on error call sys_read pop edi lcc_loadskip: add esi,2
cmp word[sectortmp+di],0xFFFF je lcc_endofchain cmp word[sectortmp+di],0 je lcc_endofchain cmp word[sectortmp],0 mov ax,[sectortmp+di] mov [esi],ax and eax,0xFFFF jmp lcc_getnextcluster lcc_endofchain: jmp $ ;until here for now mov edi,datax2 mov ecx,esi xor esi,esi mov ebp,datax3 loadchain: push edi xor edx,edx ;LBA = (relative_sector-2)*spc movzx ebx,word[edi] ; sub ebx,2 mov eax,ebx mov ebx,[fs_SectorsPerCluster] mul bx mov ebx,eax add ebx,[fs_datastart] ;LBA+=data_start+vrbase add ebx,[fs_vrbase] ; adc edx,[fs_vrbase+4] ;to memory mov eax,[fs_SectorsPerCluster] ;number of sector to load push ebp mov di,bp ; and di,0xF ; (ebp>>4):bp&0xF shl ebp,12 ; xor bp,bp ; or edi,ebp pop ebp push ecx ;edi - buffer address [segment:offset; 16:16]; ebx - lower dword lba, al-number of sectors,edx - upper dword lba, cf - on error call sys_read pop ecx pop edi add ebp,[fs_bpc] add edi,2 cmp edi,ecx jbe loadchain popa ret ;; xzxc: ;<<----------------- ;; ;The I tried to use interupt ;; mov ax,0x0eeb ;@ 0x7ee6 ;; int 0x10 ;; ;Yeah it returned!! ;; ;But nothing happened...it is supposed to display tadpole like character. ;; ;I thought that I smashed the data area for BIOS..but according to ;; ;the memory map I had, addresses 0x100 to 0xA0000 is a free memory to use, ;; ;Isn't it?? I'm realy confused now...... TT ;; jmp $
sys_checkfs: ;check fs type of a bootsector loaded at "sectortmp" ;return ax, 1->fat16, 2->fat32 push ebx push ecx push edx ;check rsvd sector size cmp word[ReservedSector-0x7a00],0 je rsvdsctr32 movzx edx,word[ReservedSector-0x7a00] mov [fs_rsvdsector],edx jmp rsvdsctrx rsvdsctr32: mov edx,[FAT32_ReservedSector] mov [fs_rsvdsector],edx rsvdsctrx: ;check sector count cmp word[SectorCount16-0x7a00],0 ; jne sectsz16 mov edx,[SectorCount32-0x7a00] ; mov dword[fs_totalsector],edx jmp sectszx sectsz16: movzx edx,word[SectorCount16-0x7a00] ; mov dword[fs_totalsector],edx sectszx: cmp word[FATsz16-0x7a00],0 jne FATsz16x mov eax,dword[FATsz32-0x7a00] mov [fs_fatsize],eax jmp FATszx FATsz16x: movzx eax,word[FATsz16-0x7a00] mov [fs_fatsize],eax FATszx: movzx bx,byte[FATCount-0x7a00] push edx mul bx pop edx ;discard edx in edx:eax push eax movzx eax,word[RootDirCount-0x7a00] ; shl eax,5 movzx ebx,word[BytesPerSector-0x7a00] ; mov [fs_bytespersector],ebx push edx call divx ;eax=((rootdircount*32)/bps)=rootdircount cmp edx,0 ;ceiling je rx1 inc eax rx1: pop edx mov ecx,eax pop eax push edx mov ebx,[fs_rsvdsector] mov [fs_datastart],ebx ; fs_datastart=ReservedSector add [fs_datastart],eax ; fs_datastart+=(fatsz*FATCount) mov edx,[fs_datastart] mov [fs_dirstart],edx add [fs_datastart],ecx ; fs_datastart+=rootdirsectors pop edx sub edx,ebx ; totalsector-=ReservedSector sub edx,eax ; totalsector-=fatsz*FATCount sub edx,ecx ; totalsector-=rootdirsectors mov eax,edx movzx ebx,byte[SectorsPerCluster-0x7a00] mov [fs_SectorsPerCluster],ebx ;eax is NumberOfDataSector call divx ;eax=ebx/eax=NumberOfDataSector/SectorsPerCluster = number of data cluster ;floor cmp eax,4085 jb sys_checkfs_un cmp eax,65525 jb sys_checkfs_fat16 cmp eax,268435445 jb sys_checkfs_fat32 sys_checkfs_un: mov ax,0 jmp sys_checkfsx sys_checkfs_fat16: mov dword[fs_fatentsz],2 mov ax,1 jmp sys_checkfsx sys_checkfs_fat32: mov dword[fs_fatentsz],4 mov ax,2 jmp sys_checkfsx sys_checkfsx: push eax mov eax,[fs_bytespersector] mov ebx,[fs_fatentsz] call divx mov [lcc_entrypersector],eax
mov eax,[fs_bytespersector] mov ebx,[fs_SectorsPerCluster] mul bx mov [fs_bpc],eax pop eax pop edx pop ecx pop ebx ret
FindSaiOnRoot16: mov si,datax3 findrep: mov di,filename mov cx,11 mov bx,0x7BFF call sys_findstr ;0:si - data start search offset address ;0:di - data to be searched offset address ;cx - lenght of data to be searched ;bx - data limit (bx+si) ; found cl=1 cmp cl,0 je FindSaiOnRoot_notfound push esi movzx eax,si xor ebx,ebx mov bl,0x20 ; eax-dividend ; ebx-divisor ; eax-qoutient ; edx-remainder call divx pop esi cmp dl,0 jne findrep add si,0x1a xor eax,eax mov ax,[si] call sys_loadclusterchain16 jmp commonret FindSaiOnRoot_notfound: mov si,nofile call sys_print jmp $
sys_dumpmem: ;si-dumpstart ;cl-dump size in byte*4 pusha xor edx,edx dumpx: push cx mov cx,24 dumpxx: lodsb ; Get char from string shl eax,cl or edx,eax xor eax,eax sub cx,7 loop dumpxx pop cx lodsb or edx,eax mov eax,edx xor edx,edx call sys_printint loop dumpx popa ret
sys_eA20: pusha mov cx,5 ea20_1: ea20_cmdw1: xor ax,ax in al,0x64 bt ax,1 jc ea20_cmdw1 mov al,0x0D0 out 0x64,al ; Wait for the controller to be ready with a byte of data ea20_dw1: xor ax,ax in al,0x64 bt ax,0 jnc ea20_dw1 ; Read the current port status from port 60h xor ax,ax in al,0x60 push ax ;Wait for the controller to be ready for a command ea20_cmdw2: in al,0x64 bt bx,1 jc ea20_cmdw2 ; Tell the controller we want to write the status byte again mov al,0x0D1 out 0x64,al ;Wait for the controller to be ready for the data ea20_cmdw3: xor ax,ax in al, 64h bt ax,1 jc ea20_cmdw3 pop ax ; Turn on the A20 enable bit or al,2 out 0x60,al ;; Wait for the controller to be ready for a command ea20_cmdw4: xor ax,ax in al,0x64 bt bx,1 jc ea20_cmdw4 ; Send the command D0h: read output port. mov al,0x0D0 out 0x64,al ; Wait for the controller to be ready with a byte of data ea20_dw2: xor ax,ax in al,0x64 bt ax,0 jnc ea20_dw2 ; Read the current port status from port 60h xor ax,ax in al,0x60 ; Is A20 enabled? bt ax,1 ; If carry is on, A20 is on. jc ea20_ok loop ea20_1 ;Other method mov cx,5 ea20_2: ; Wait for the keyboard to be ready ea20_cmdw5: xor ax,ax in al,0x64 bt ax, 1 jc ea20_cmdw5
; turn on A20 mov al,0x0DF out 0x64,al ; Wait for the controller to be ready for a command ea20_cmdw6: xor ax,ax in al,0x64 bt ax,1 jc ea20_cmdw6 mov al,0x0D0 out 0x64,al ; Wait for the controller to be ready with a byte of data ea20_dw3: xor ax,ax in al,0x64 bt ax,0 jnc ea20_dw3 ; Read the current port status from port 60h xor ax,ax in al,0x60 ; Is A20 enabled? bt ax, 1 jc ea20_ok loop ea20_2 mov si,noa20 call sys_print jmp $ ea20_ok: sti popa ret
filename db "SAJIAXXXBIN",0 nofile db "Boot file not found. You deleted it!!",0 noa20 db "Unable to enable A20 gate. Booting cannot be continued.",0
GDTr: dw GDTe-GDT-1 ;Limit dd GDT ;Base GDT: dq 0 ;Dummy entry CODESEL: dw 0xFFFF;Lower limit dw 0;Lower base db 0;Mid base db 0x9A;p,dpl(2-bit),s,type(4-bit) db 0xCF;G,D/B,0,avl.Upper limit(4-bit) db 0;Upper base DATASEL: dw 0xFFFF;Lower limit dw 0;Lower base db 0;Mid base db 0x92;p,dpl(2-bit),s,type(4-bit) db 0xCF;G,D/B,0,avl.Upper limit(4-bit) db 0;Upper base GDTe: times 2048 -($-$$) db 0 ;
|
Fri Apr 09, 2010 12:24 am |
|
|
Terry A. Davis
Joined: Tue Jan 19, 2010 11:51 pm Posts: 66
|
Re: There's something wrong with my boot code
Looks like you have a clue, unlike some of the people around here. I picked my company motto, "Happy programmers make us happy," not that my company has anything to do with this. You make me happy. You'll figure-it out. Too much code for me to look at.
|
Fri Apr 09, 2010 2:10 am |
|
|
AndyEsser
Joined: Mon Oct 26, 2009 2:33 pm Posts: 38 Location: United Kingdom
|
Re: There's something wrong with my boot code
@Terry: This website is a learning resource, the point is people come here to learn and help. So you can't expect everyone to suddenly be amazing; as you seem to think you are. On the subject of helping, if you're not going to bother helping the OP, why bother posting?
@prinzrainer: Can you strip out as much of the superfluous code as possible and replicate the problem with a little code as possible, that will help you narrow down exactly where the problem lies and can help us move forward and get it solved.
|
Fri Apr 09, 2010 6:28 am |
|
|
Terry A. Davis
Joined: Tue Jan 19, 2010 11:51 pm Posts: 66
|
Re: There's something wrong with my boot code
@AndyEsser: Some people on this site think they deserve an award for locating where an unwanted infinite loop is happening! Clueless--lazy and no perseverence. I wrote a big comment on perseverence when it comes to hardware code. You have to not be lazy. This guy wrote code to dump blocks. I was impressed. He has lots of diagnostic code. There is hope for him. When you get stuck, try something, no matter how crazy -- you might learn something. You have to not be lazy and willing put-in diagnostics. I'm confident there's hope and he can figure-it out himself. I wrote mine with no forum help.
@prinzrainer: I glanced at your code. I saw you put the stack pointer at 7C00. I don't know what's below that, but I'd be nervous of hitting something the BIOS was using. That might result in a screwy BIOS. Maybe, it's safe, I don't know.
|
Fri Apr 09, 2010 12:10 pm |
|
|
prinzrainer
Joined: Sat Sep 26, 2009 4:29 am Posts: 15 Location: Philippines
|
Re: There's something wrong with my boot code
I already solved it by putting all my data above 0x7c00...thanks anyway
|
Sat Apr 10, 2010 4:23 am |
|
|
|
Page 1 of 1
|
[ 5 posts ] |
|
Who is online |
Users browsing this forum: Google [Bot] and 0 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|