OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Nov 20, 2017 8:02 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Fri Jul 21, 2017 2:50 am 
Offline

Joined: Thu Jul 20, 2017 11:36 pm
Posts: 5
Hello Everybody

I am trying to develop 16 bit sample 2 stage boot loader using visualstudio 1.5 and MASM 1.5 and want to test on the virtual box.

My sample code is
Code:
.MODEL SMALL
.486p

   _TEXT   SEGMENT   WORD USE16 'CODE'
      ASSUME   CS:_TEXT, DS:_TEXT, ES:_TEXT

   ORG    100H   
   ORG      0500H    
   
   StartFromSecondSector:
      jmp      near ptr SecondSector
      nop
      ORG   0500H
      
      
   SecondSector:
         ; Boot Code
      
   ORG    7C00H
   ASSUME   CS:_TEXT, DS:_TEXT, ES:_TEXT   
   
   main:
      
         xor   ax, ax         
         mov   ds, ax
         mov   es, ax
         cli               
         mov   ss, ax         
         mov   sp, 4F00H   
         sti
         
         mov      dl, 80h
         mov      ah, 41h
         mov      bx, 55aah
         int      13h
         setnc         is_ext
         
         mov      si, offset vol0
         mov      bx, 0400H
         
         test          is_ext, 0ffh
         jz      short ErrorMSGPrompt
         
         mov      ah, 42h
         mov           dl, 80h
         int      13h
         jmp      StartFromSecondSector
         
         ORG      7C00H+1BEH   
         DB      64 DUP (0FFH)   

         DB      055H      
         DB      0AAH      

         ErrorMSGPrompt:
            ; Error mesage int10

         _TEXT      ends
         
   end      main


After Assembling and making and 16 bit executable , i remove the EXE signature and placed the binary in 2 file . 1 stage0.DAT which contains the 512 bytes of code started from 7c00 and another file is stage1.DAT which contains the next 512 bytes of started from 500 offset.

In virtualbox vdi HDD of fixed size , i copied the 512 byte of stage0.dat from 0200000 and i copied the 512 bytes of stage1.DAT from 0200500

The stage0 works fine but the jump to the stage 2 is failing. is i am missing some thing ?

Thanks in Advance

Niraj


Top
 Profile  
 
 Post subject: Re: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Fri Jul 21, 2017 4:26 am 
Offline
Member
Member

Joined: Mon Sep 07, 2009 12:01 pm
Posts: 148
I would recommend using bochs debugger to step through instruction by instruction, to work out exactly where it is failing.

(Also: why are you stripping an EXE header rather than assembling to flat binary in the first place?)


Top
 Profile  
 
 Post subject: Re: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Fri Jul 21, 2017 4:55 am 
Offline
Member
Member

Joined: Thu Aug 13, 2015 4:57 pm
Posts: 334
Or doing a thousand ORG's, or extraneous cli/sti....


Top
 Profile  
 
 Post subject: Re: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Fri Jul 21, 2017 6:01 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 118
LtG is right. You need exactly one ORG (maybe 2 with relocation), and use cli/sti instructions carefully. What's more, there's a reason why all boot loaders start with cli. Even more, your stack will very likely overwrite your code or data.

Suggestions:
1. read spec carefully, don't start writing a boot loader until you are 100% sure how memory layout looks like (the ORGs suggest you don't have a clue)
2. relocate your code if you want to support chainloading. 0:600h would be an appropriate place for that.
3. set up segment registers properly. You've forgotten to set up the most important segment register. Only original IBM BIOS used 0:7C00h, there are BIOSes that use 7C0h:0 (homework: learn about real mode addressing scheme and figure out why 0:7C00h == 7C0h:0).
4. place your stack out of the way, and calculate it's maximum size properly. Make sure it won't overwrite your code or data
5. as madanra suggested, boot loaders are raw flat binaries. There's a good chance that your assembler messes up segments when using EXE layout, and stripping header won't magically fix that.
6. learn about x86 instructions and BIOS interrupts. Code size is an essence. Use int/jc as it compiles to less bytes.
7. Don't assume you are booting from the first disk. Don't touch dl.
8. Your description on modifying the VDI is uninterpretable in this context. At what sector do you want to store 2nd stage? It must be sector aligned, at least. And if your stage1.DAT contains any code, you have seriously messed up something. Your code (from main label to the end) is less than 512 bytes...
9. If you've thought that your first jump will work (with wrong addresses and unloaded 2nd stage), then I'd suggest to study a lot before you start to write a boot loader. Right now, you definitely don't have the required knowledge.


Top
 Profile  
 
 Post subject: Re: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Sun Jul 23, 2017 10:24 pm 
Offline

Joined: Thu Jul 20, 2017 11:36 pm
Posts: 5
Thanks to All for this valuable input. I am new to this bootloader stuff and you are right i need to learn more.
I will go with single assembly for all.

Can i get any sample for this 2 stage bootloader for x86 machine so that i can go through that and learn .

Thanks
Niraj


Top
 Profile  
 
 Post subject: Re: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Mon Jul 24, 2017 5:07 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 118
NirajJha wrote:
Thanks to All for this valuable input. I am new to this bootloader stuff and you are right i need to learn more.
I will go with single assembly for all.

Can i get any sample for this 2 stage bootloader for x86 machine so that i can go through that and learn .

Thanks
Niraj

Welcome! Yes, there are a lot of examples in this forum and there's a very good description on the wiki as well. Also you can take a look at my code.

stage1 code that loads my stage2 and transfers control to it. I do not support floppies, only hard drives (and I don't support CHS, I use LBA addresses to load sectors from disk to memory. Suitable for USB sticks). I assume that the stage2 can be anywhere on the disk, it's continuous (if it's on a filesystem then the fs is defragmented) and it's first LBA is recorded in stage1 at 0x1B0. I have created an mkfs tool that will guarantee that. It's called mbr.asm, but don't let that confuse you, it works as a VBR too.

stage2 code is special as it complies with BIOS boot specification therefore it can be loaded not only by stage1, but from ROM as well. It's also compatible with GRUB's Multiboot. My goal was to achieve multiple ways to load stage2 in a single binary image, so it's a bit more complex than other examples you can find.

You can use my stage1 code (binary included) and write your own stage2 with VS if you like. Your stage2 must start with a 6 bytes header, but other than that you are free to do whatever you want (32 bytes header only required if you want to load your stage2 from ROM too, and 64 bytes if you also want it to be Multiboot compliant as well). I suppose (as you are using VS) you're not building on ELF but PE kernel? But if so, you can use both stages if you are okay with an ELF64 mapped at the last page directory in the memory, -2M. Both sources are public domain. You can find more documentation and precompiled binaries here.


Top
 Profile  
 
 Post subject: Re: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Mon Jul 24, 2017 6:01 am 
Offline

Joined: Thu Jul 20, 2017 11:36 pm
Posts: 5
Thanks :D :D . I will Go through this .

Can i test this on virtual box vdi image. DO i need to copy of the 1st stage code 0200000 to 2001F0 and second stage from 0200600 to 0200B12 or from 0200200 .


Top
 Profile  
 
 Post subject: Re: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Tue Jul 25, 2017 5:43 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 118
NirajJha wrote:
Can i test this on virtual box vdi image. DO i need to copy of the 1st stage code 0200000 to 2001F0 and second stage from 0200600 to 0200B12 or from 0200200 .
Stage1 must be 200h bytes long, and stage2 must be multiple of 200h bytes. I suggest to create raw image, and copy the stage1 in the first sector of the disk at offset 0 (if you want to use it as an MBR) or in the first sector of a partition (if you intend to use it as VBR), and save the stage2's first lba address at dword 0x1B0 (which will be 2 if you add the stage2 right after the MBR and before the first partition).
I cannot tell you exactly where my stage2 is located, as I copy it as a simple file on the first partition. Depending on configuration, that first partition is either a FATx (in which case I use BOOTBOOT\LOADER) or a partition with my own fs, FS/Z (in that case I use /sys/loader). Regardless my disk creation utility (mkfs disk) locates the stage2 part and records it's starting sector in the MBR (and also stores stage1 code there). So when my image (bin/disk.dd) is finished, everything is at place to boot. If you want to test it with Virtualbox, you can use VBoxManage utility to create vdi from the raw image (part of Virtualbox, see my makefile for make vdi).

Other than that if you meant memory addresses, you cannot access memory above 0FFFFh in real mode (assuming your segment is 0). The stage1 is loaded at 7C00h (or 7C0h:0) by the BIOS, and then it relocates itself to 0:600h. The stage2 (which is loaded by stage1, GRUB or already accessible in ROM above C8000h) relocates itself after that, at 0:800h if necessary (the memory map is described in the beginning of the source in detail).

If you use BOOTBOOT stage1 and roll your own stage2, you should use ORG 800h, zero out segment registers and the stack pointer.
Code:
    ORG 800H
SecondSector:
    DB 55H, 0AAH, 0, 0E9H  ; magic bytes, don't care, don't change
    DW main                ; label to execute on start
main:
    xor ax, ax
    mov sp, ax             ; see below
    mov ds, ax
    mov es, ax
    ...etc.
You shouldn't bother with size, checksum and relocation at all (as you don't want to store your stage2 in ROM) therefore the first 6 bytes won't change. Now I've also used a little trick here with the stack. When you push your first item on the stack, it will decrease the sp pointer from 0 which will wrap around to 0FFFEh and will store the item there. That's the highest address you can use in small model in real mode, therefore it provides the biggest space for your program and the stack. You can of course use "mov sp, 07C00h" if you like.

You can place your stage2 code anywhere on the disk (as long as it's sector aligned, that is), just don't forget to save the starting LBA address in stage1's sector (that can be detected with a hexeditor the same way my mkfs utility does: look for the magic bytes, then use offset/512+1). If you're not creating a raw image and convert it to vdi afterwards as suggested, then you should subtract the size of the vdi header (in other words the offset of MBR) from the offset first. So for example if vdi header is 200000h bytes long, mbr.bin should be copied to 200000h-2001FFh. If you choose to save your stage2 right after it, then store that to 200200h-207DFFh (or less if it's smaller), and set 2 at 2001B0h. If you choose to create a partition with your stage2 as a file on it, then locate the magic bytes in the vdi. Let's say they are at 201600h, then 2001B0h should be 0Ch ('cos (201600h-200000h)/200h+1=0Ch).


Top
 Profile  
 
 Post subject: Re: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Tue Jul 25, 2017 9:49 pm 
Offline

Joined: Thu Jul 20, 2017 11:36 pm
Posts: 5
Thanks a lot .. :) :) :)


Top
 Profile  
 
 Post subject: Re: Testing 2 Stage Bootloader on VirtualBox
PostPosted: Tue Sep 19, 2017 4:38 am 
Offline

Joined: Thu Jul 20, 2017 11:36 pm
Posts: 5
Hi ,

I have followed the given suggestion and perform the following
1. As I am using windows as mt dev machine , so Written Disk Filter Driver to read and write Disk sectors
2. Create a Format tool by which I am creating an file and copied my 2nd stage bootloader file , defreg it and got its physical address using FSCTL_GET_RETRIEVAL_POINTER and place its base physical address in MBR . In one of my test example this was like Start Sector(0x567D8) => EndSector(0x56FD7 ) . In MBR i copied this address at 0x11 . I used my Driver to update this MBR .

3. A New MBR loaded 0n 0x7c00 and this address is in data segment 0x7c10 .


Now I am trying to perform 2 things from here

1. Try to read the Extended by calling int 13h with service 42 . What should i include in my format tool so that i can read my 2nd stage code using 42h of 13h interrupt . Currently when i perform this service the windows original BootSector code is getting loaded on given stack

2. How do i load this sector using 13h 2 service . Below is the code i am using for this purpose which seems to be incorrect somewhere as on 13h interrupt the value of AH is 1 but the wrong data is copied on stack .

I am using BOCHS emulator and debuggers to debug this code ;

mov ah , 0x08 ;
int 13h
and cx , 03fh ;
mov byte ptr [SectorPerTrack] , cl ; (0x7a09 ==> 3fh)
movzx ax , dh
inc ax
mul cx
mov word ptr [ SectorPerCyl] , ax ; (0x7a00 => 3ec1h)
mov word ptr [SectorPerCyl +2] , dx ; (0x7a02=> 0 )
mov si , 0x7c10 ; ( actual address offset of bootloader file)
mov bx, 0x600

mov edx , dword ptr ds:[si+4]
mov eax , dword ptr ds:[si]
div eax , dword ptr ds:0x7a00
cmp eax, 1024 // File Size in KB
; jne error ;

push ax
mov ax , dx
div al, byte ptr ds:0x7a09
mov dh , al
mov cl, ah
inc cx
pop ax
mov ch , al
shl ah , 0x06
or cl , ah
mov ax , 0x001
mov ah, 0x02
mov dl , 80h
int 13h


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot], osdevnewbie and 15 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

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group