flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
dosin 27 Nov 2010, 20:31
you can start here.. shows code for a read and write.. using buffers .. and has more notes for the code.
http://board.flatassembler.net/topic.php?t=8771 once you read the code into your buffer.. to execute it.. you can do something like this: Code: mov esp, buffer ; or adress of code.. sti cld mov si,sp mov di, 7C00h ; copy buffer to 7c00h mov cx,512/2 rep movsw xor eax,eax xor ebx,ebx jmp farjmp farjmp dw 0x7c00 dw 0x0000 |
|||
![]() |
|
binary 27 Nov 2010, 21:48
If I understood correctly this:
Code: mov cx,512/2 mov edi, 1400000 mov dx,1f0h rep insw should copy the sector to address [1400000] ( I use protected mode addressing ) After that I checked the byte at [1400000] to see if my sector was loaded and it didn't. ( I checked the bytes around it and nothing ) I want to load sector 2 at [1400000] What am I doing wrong |
|||
![]() |
|
dosin 27 Nov 2010, 23:53
Quote: want to load sector 2 at [1400000] did you write something at sector 2??? 1st step with reading the hdd.. is knowing what is on your disk.. sector 0 is the MBR sector 2. well in LBA sectors the disc is layed out like 0,1,2,3,4 ect... on I think all MS fat file system there is nothing in sector 2... its empty... uless you have written something there,, or if you have grub.. I think it uses sector 2.. so depending on what file system you have there may or may not be something there.. empty... you should get a hex editor and look at the hd.. to see whats on it.. but you should keep it simple.. start with sector 0... read it from a floppy test program.. then execute to boot your OS on the HDD.. then learn about the layout of the MBR.. how to decode it.. and find the lba boot address of the portion your os is on.. and then boot it.. next step should be to understand the MBR... and the portions.. the layout.. ect.. and then read sector 0 and dump it to screen and decode it.. or use a hex editor ------------ if you have writen a boot program to sector 2.. you should do the same ... read it 1st.. then dump it to screen as hex.. to and cmp it. make sure what you put there is correct.. double check everything with a program like hex edit.. this one is very good.. http://mh-nexus.de/en/programs.php use with caution,.. you can overwrite stuff with this app.. and with the code your using.. also.. if using your personal computer and not a test one.. all I can say is Back it up.. some people here have found out the hard way,, |
|||
![]() |
|
edfed 28 Nov 2010, 02:45
Quote: also.. if using your personal computer and not a test one.. all I can say is Back it up.. yes! ![]() make backup, or find a way to don't write directlly to disks. for example, you test a first time your lba routine on a virtual machine. and after, you just play with a memory buffer when you do some tests. and ones your memory shows good results, test under virtual machine. and ones it is ok on virtual machine, test on real hardware, but with a lot of care. |
|||
![]() |
|
binary 28 Nov 2010, 13:29
Thank you
I use an emulator ( Bochs ) and from time to time a USB stick (with HDD emulation) to test it on real hardware. I've done all that experimentation with floppy and hdd with int 13h. I don't use MS's file system,and I always use a hex editor for copying the compiled binary file to a hdd image or USB stick. I have a 2 stage boot loader and I'm trying to load the second stage(located after the first stage on drive) using I/O ports instead of int 13h,the problem is that the code that I use for loading doesn't copy my second stage to memory so I'm dumping on screen only zeros. |
|||
![]() |
|
dosin 29 Nov 2010, 16:46
sorry.. but with out seeing all whats going on its hard to give an answer on what is failing..
could be a few things.. you could post an example of the stage 1.. and we can try and help.. |
|||
![]() |
|
binary 29 Nov 2010, 17:16
Code: ORG 0x7c00 ; unreal mode xor ax, ax mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax mov sp, 0x9c00 cli push ds lgdt [TabelGDT] mov eax, cr0 or al,1 mov cr0, eax mov bx, 0x08 mov ds, bx and al,0xFE mov cr0, eax pop ds sti ; ------------------------------------------------------------------------------------ ; set default video mode 80x25: mov ah, 00h mov al, 03h int 10h ; hide blinking text cursor: mov ch, 32 mov ah, 1 int 10h ; Load stage 2 mov dx,1f6h mov al,0a0h out dx,al mov dx,0x1F1 mov al,0h out dx,al ; Number of sectors mov dx,1f2h mov al,1 out dx,al ; loacation mov dx,1f3h mov al,1 out dx,al mov dx,1f4h mov al,0 out dx,al mov dx,1f5h mov al,0 out dx,al ; read mov dx,1f7h mov al,20h out dx,al t: in al,dx test al,8 jz t mov cx,512/2 mov edi, 1400000 mov dx,1f0h rep insw ; check if there is something at 1400000 mov bh,[1400000] cmp bh,0 je nd mov dh, 10 mov dl, 21 mov bh, 0 mov ah, 2 int 10h mov al , "2" mov bl , 00001111b mov AH , 09h mov bh , 0 mov cx , 1 INT 10h nd: cli hlt TabelGDT: dw gdt_end - gdt - 1 dd gdt gdt dd 0,0 flatdesc db 0xff, 0xff, 0, 0, 0, 10010010b, 11001111b, 0 gdt_end: times 510 - ($-$$) db 0 dw 0xAA55 |
|||
![]() |
|
edfed 29 Nov 2010, 20:56
you cannot execute BIOS interrupt when in protected mode.
means that for the moment, you call an unexisting vector because in PM, the IDTR points to a memory zone where is located the IDT, and each entry in the IDT points to a memory where is loaded the routine. that code cannot work at all because you set PM before to initialise it. |
|||
![]() |
|
dosin 30 Nov 2010, 02:27
Do this before entering PMode
Code: ; set default video mode 80x25: mov ah, 00h mov al, 03h int 10h ; hide blinking text cursor: mov ch, 32 mov ah, 1 int 10h once in PM there is no more bios int 10h.. as edfed pointed out.. just a quick way to print text in pm for testing: Code: mov byte [es:0xB809A], "A" ;print a char you will want to write your own text function for PMode same goes for your stage 2.. since your in pm.. bios int 10h text functions will not work in it.. |
|||
![]() |
|
binary 05 Dec 2010, 17:18
The code that I posted above was a Flat real mode loader and int 10 and 13 worked , but anyway , now I have a P mode loader , did some research and some of experimentation and the second sector seems to be loaded but when I try to execute it with:
mov eax,500000 jmp eax or jmp 500000 or jmp far dword [500000] or jmp far pword [500000] the CPU resets - everything else works as it should , I checked everything separately. here's the loader: Code: org 7C00h ; A20 in al, 092h or al, 2 out 080h, al out 092h, al ; video mode 80x25: mov ah, 00h mov al, 03h int 10h ; Hide blinking mov ch, 32 mov ah, 1 int 10h ; --------------------------------- enter 32 biti mode -------------------------------------- cli lgdt fword [gdt.size] mov eax,cr0 or al,1 mov cr0,eax jmp gdt.code_descriptor:Mode32 ; -------------------------------------- GDT -------------------------------------------- gdt: dw 0 .size dw gdt_end -gdt - 1 dd gdt .null_descriptor = $ - gdt dq 0 .code_descriptor = $ - gdt dw 0FFFFh dw 0 db 0 db 10011010b db 11001111b db 0 .data_descriptor = $ - gdt dw 0FFFFh dw 0 db 0 db 10010010b db 11001111b db 0 gdt_end: ; -------------------------------------- GDT -------------------------------------------- use32 Mode32: mov ax,gdt.data_descriptor mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ss,ax mov esp, 90000h ; ------------------------------------------------------------------------------------------- ;Load the 2'nd sector mov dx,1f6h mov al,01000000b out dx,al mov dx,0x1F1 mov al,0h out dx,al mov dx,1f2h mov al,1 out dx,al mov dx,1f3h mov al,1 out dx,al mov dx,1f4h mov al,0 out dx,al mov dx,1f5h mov al,0 out dx,al mov dx,1f7h mov al,20h out dx,al w: in al,dx test al,8 jz w mov cx,512/2 mov edi, 500000 mov dx,1f0h rep insw ; Verify if 2nd sector is loaded mov byte ah,[500012] cmp ah,0x80 jne fd mov byte[0xB8000], "1" mov byte[0xB8001], 00011011b fd: ; ASCII viewer mov ebx,500000 mov edi,0xB8000 l: cmp edi,757664 je ad mov ah,[ebx] mov byte [edi], ah add edi,1 mov byte [edi], 00011011b add edi,1 add ebx,2 jmp l ad: ; jump mov ax,[500000] jmp ax hlt ; ---------------------------------------- variables ----------------------------------------- ; ---------------------------------------- variables ----------------------------------------- times 510-($-$$) db 0 dw 0xAA55 |
|||
![]() |
|
dosin 07 Dec 2010, 06:09
the 1st jmp code is more for a cold boot.. to a MBR to the boot loader..
to execute an app loaded at [500000] you could try this... Code: mov ax,18h mov ds,ax mov es,ax xor eax,eax mov ebx,eax mov ecx,eax mov edx,eax call dword[500000] ;... exit stuff mov ax,18h mov ds,ax mov es,ax xor eax,eax mov ebx,eax mov ecx,eax mov edx,eax |
|||
![]() |
|
egos 10 Dec 2010, 08:35
Quote:
|
|||
![]() |
|
edfed 10 Dec 2010, 09:28
Quote:
it is not the good way. the far pointer is a data, not a direct adress. then, you will need to create this far pointer somewhere in bootloader as said egos. Code: jmp pword[stratptr] ... stratptr dp CODE_SEL:500000 indead, it is interresting to see that it doesn't work the easy way with jmp 500000. are you sure you load it in DS=CS? indeed, good job, it is a good start to overcome the int13h ![]() but it will be a problem if you want to try with other mediums than HDD. |
|||
![]() |
|
binary 10 Dec 2010, 20:13
@dosin
I tried that and it triple faults for some reason @ egos and edfed I tried that and it seams to work (at least it doesn't triple fault). In stage 2 I have a code to print a character on screen but it doesn't print it. I also tried some combinations with dosin's code and it still doesn't work Second stage: Code: mov byte[0xB8004], "2" mov byte[0xB8005], 00011011b hlt Quote:
Before the jmp DS an CS are not egual CS = 8 DS = 16 |
|||
![]() |
|
edfed 10 Dec 2010, 22:54
sorry, i wanted to say
[GDT.base+CS] = [GDT.base+DS] |
|||
![]() |
|
binary 17 Dec 2010, 23:25
It works now
Here's an example code that loads a sector within protected mode , jumps to it and writes to HDD: Code: ; -- ----------------------------------------------------------------------------------------- ; ----------------------------- Bootloader ( first sector ) --------------------------------- ; ------------------------------------------------------------------------------------------- org 7C00h ; video mode 80x25: mov ah, 00h mov al, 03h int 10h ; hide blinking mov ch, 32 mov ah, 1 int 10h ; --------------------------------- enter 32 biti mode -------------------------------------- cli lgdt [gdt] mov eax,17 mov cr0,eax jmp CodeDescriptor:Mode32 ; -------------------------------------- GDT -------------------------------------------- gdt_begin: NullDescriptor: dq 0 CodeDescriptor = $ - gdt_begin dw 0FFFFh dw 0 db 0 db 10011010b db 11001111b db 0 DataDescriptor = $ - gdt_begin dw 0FFFFh dw 0 db 0 db 10010010b db 11001111b db 0 gdt_end: gdt: dw gdt_end - gdt_begin - 1 dd gdt_begin ; -------------------------------------- GDT -------------------------------------------- use32 Mode32: mov ax,DataDescriptor mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ss,ax mov esp, 654000 ; ------------------------------------------------------------------------------------------- ; print a character mov byte[0xB8000], "1" mov byte[0xB8001], 00011011b ; load sectors to 2 MB location in RAM using LBA28 mov dx,0x1F1 mov al,0h out dx,al ; sector count mov dx,1f2h mov al,4 ; number of sectors to read out dx,al ; sector location mov dx,1f3h mov al,[rb1] ; 4 8 8 [8] out dx,al mov dx,1f4h mov al,[rb2] ; 4 8 [8] 8 out dx,al mov dx,1f5h ; 4 [8] 8 8 mov al,[rb3] out dx,al mov dx,1f6h mov al,01000000b or al,[rb4] ; [4] 8 8 8 out dx,al ; read/write command mov dx,1f7h mov al,20h ;20h - read 30h - write out dx,al WhaitRead: in al,dx test al,8 jz WhaitRead mov cx,256*4 ; 4 sectors to load mov edi, 2000000 ; location in RAM mov dx,1f0h rep insw ; jump to loaded code jmp CodeDescriptor:2000000 ; sector location rb1 db 1 rb2 db 0 rb3 db 0 rb4 db 0 ; fill witgh zeroes the rest times 510-($-$$) db 0 dw 0xAA55 ; ------------------------------------------------------------------------------------------- ; ----------------------------- Kernel ( second sector ) --------------------------------- ; ------------------------------------------------------------------------------------------- org 0 ; print a character mov byte[0xB8002], "2" mov byte[0xB8003], 00011011b ; print a character mov eax , 2000000 add eax,var mov ah , [eax] mov byte[0xB8004], ah mov byte[0xB8005], 00011011b ; write sectors from 2 MB location in RAM using LBA28 mov dx,0x1F1 mov al,0h out dx,al ; sector count mov dx,1f2h mov al,1 ; number of sectors to write out dx,al ; sector location mov dx,1f3h mov al,2 ; 4 8 8 [8] out dx,al mov dx,1f4h mov al,0 ; 4 8 [8] 8 out dx,al mov dx,1f5h ; 4 [8] 8 8 mov al,0 out dx,al mov dx,1f6h mov al,01000000b or al,0 ; [4] 8 8 8 out dx,al ; read/write command mov dx,1f7h mov al,30h ;20h - read 30h - write out dx,al WhaitWrite: in al,dx test al,8 jz WhaitWrite mov cx,256 mov esi, 2000000 mov dx,1f0h rep outsw hlt var db "3" |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.