Page 1 of 1

Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 6:27 am
by Roman
I can't realize, why doesn't my boatloader jump to its second stage.

Stage 1:

Code: Select all

	section .text
	use16
	org 0x7C00  ; Load addr
start:
	mov ax, cs
	mov ds, ax ; Select data segment.

	mov ah, 1 ; Turn on the cursor.
	int 0x10

	mov ah, 00h ; Set video mode.
	mov al, 2
	int 0x10

	mov ah, 13h ; Notify about booloader start.
	mov al, 1
	mov bh, 0
	mov bl, 0_7h
	mov cx, start_msg_len
	mov dh, 0
	mov dl, 0
	mov bp, start_msg
	int 0x10

	mov bl, 0_2h ; Write welcome message.
	mov dl, start_msg_len + 1
	mov cx, welcome_msg_len
	mov bp, welcome_msg
	int 0x10

	mov bl, 0_7h ; Notify about next stage loading.
	mov dh, 2
	mov dl, 0
	mov cx, next_stg_msg_len
	mov bp, next_stg_msg
	int 0x10

	mov ah, 0 ; Let's reset floppy's controller!
	mov dl, 0
	int 0x13
	jc error

	mov ah, 2
	mov al, 1
	mov ch, 0
	mov cl, 1
	mov dh, 0
	mov ebx, 0x1000
	mov dl, 0
	int 0x13
	jc error

	jmp dword 0x1000

start_msg db "SimpleX bootloader started."

start_msg_len equ $ - start_msg


welcome_msg db "Welcome!"

welcome_msg_len equ $ - welcome_msg


next_stg_msg db "Loading next stage..."

next_stg_msg_len equ $ - next_stg_msg


error:
	mov ah, 00h
	mov al, 2
	int 0x10
	
	mov ah, 13h
	mov al, 1
	mov bh, 0
	mov bl, 0_4h
	mov cx, error_msg_len
	mov dh, 0
	mov dl, 0
	mov bp, error_msg
	int 0x10

	cli
	hlt

error_msg db "Critical error occured! Cannot continue."

error_msg_len equ $ - error_msg


finish:
	times 0x1FE-finish+start db 0
	db   0x55, 0xAA ; Boot signature
Stage 2:

Code: Select all

    section .text
    use16
    org 0x7C00
start:
	mov ax, cs
	mov ds, ax ; Select data segment.

    mov ah, 00h ; Set video mode.
    mov al, 2
    int 0x10

    cli
    hlt
finish:
    times 0x1FE-finish+start db 0
Boot disk creation:

Code: Select all

$ dd if=/dev/zero of=boot.img bs=1024 count=1440
$ dd if=stage1.bin of=boot.img conv=notrunc
$ dd if=stage2.bin of=boot.img conv=notrunc seek=512

Re: Writing a two stage bootloader.

Posted: Thu Mar 27, 2014 6:39 am
by bwat
Set register cl to 2 in your sector loading code.

BIOS int 13h, function 02h, Read Sector.
Input
AH = 02h
AL = number of sectors to read
CH = track/cylinder
CL = sector
DL = disk (00h-7Fh floppy, 80h-FFh hard disk)
DH = head
ES:BX = segment:offset of buffer
Output
CF = 0 on success, 1 on failure with AH = failure code
AL = number of sectors read

Re: Writing a two stage bootloader.

Posted: Thu Mar 27, 2014 6:55 am
by Roman
bwat wrote:Set register cl to 2 in your sector loading code.

BIOS int 13h, function 02h, Read Sector.
Input
AH = 02h
AL = number of sectors to read
CH = track/cylinder
CL = sector
DL = disk (00h-7Fh floppy, 80h-FFh hard disk)
DH = head
ES:BX = segment:offset of buffer
Output
CF = 0 on success, 1 on failure with AH = failure code
AL = number of sectors read
I've set cl to 2, but it still doesn't work. :(

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 7:18 am
by Combuster
How often did you run this code through a debugger?

Remember, "never" is not allowed as an answer :wink:

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 7:23 am
by bwat
Roman wrote:

Code: Select all

$ dd if=/dev/zero of=boot.img bs=1024 count=1440
It's been a while since I've booted a floppy but is that block size correct?
Roman wrote:

Code: Select all

$ dd if=stage2.bin of=boot.img conv=notrunc seek=512
Do you want to seek 512 blocks?

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 7:37 am
by Roman
bwat wrote:
Roman wrote:

Code: Select all

$ dd if=/dev/zero of=boot.img bs=1024 count=1440
It's been a while since I've booted a floppy but is that block size correct?
Roman wrote:

Code: Select all

$ dd if=stage2.bin of=boot.img conv=notrunc seek=512
Do you want to seek 512 blocks?
I want to write stage 2 right after stage 1 and jump from 1 to 2.

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 7:51 am
by Roman
Why doesn't this code load the second sector and jump to it?

Code: Select all

	mov ah, 02
	mov al, 01
	mov ch, 01
	mov cl, 02
	mov dh, 01
    mov bx, 0x2000
    mov es, bx
    mov bx, 0
	mov dl, 00
	int 0x13
	jc error

	jmp 0x2000:0x0000

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 8:08 am
by bwat
Roman wrote:I want to write stage 2 right after stage 1 and jump from 1 to 2.
When you hex dump the image file, do you see your second stage at offset 512?

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 8:40 am
by Roman
bwat wrote:
Roman wrote:I want to write stage 2 right after stage 1 and jump from 1 to 2.
When you hex dump the image file, do you see your second stage at offset 512?
Yes.
Not really sure about offset. That's boot.img hex dump:

Code: Select all

0000000 8c c8 8e d8 b4 01 cd 10 b4 00 b0 02 cd 10 b4 13
0000010 b0 01 b7 00 b3 07 b9 1b 00 b6 00 b2 00 bd 61 7c
0000020 cd 10 b3 02 b2 1c b9 08 00 bd 7c 7c cd 10 b3 07
0000030 b6 02 b2 00 b9 15 00 bd 84 7c cd 10 b4 00 b2 00
0000040 cd 13 72 55 b4 02 b0 01 b5 01 b1 02 b6 01 bb 00
0000050 20 8e c3 bb 00 00 b2 00 cd 13 72 3d ea 00 00 00
0000060 20 53 69 6d 70 6c 65 58 20 62 6f 6f 74 6c 6f 61
0000070 64 65 72 20 73 74 61 72 74 65 64 2e 57 65 6c 63
0000080 6f 6d 65 21 4c 6f 61 64 69 6e 67 20 6e 65 78 74
0000090 20 73 74 61 67 65 2e 2e 2e b4 00 b0 02 cd 10 b4
00000a0 13 b0 01 b7 00 b3 04 b9 28 00 b6 00 b2 00 bd b5
00000b0 7c cd 10 fa f4 43 72 69 74 69 63 61 6c 20 65 72
00000c0 72 6f 72 20 6f 63 63 75 72 65 64 21 20 43 61 6e
00000d0 6e 6f 74 20 63 6f 6e 74 69 6e 75 65 2e 00 00 00
00000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
0000200 8c c8 8e d8 b4 00 b0 02 cd 10 fa f4 00 00 00 00
0000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0168000

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 8:47 am
by Roman

Code: Select all

00040008   CD 10 FA F4  42 4F 4F 54  53 54 41 47  45 32 00 00
Seems to be the stage2.bin int the boot.img

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 8:54 am
by Roman
I dumped memory at 0x2000 in QEMU. Opened using hexedit:

Code: Select all

00000000   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
0000002C   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
00000058   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
00000084   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
000000B0   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
000000DC   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
00000108   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
00000134   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
00000160   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
0000018C   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
000001B8   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............................................
000001E4   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                                                      ............................

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 9:26 am
by bwat
Roman wrote:

Code: Select all

00040008   CD 10 FA F4  42 4F 4F 54  53 54 41 47  45 32 00 00
Seems to be the stage2.bin int the boot.img
Roughly 512 disk blocks into the disk. As I asked before, do you want to seek 512 blocks?
Roman wrote:I dumped memory at 0x2000 in QEMU. Opened using hexedit:
Why?
Earlier you showed us this piece of code. Would it not be better dumping that address?
Roman wrote:

Code: Select all

	jmp 0x2000:0x0000

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 10:09 am
by M2004
Roman: You are not setting up the stack properly in your code.

regards
M2004

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 10:46 am
by Pancakes
I am sure somebody will eventually tell you what is wrong, but I wanted to help give you some debugging help/examples. Debugging is very useful no matter what you are doing.
  • verify execution is reaching the floppy sector loading code and your jump instruction by printing some messages before and after each area/block of code
  • if your messages show stuff was being executed, then double check it is actually doing what is intended; first verify 0x1000 can be written to by writing a byte and reading the result
  • check that your floppy image actually contains the second stage; however, maybe its not at the right location; it has been too long since I have done floppy stuff - but always verify never assume something is right
  • if you can write a byte (or even more) and then read it back then the memory is likely writable
  • if the memory is writable look closer at the floppy sector loading code because apparently it is either not loading, not loading the correct sector, loading to the wrong address, or a combination
  • Try placing the 2nd stage code about 100 times with a shell script of some kind, lol. If its loading one sector too far your bound to get some results. You goal in debugging is to get results so change things and look for the change. Even if it is a bad change it is still a little evidence that might help you figure out what is wrong.
  • Also, another idea is to make a loop and increment the sector index, head, and cylinder and each time you call the BIOS function in that loop to read the byte at the intended location for any value other than zero (or whatever is there before you start). If you find a value other than your start value then print a message and find a way to print the value. Eventually, you are going to get some results.
  • Also, you could fill your entire floppy image with 32-bit numbers with the value of the first byte of the word. Then when something loads you can tell where it loaded from if you dump the memory. I would write a little program to do this, if it was me, and have it append onto your boot sector. If the code is loading.. it is going to load something and if you still have nothing at that memory location then double check the memory location.
The hardest part about working with anything is figuring out what is wrong and what is right. Because, your going to run into a problem that nobody is going to be able to help you solve because your code is going to become large and complex. Then your going to be unable to continue unless you learn how to debug and narrow down your problem.


Also... why are you doing...

Code: Select all

    mov bx, 0x2000
    mov es, bx
    mov bx, 0
Does that not seem odd? ES:BX = segment:offset of buffer
Output
..

BX, should hold the offset of your buffer and, ES should be zero? Or, have I just completely forgotten how segment registers work... Anyway, verify it (try it)! LOL
[/size]

Re: Writing a two stage boot loader. HELP!

Posted: Thu Mar 27, 2014 11:01 am
by Roman
Thanks, everyone! My mistake was my in attempt to write using dd with seek=512, instead of seek=1.