OSDev.org https://forum.osdev.org/ |
|
Why isn't VMWare copying the content of my drive to 0x7C00? https://forum.osdev.org/viewtopic.php?f=1&t=42535 |
Page 1 of 1 |
Author: | paikuhan [ Tue Apr 06, 2021 3:44 pm ] |
Post subject: | Why isn't VMWare copying the content of my drive to 0x7C00? |
Hi fellow OSDeverz, I created a simple "Master Boot Record" for my future toy OS. The first sector (MBR) loads perfectly to memory address 0x7C00. At first I didn't know why, but I was finally able to use pointer to other memory addresses by adding these few line at the start of my nasm code: Code: CLI MOV AX,CS ; Copy code segment MOV DS,AX ; Make DS correct MOV ES,AX ; Make ES correct MOV SS,AX ; Make SS correct MOV BP,0x7C00 MOV SP,0x7C00 ; SETUP A STACK STI Note that I don't need them with Bochs Emulator (I'm guessing because it's outdated?), but need them in both VMWare Player and Oracle VirtualBox. Then what I made my MBR do is to load itself at memory address 0x600 and jump to that address + skipping previously executed instructions. Up to this point everything is fine. Now to my issue: The next thing the code is supposed to do is load the partition's first sector to memory address 0x7C00 (where the old copy of the MBR resides) and jump back there but this doesn't happen. the old copy of the MBR is not overwritten and thus VMWare Player is looping between 0x7C00 and 0x600. Here is my full code: Code: ;********************************************************************; ;* START OF CODE *; ;********************************************************************; %define SIZE 512 ; MBR sector size (512 bytes) %define BASE 0x7C00 ; Address at which BIOS will load MBR %define DEST 0x0600 ; Address at which MBR should be copied ;********************************************************************; ;* NASM settings *; ;********************************************************************; [BITS 16] ; Enable 16-bit real mode [ORG BASE] ; Set the base address for MBR ;********************************************************************; ;* Setup segment registers *; ;********************************************************************; CLI MOV AX,CS ; Copy code segment MOV DS,AX ; Make DS correct MOV ES,AX ; Make ES correct MOV SS,AX ; Make SS correct MOV BP,0x7C00 MOV SP,0x7C00 ; SETUP A STACK STI ;IT WAS ORIGINALLY PUBLISHED ON HTTPS://WWW.APRIORIT.COM/ ;********************************************************************; ;* Prepare registers *; ;********************************************************************; MOV BX,Prepare CALL print_string ; function that prints a string whose pointer is loaded in BX XOR AX,AX MOV DS,AX MOV ES,AX MOV SS,AX MOV SP,BASE ;********************************************************************; ;* Copy MBR to DEST and jump there *; ;********************************************************************; MOV BX,Copy CALL print_string ; function that prints a string whose pointer is loaded in BX MOV SI,BASE MOV DI,DEST MOV CX,SIZE CLD REP MOVSB JMP DEST + SKIP ; When you ask to jump somewhere it will jump in absolute address ; For instance JMP 0x05 will jump to memory address 0x05 instead ; of 0x7C05 SKIP: EQU ($ - $$) ; Go here in copied code MOV BX,Loading CALL print_string ; function that prints a string whose pointer is loaded in BX ;Extended Read MOV AH, 0x42 MOV AL, 3 ;MOV DL, MOV BX, 0 MOV DS, BX MOV SI, DAP MOV BX, 0x7C00 INT 0x13 JMP 0x7600 + 0x7C00 DAP: DAP_SIZE: DB 0x10 UNUSED: DB 0x00 SECTOR_COUNT: DW 3 ; int 13 resets this to # of blocks actually read/written SEGMENT_OFFSET: DD 0x7C00 ; memory buffer destination address (0:7c00) LBA: DQ 2048 ; put the lba to read in this spot %include "../../inc/chapter3/print_string.inc.asm" ; print string function is in an external file Prepare: DB "Prepare registers.",10,13,0 Copy: DB "Copy MBR to DEST and jump there.",10,13,0 Loading: DB "Loading the partition bootsector.",10,13,0 TIMES 446-($-$$) DB 0 ;********************************************************************; ;* END OF CODE *; ;********************************************************************; Note that on the Bochs Emulator and on Oracle Virtualbox the old MBR is overwritten and there is no endless loop. What should I do to make VMWare Player copy the partition's first sector to memory 0x7C00. Thanks in advance. |
Author: | nullplan [ Tue Apr 06, 2021 11:55 pm ] |
Post subject: | Re: Why isn't VMWare copying the content of my drive to 0x7C |
paikuhan wrote: I created a simple "Master Boot Record" for my future toy OS. The first sector (MBR) loads perfectly to memory address 0x7C00. At first I didn't know why, but I was finally able to use pointer to other memory addresses by adding these few line at the start of my nasm code: I suggest you replace the second instruction with "xor ax,ax". Reason is that you don't really know the value of CS. You know your code will be loaded to 0x7c00, but not whether it will be executed as 0:7C00 or 07C0:0000. Moreover, it does not matter to the code. Relative jumps and calls still work as expected. However, to access memory you need your DS/ES to have known addresses. It is usually the best to just keep them at 0 until you really can't anymore.paikuhan wrote: Note that I don't need them with Bochs Emulator (I'm guessing because it's outdated?), but need them in both VMWare Player and Oracle VirtualBox. Bochs initializes all memory, and all registers, before executing your code. Other BIOSes do not have to do the same. In general, never assume the value of anything unless there is some kind of interface contract that something must have a certain value. In this case, you can assume that DL contains the BIOS drive number of the drive being booted, and that CS:IP will combine to form the linear address 7C00, and that is about it.Your code contains exactly the code I suggested after the first call to print_string. Why? Memory is tight, doing unnecessary work uses it up. The normal way to do a relocating MBR is something like this: Code: org 600h ;eventually, we end up there cli xor ax,ax mov ds,ax mov es,ax mov ss,ax mov sp,7c00h sti cld mov si,7c00h mov di,600h mov cx,256 rep movsw jmp 0:start start: This will use a far jump to jump to an absolute address to actually start the MBR at the correct address. Beyond that I see you are using INT 13 extensions, but do not check whether INT 13 extensions are available on the drive you are using, or whether INT 13 returned an error. The behavior you are seeing is consistent with something being not to the BIOSes liking. For something as simple as this, might I suggest foregoing the INT 13 extensions and just using the normal functions? Way less to do wrong there. |
Author: | paikuhan [ Wed Apr 07, 2021 6:55 am ] |
Post subject: | Re: Why isn't VMWare copying the content of my drive to 0x7C |
nullplan wrote: Your code contains exactly the code I suggested after the first call to print_string. Why? You are right I added it again on top because my print_string wasn't working and forgot to add remove it after. nullplan wrote: The normal way to do a relocating MBR is something like this: Code: org 600h ;eventually, we end up there cli xor ax,ax mov ds,ax mov es,ax mov ss,ax mov sp,7c00h sti cld mov si,7c00h mov di,600h mov cx,256 rep movsw jmp 0:start start: This will use a far jump to jump to an absolute address to actually start the MBR at the correct address. That looks like what I did only I used MOVSB instead of MOVSW and for 7C00H and 600H I used defined constant instead but that pretty much the same thing. nullplan wrote: Beyond that I see you are using INT 13 extensions, but do not check whether INT 13 extensions are available on the drive you are using, or whether INT 13 returned an error. The behavior you are seeing is consistent with something being not to the BIOSes liking. For something as simple as this, might I suggest foregoing the INT 13 extensions and just using the normal functions? Way less to do wrong there. Thanks this comment helped a lot! I used a virtual Floppy drive and loaded as Floppy disk a 256 MB raw binary (that represents the disk). I guess because the raw binary was too big to be a floppy disk, VMWare didn't want to do a thing. (According to Wikipedia and OSDev's Wiki, INT 13H is the only game in town when it comes to loading data from HDD, Floppy and USB so I am not sure what you are talking about when you say : nullplan wrote: and just using the normal functions Anyway, I was able to fix my issue by telling VMWare to use a *.vmdk as SATA HDD instead of a raw *.bin as floppy disk. I'm curious still... What other way are you talking about when it comes to reading data from something that is not RAM? |
Author: | bzt [ Wed Apr 07, 2021 10:05 am ] |
Post subject: | Re: Why isn't VMWare copying the content of my drive to 0x7C |
paikuhan wrote: That looks like what I did only I used MOVSB instead of MOVSW and for 7C00H and 600H I used defined constant instead but that pretty much the same thing. Nope, you haven't used the ORG directive correctly. If you had, then you couldn't access string and the print function, and there would be no need for adjusting the JMP. Also as nullplan pointed out, you should set CS too with a far jump. Here's how I do it (Note that I locate the actual position dynamically, and I do not access any variables nor functions before the relocation, except with a relative address near call):Code: bootboot_record: Notes: I set DS to CS before the copy and I autodetect the location because I also support ROM boot (code is "loaded" somewhere above C8000h), you probably won't need that part. I also clear both DS and CS when I jump to ".start" but not before (movsb/movsw in the copy implicitly uses DS/ES), and no address adjustments needed for the far jump.jmp short .skipid nop ;skip BPB area so that we can use this ;boot code on a FAT / exFAT volume if needed db 120-($-$$) dup 0 .skipid: ;relocate our code to offset 0h:600h cli cld xor ax, ax mov ss, ax mov sp, 600h push ax pop es push cs pop ds ;find our position in memory. call .getaddr .getaddr: pop si sub si, .getaddr-bootboot_record mov di, sp ;clear data area 500h-600h sub di, 100h mov cx, 80h repnz stosw ;and copy ourselves to 600h mov cx, 100h repnz movsw ;have to clear ds, because cs is set to 7c0 when booted from El Torito push es pop ds jmp 0:.start .start: paikuhan wrote: Anyway, I was able to fix my issue by telling VMWare to use a *.vmdk as SATA HDD instead of a raw *.bin as floppy disk. I'm curious still... What other way are you talking about when it comes to reading data from something that is not RAM? The extended read AH=42h uses LBA addressing mode, not available for floppies (not on all BIOS that is). That's why it worked with HDD but not with floppy. In general, you can only assume LBA addressing if the drive code is 80h or above. You can use AH=41h, BX=55AAh function to check for support, it returns BX=AA55h if the device in DL does support the extended read function. Take a look at my boot sector, which works as MBR, VBR and CDROM boot sector too.Cheers, bzt |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |