Bootloader loaded at memory other than 0x7c00

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
jarvis
Posts: 3
Joined: Thu Dec 26, 2013 12:33 am

Bootloader loaded at memory other than 0x7c00

Post by jarvis »

I made a simple boot loader that would just check for the first 'filled' memory location starting from 0x00 and show the next 512 bytes (which should be the 512 bytes of the bootloader).

Probably this first 'filled' memory should be the first byte of the bootloader where it is loaded. Traditionally a bootloader is loaded at 0x00007c00. But the program is outputting that the bootloader was loaded at 0x00.

How is this possible ? It gives the same result in a virtual machine (Virtual Box) as well as real machine. Please help. Also the program isn't executed if I use ORG 0x7C00 at line 2

Here is the bootloader :

Code: Select all

BITS 16

start:
	mov ax, 07C0h		; Set up 4K stack space after this bootloader
	add ax, 288		; (4096 + 512) / 16 bytes per paragraph
	mov ss, ax
	mov sp, 4096

	mov ax, 07C0h		; Set data segment to where we're loaded
	mov ds, ax


	mov si, text_string	; Put string position into SI
	call print_string	; Call our string-printing routine

	jmp find

	jmp $			; Jump here - infinite loop!


	text_string db 'Ram contents from 0x7c0:0x0000 are : ', 0
	ram_byte db 65

print_string:			; Routine: output string in SI to screen
	mov ah, 0Eh		; int 10h 'print char' function

.repeat:
	lodsb			; Get character from string
	cmp al, 0
	je .done		; If char is zero, end of string
	int 10h			; Otherwise, print it
	jmp .repeat

.done:
	ret

find:
	mov cx,65535
	mov edx,0
again:
	mov al,[edx]
	cmp al,0
	jne print
	inc edx
	dec cx
	cmp cx,0
	jne again
	hlt

print:
	mov ah,0eh
	mov cx,512
print_again:	mov al,[edx]
	int 10h
	inc edx
	dec cx
	cmp cx,0
	jne print_again
	sub edx,512         ;Make edx equal to the loaction where it first found the non-zero byte
	ror edx,24         ; 
	mov al,dl          ;
	int 10h            ;
	rol edx,8          ;
	mov al,dl          ;
	int 10h            ;
	rol edx,8          ; Output the contentes of edx 
	mov al,dl          ;
	int 10h            ;
	rol edx,8          ;
	mov al,dl          ;
	int 10h            ;
	jmp $              ; Jump here
	
	
	times 510-($-$$) db 0	; Pad remainder of boot sector with 0s
	dw 0xAA55		; The standard PC boot signature 
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Bootloader loaded at memory other than 0x7c00

Post by iansjack »

You're not starting your search at 0x00, are you?
jarvis
Posts: 3
Joined: Thu Dec 26, 2013 12:33 am

Re: Bootloader loaded at memory other than 0x7c00

Post by jarvis »

Yes, the code does start searching from 0

Code: Select all

mov edx,0
again: mov al,[edx] 
It does just that. Correct me if I am wrong.
User avatar
mnovotny
Member
Member
Posts: 27
Joined: Mon Aug 10, 2009 2:54 am
Location: Slovakia

Re: Bootloader loaded at memory other than 0x7c00

Post by mnovotny »

mov ax, 07C0h ; Set data segment to where we're loaded
mov ds, ax
Also your bootcode is not the first nonzero thing in memory.
Keep the world with all its sin
It's not fit for livin' in
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Bootloader loaded at memory other than 0x7c00

Post by iansjack »

You start your search from DS:0x00.

This is extremely basic stuff. I think you need to review the fundamentals of x86 assembler and memory addressing.
jarvis
Posts: 3
Joined: Thu Dec 26, 2013 12:33 am

Re: Bootloader loaded at memory other than 0x7c00

Post by jarvis »

I learnt assembly from Paul Crater's book.
It says using [edx] will just point to the data inside the memory location pointed by contents of edx.
I think

Code: Select all

mov al,[edx]
should do just that irrespective of DS

PS : I am not much confident about the cs,ds,es,etc. registers
CWood
Member
Member
Posts: 127
Joined: Sun Jun 20, 2010 1:21 pm

Re: Bootloader loaded at memory other than 0x7c00

Post by CWood »

In real mode, unless explicitly stated, (well, in all modes actually, but protected/long mode usually has flat memory, rather than segmented), any memory access is relative to DS. When you write

Code: Select all

mov al, [edx]
you are, in fact, implying

Code: Select all

mov al, [ds:edx]
My honest suggestion to resolve this, would be to write

Code: Select all

mov ax, 0x00
mov es, ax
mov al, [es:edx]
This way, you're starting at absolute address 0. My suggestion would be to find a good resource, and brush up on segmentation. Or, failing that, use a multiboot loader, like GRUB, and deal with protected mode only, where you don't have to worry about things like this.
User avatar
mnovotny
Member
Member
Posts: 27
Joined: Mon Aug 10, 2009 2:54 am
Location: Slovakia

Re: Bootloader loaded at memory other than 0x7c00

Post by mnovotny »

CWood wrote:In real mode, unless explicitly stated, (well, in all modes actually, but protected/long mode usually has flat memory, rather than segmented), any memory access is relative to DS.
Except not. DI uses ES and BP and SP use SS.
Keep the world with all its sin
It's not fit for livin' in
rdos
Member
Member
Posts: 3311
Joined: Wed Oct 01, 2008 1:55 pm

Re: Bootloader loaded at memory other than 0x7c00

Post by rdos »

The boot code is always loaded at linear address 0x7c00, but it is not guaranteed to be loaded at 0x0:0x7c00 or 0x7C0:0, rather it could be either of those. That's why stable boot-code need to use a far jump to make sure code segment offsets used are correct.
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Bootloader loaded at memory other than 0x7c00

Post by iansjack »

Paul Carter's book deals exclusively with Protected Mode programming (and it assumes a specific, rather simple, memory model). You are trying to program in Real Mode here, so the concepts are not exactly the same. If you wish to program at this sort of level you need a better grasp of assembler programming and a more comprehensive reference. Ultimately that will be the Intel (or AMD) Programmers' Reference Manuals, but there are several other good books and online resources that cover the subject.

I think you need to find a web site that deals with x86 assembler programming and learn the basics from that before you try ambitious stuff like boot loaders. You should find several sites via Google, but these particular forums are not designed to teach the basics.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Bootloader loaded at memory other than 0x7c00

Post by thepowersgang »

My I be the first to point out that OP's strategy is fundamentally flawed.

The first thing in linear memory is the IVT, which will (nearly) always be non-zero. Your search will find it before it finds your bootloader.

And for the root problem - Why are you searching for your boot loader at all?
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Bootloader loaded at memory other than 0x7c00

Post by iansjack »

Well, mnovotny pointed out several posts back that the bootloader is not the first non-zero bytes in memory. Even ignoring the IVT it is invalid to assume that uninitialized memory is zero-filled. As it happens, the OP's code does exactly what he wants (why he wants it to do that is a mystery) and is guaranteed to find the start of his bootloader. It would have been quicker just to move 0 into edx and forget the rest of the code, but never mind.

I think the first, and fundamental, error in the OP is
I made a simple boot loader
Clearly this is untrue. You don't write code that loads the segment registers (including comments) without understanding what the segment registers are and how they work. It's another example of the dangers of cut-and-pasting code without understanding it.
Post Reply