Bootloader needs fix. See (JMP ...)

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.
0b00000000
Member
Member
Posts: 50
Joined: Sun Dec 20, 2015 4:00 pm
Libera.chat IRC: 0b00000000

Re: Bootloader needs fix. See (JMP ...)

Post by 0b00000000 »

Code: Select all

[BITS 16]
[ORG 0x7c00]

JMP 0x0000:start

start:
CALL reset
CALL load
JMP 0x0000:loaded

load:
MOV AL, 67
CALL print_character
MOV AX, 0x0000
MOV ES, AX
XOR BX, BX
MOV BX, loaded
MOV AH, 0x02
MOV AL, 1
MOV CH, 0
MOV CL, 2
MOV DH, 0
MOV DL, 0x80
INT 0x13
JC load
MOV AL, 68
CALL print_character
RET

print_character:
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07
INT 0x10
RET

reset:
MOV AL, 65
CALL print_character
MOV AH, 0
MOV DL, 0
INT 0x13
JC reset
MOV AL, 66
call print_character
RET

TIMES 510 - ($ - $$) db 0
DW 0xAA55

loaded:
MOV AL, 69
CALL print_character
JMP $
TIMES 1024 - ($ - $$) db 0
Is this any better? My intention here is to load to 0x07E00 (just after the in memory copy of the first sector) and to JMP to that same address. (above code still doesn't work - just wondering if I've got the address right).

0x00
0x00
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: Bootloader needs fix. See (JMP ...)

Post by Techel »

Thats better. At startup before jumping to 7C00 the bios supplies the id of the bootdrive in dl which should be passed to the int 13h read function.
0b00000000
Member
Member
Posts: 50
Joined: Sun Dec 20, 2015 4:00 pm
Libera.chat IRC: 0b00000000

Re: Bootloader needs fix. See (JMP ...)

Post by 0b00000000 »

So I should just leave DL and not set it?
0x00
0b00000000
Member
Member
Posts: 50
Joined: Sun Dec 20, 2015 4:00 pm
Libera.chat IRC: 0b00000000

Re: Bootloader needs fix. See (JMP ...)

Post by 0b00000000 »

Thanks guys,

that was one of the most prolonged prograsms I've ever had.

0x00
0x00
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: Bootloader needs fix. See (JMP ...)

Post by Techel »

You could save dl in memory in case it gets trashed.
0b00000000
Member
Member
Posts: 50
Joined: Sun Dec 20, 2015 4:00 pm
Libera.chat IRC: 0b00000000

Re: Bootloader needs fix. See (JMP ...)

Post by 0b00000000 »

How portable would this be?

What can I do to make sure this would run correctly on a wider variety of machines?

0x00
0x00
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Bootloader needs fix. See (JMP ...)

Post by Combuster »

0b00000000 wrote:What can I do to make sure this would run correctly on a wider variety of machines?
You should read the FAQ on common bootloader issues - you still have obvious bugs left waiting to strike.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
TightCoderEx
Member
Member
Posts: 90
Joined: Sun Jan 13, 2013 6:24 pm
Location: Grande Prairie AB

Re: Bootloader needs fix. See (JMP ...)

Post by TightCoderEx »

0b00000000 wrote:How portable would this be?
What can I do to make sure this would run correctly on a wider variety of machines?
0x00
What I've done is loaded the next 17 sectors using CHS, starting @ 7E00 which populates memory up to BFFF. My loader has been tested on USB, FCD & HDC desktops and laptop. I'm confident that I've covered all bases except for UEFI machines that won't emulate BIOS. Should I come across lower density 3.5 or 5.24, all that needs to be done is change AL accordingly. As you progress you'll probably find your development paradigm excluding more and more hardware. IDE & FDC are probably at the top of the list, so the point is just concern yourself with hardware that you can test on and once your OS is complete, it will probably be pretty easy for you to re-implement.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Bootloader needs fix. See (JMP ...)

Post by Brendan »

Hi,
0b00000000 wrote:Is this any better?
Here's a list of every problem I could see. Please note that I'm a bit of a perfectionist I guess - don't let this worry you too much. The problems are:

a) NASM directives have a "user-level form" and a "primitive form". The primitive form is what the assembler uses internally, and the user level form is like a macro that can augment the primitive form. For some directives they're (currently) effectively equivalent, and for some directives things break when you use the primitive form. You should always use the user-level form unless you've got a very good reason not to. You are using the primitive form everywhere (e.g. "[bits 16]" and "[orc 0x7C00]" and you should really be using the user-level form (e.g. "bits 16" and "org 0x7C00").

b) Some (extremely old and rare now) Compaq computers expect a boot loader to begin with a "short JMP" instruction and assume the code is not bootable if it begins with something else (e.g. a "far JMP" instruction).

c) There is no reason to reset the disk system before you use disk IO; mostly because you know for a fact that the BIOS has just used it successfully to load your boot sector and therefore it must be working fine.

d) When loading sectors from disk, you should have a "retry at least 3 times" loop. If the disk is faulty you do not want to retry an infinite number of times (unless you're writing malicious code that intentionally tries to destroy floppy drives or something). Note that if/when there has been a problem, you want to reset the disk system occasionally between retries. I typically do an "if retry count is odd and not even; then reset disk system" thing. If you've retried 3 or more times and it still doesn't work, you need to inform the user using a nice descriptive error message (if possible) so they've got at least some hope of figuring out what the problem might be.

e) It is a very bad idea to assume that the BIOS left SS:SP (the stack) pointing to anywhere specific. You must initialise SS:SP yourself (just so you can know your stack is somewhere safe) before loading anything from disk; otherwise it's possible that the data you load from disk will overwrite your stack.

f) It is a bad idea to assume that the BIOS started your code. Often it did not - e.g. the BIOS started some sort of boot manager thing, which chain-loaded your code. You shouldn't assume that you're booting from "device 0x80" - whatever booted your code tells you the correct device number in DL, and you should save this value somewhere and use it for all disk IO (so that your OS can boot correctly from "device 0x81" or anything else).

g) It's also probably a bad idea to assume that whatever booted your code left the video in a sane state. You should set 80*25 mode yourself, and ask the BIOS which "video page number" is currently active. A nicer idea is to ask the BIOS if you're already in 80*25 mode and only set the video mode if you have to.

h) For boot sectors; you will have trouble cramming as much as possible into 512 bytes, and you will need to cripple your code a little to make things fit. This means that it's important to at least try to reduce code size. A simple optimisation is to load both halves of a 16-bit register at once (e.g. "mov ax,0x02 * 256 + 1" instead of "mov ah,0x02" and "mov al,1").

i) For hard disks, the first sector of the disk should contain the MBR and primary partition table (even for UEFI where it's a "protective partition table"). The first sector of the disk should not contain any OS's boot sector. An OS's boot sector belongs in the first sector of the OS's partition.

j) For hard disks, it's a bad idea to use "int 0x13, ah=0x02" because the OS's partition may be outside the small area that this function can reach. You need to use "int 0x13, ah=0x42" instead (and fall back to "int 0x13, ah=0x02" on extremely ancient computers, if you could be bothered supporting computers that are 20+ years old, and if "int 0x13 extensions" aren't supported).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
TightCoderEx
Member
Member
Posts: 90
Joined: Sun Jan 13, 2013 6:24 pm
Location: Grande Prairie AB

Re: Bootloader needs fix. See (JMP ...)

Post by TightCoderEx »

Brendan wrote:b) Some (extremely old and rare now) Compaq computers expect a boot loader to begin with a "short JMP" instruction and assume the code is not bootable if it begins with something else (e.g. a "far JMP" instruction).
A couple of other reasons to consider this is; a) Applications like HexEdit won't work right when trying to write raw data to disk. I don't believe "dd" or "partcopy" have this issue and I know the "w" command in debug.com doesn't. b) BPB only uses 60 bytes and even though in my case I don't plan on using it, but should I change my mind, it's already there.
0b00000000
Member
Member
Posts: 50
Joined: Sun Dec 20, 2015 4:00 pm
Libera.chat IRC: 0b00000000

Re: Bootloader needs fix. See (JMP ...)

Post by 0b00000000 »

TightCoderEx wrote:
0b00000000 wrote:How portable would this be?
What can I do to make sure this would run correctly on a wider variety of machines?
0x00
What I've done is loaded the next 17 sectors using CHS, starting @ 7E00 which populates memory up to BFFF. My loader has been tested on USB, FCD & HDC desktops and laptop. I'm confident that I've covered all bases except for UEFI machines that won't emulate BIOS. Should I come across lower density 3.5 or 5.24, all that needs to be done is change AL accordingly. As you progress you'll probably find your development paradigm excluding more and more hardware. IDE & FDC are probably at the top of the list, so the point is just concern yourself with hardware that you can test on and once your OS is complete, it will probably be pretty easy for you to re-implement.
Thanks for the feedback. That's good to know. At the moment I'm thinking of doing something similar. I wonder if we could automatically detect UEFI and JMP to alternate loading technique.
0x00
0b00000000
Member
Member
Posts: 50
Joined: Sun Dec 20, 2015 4:00 pm
Libera.chat IRC: 0b00000000

Re: Bootloader needs fix. See (JMP ...)

Post by 0b00000000 »

TightCoderEx wrote:
Brendan wrote:b) Some (extremely old and rare now) Compaq computers expect a boot loader to begin with a "short JMP" instruction and assume the code is not bootable if it begins with something else (e.g. a "far JMP" instruction).
A couple of other reasons to consider this is; a) Applications like HexEdit won't work right when trying to write raw data to disk. I don't believe "dd" or "partcopy" have this issue and I know the "w" command in debug.com doesn't. b) BPB only uses 60 bytes and even though in my case I don't plan on using it, but should I change my mind, it's already there.
Does the code above not being with a short JMP?

0x00
0x00
User avatar
TightCoderEx
Member
Member
Posts: 90
Joined: Sun Jan 13, 2013 6:24 pm
Location: Grande Prairie AB

Re: Bootloader needs fix. See (JMP ...)

Post by TightCoderEx »

What your using is a far jump. Not necessary but assembler doesn't complain because it's legitimate, but if you were using BPB, that would have overwritten the first two bytes of OEM name.
It is important to have a thorough understanding of real-mode segmentation as without it, this boot sector and other 16 bit code will drive you nuts.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Bootloader needs fix. See (JMP ...)

Post by intx13 »

0b00000000 wrote: Thanks for the feedback. That's good to know. At the moment I'm thinking of doing something similar. I wonder if we could automatically detect UEFI and JMP to alternate loading technique.
UEFI has a completely different bootloading mechanism: the firmware searches for a GPT partition with a PE executable with a particular name, and loads it into memory at a dynamically-determined address. However, GPT allows for a "protective" MBR for backwards compatibility, which can contain the standard 446 bytes of real mode boot code. So you can have a single disk image with a legacy bootloader and a UEFI application, if you want.
0b00000000
Member
Member
Posts: 50
Joined: Sun Dec 20, 2015 4:00 pm
Libera.chat IRC: 0b00000000

Re: Bootloader needs fix. See (JMP ...)

Post by 0b00000000 »

TightCoderEx wrote:What your using is a far jump. Not necessary but assembler doesn't complain because it's legitimate, but if you were using BPB, that would have overwritten the first two bytes of OEM name.
It is important to have a thorough understanding of real-mode segmentation as without it, this boot sector and other 16 bit code will drive you nuts.
OK,

now I'm really confused. Because I've found information elsewhere that I should not just JMP 0xoffset because I have no guarantee what state CS is in. How on earth is it going to be possible to satisfy both problems? If I set CS manually first then JMP is not the first instruction.

Also why would far jump cause the first two bytes of BPB to be overwritten? A far JMP overwrites bytes after it?

0x00
0x00
Post Reply