load & execute next sector after bootsector

Programming, for all ages and all languages.
bilsch01
Member
Member
Posts: 42
Joined: Sat Dec 19, 2015 10:48 am

load & execute next sector after bootsector

Post by bilsch01 »

The program I have in the boot sector (sector 1) of the first partition is in file boot1.s below. I intend it to be loaded in memory at 7c00:0000, and for it to load the program in kern1.asm (in sector 2 of the first partition) to memory at 7e00:0000 and jump to it. I assembled and linked these two as follows:

as boot1.s -o boot1.o
nasm -f elf kern1.asm -o kern1.o
ld --oformat binary boot1.o kern1.o -o kernel1.bin

I wrote the resulting file (kernel1.bin) to the first 2 sectors of the
first partition with the following command line:

dd if=/sda5/home/bilsch/jinx/kernel1.bin count=2 of=/dev/sda1 count=2

boot1.s should print 'ABCD' if int 0x13 ah=0x42 returns cf=0. I intend it to also set up the 'disk address packet' at 7c00:0x100, and run Int 0x13 ah=0x42 (read sectors), and then execute the code from sector 2 via a far call to 07e0:0000. The code from sector 2 should print '123'. If everything goes as planned the result should be 'ABCD123'. But when I boot the partition it just prints ABCD and stops. The fact that the 'D' prints indicates that int 0x13 was successful. I think the far call does not reach the code of kern1 but I can't figure why. Maybe specifying lba sector 2 is wrong, though the command line should write kernel1.bin to the first two sectors of partition 1.

I have verified that the ELF header of kern1.o is not linked into the resulting kernel1.bin, and that the code of kern1 begins at 0x200 of kernel1.bin as it should.

QUESTION: how to load the program from sector 2 and jump to it?

Thanks. Bill S.

boot1.s is as follows:
<code>
.code16
.section .text
.global _start

_start:
push %cs
pop %ds
push %ds
pop %ss
movw $0x7bff, %sp
movw $0x0e41, %ax #A
int $0x10
movw $0x0e42, %ax #B
int $0x10
movw $0x0e43, %ax #C
int $0x10
movw $0x100, %si #offset of buffer
movw $0x10, (%si) #buffer size
movw $1, 2(%si) #one sector

movw $0x0000, 4(%si) #offset
movw $0x07e0, 6(%si) #segment

movw $64, 8(%si) #llba 2 in quadword
movw $0, 10(%si) # mbr=lba0, this=lba1, read=lba2
movw $0, 12(%si)
movw $0, 14(%si)

movb $0x42, %ah #extended read
movb $0x80, %dl #drive number
int $0x13
jc .Lhang #CF=1=failed
movb $0xe, %ah
movb $0x44, %al #D
int $0x10 #CF=0=success
lcall $0x07e0,$0x0000
.Lhang:
jmp .Lhang

***********************************************************
kern1.asm is as follows:

bits 16
SECTION .text

mov ax, 0x07e0
push ax
pop cs

mov ax, 0x0e31 ;1
int 0x10
mov ax, 0x0e32 ;2
int 0x10
mov ax, 0x0e33 ;3
int 0x10
jmp $ ;jmp here infinite loop
</code>
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: load & execute next sector after bootsector

Post by Octocontrabass »

bilsch01 wrote:I intend it to be loaded in memory at 7c00:0000, and for it to load the program in kern1.asm (in sector 2 of the first partition) to memory at 7e00:0000 and jump to it.
Your code and this description do not agree. Which is correct?

It looks like you don't understand how segment:offset addressing works. Can you tell me what you get when you convert those to linear addresses?
bilsch01 wrote:as boot1.s -o boot1.o
nasm -f elf kern1.asm -o kern1.o
Why are you using two different assemblers?
bilsch01 wrote:dd if=/sda5/home/bilsch/jinx/kernel1.bin count=2 of=/dev/sda1 count=2
Why are you testing your code by overwriting the hard disk on your PC? Are you sure /dev/sda1 starts at LBA 1 and not somewhere else?
bilsch01 wrote:movw $0x7bff, %sp
Your stack is not aligned correctly, and probably also not where you think it is.
bilsch01 wrote:movw $64, 8(%si) #llba 2 in quadword
Does 64 equal 2? Does /dev/sda1 actually start at LBA 63?
bilsch01 wrote:movb $0x80, %dl #drive number
You shouldn't hard-code the drive number.
bilsch01 wrote:pop cs
Which CPUs understand this instruction?
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: load & execute next sector after bootsector

Post by onlyonemac »

Octocontrabass wrote:
bilsch01 wrote:pop cs
Which CPUs understand this instruction?
Does that code even assemble???

EDIT: I see he's got Linux running on his 8086.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: load & execute next sector after bootsector

Post by Schol-R-LEA »

@blisch1: Oh, and FYI: you need to use the square-bracketed BBcode tags for the CODE blocks in your messages, not HTML/XML style tags. In order to minimize the risks of malicious script injection, nearly all message boards trap any HTML tags submitted through the editor, and usually escape the angle brackets into the HTML entity forms. They usually have some simplified (and somewhat more secure) markup format to allow the users to add formatting; in PHPBB, which this forum uses, the markup language is BBcode, which looks like:

Code: Select all

[code]My Code Here
    More Code Here
    Even More Code Here
[/code]

You should be still able to go back and edit the post, and I recommend doing so. Now, this is the sort of thing almost everyone gets wrong the first time, and formatting is not tremendously important for assembly code, so it's no big deal, really, but please keep this in mind for the future. I also recommend getting familiar with both BBcode and Markdown, as those are the two most widely used forum markup languages right now.

(yeah, I know, I know, but Markdown is popular for some reason, and it usually works well enough in non-technical fora. Besides, almost every complaint I ever heard about it was regarding the Discourse implementation of Markdown, and DiskHorse is so bad in general that it makes the Bibby Jebus cry - there are several reasons why the nickname 'DiskHorse' is one of the few pejoratives applied to Discourse that I could post here without the mods deleting it, with Jeff Atwood himself being #1 on the list with a bullet. While the project was overly ambitious and tried to do too many new things at once, most of those issues could have been fixed had Jeff not been so stubbornly pigheaded in refusing to listen to users' complaints and bug reports; but it was his high-handed insistence on holding, and abusing, admin privileges on every site using his software on the grounds of 'maintaining a civilized discourse' that really pushed it into unmitigated disaster territory. If @wood had set out to create an object lesson in how not to manage and maintain publicly facing software, well, mission accomplished.)
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
bilsch01
Member
Member
Posts: 42
Joined: Sat Dec 19, 2015 10:48 am

Re: load & execute next sector after bootsector

Post by bilsch01 »

Thanks for your comments. I made changes as you suggested. I got rid of GAS. File boot1.s is now bootn1.asm, assembled with NASM. I no longer link the sector 1 file with the sector 2 file, I have two binary files: bootn1.bin (in the first sector of the first partition1) and kern1.bin (in the second sector). bootn1.bin prints 'ABC' and if the int 13 call is successful it also prints 'D''. It then should read file kern1.bin from disk and load it at 07e0:0000 and jump to it and execute it. kern1.bin should print '123'. If everything works right the result should be 'ABCD123'. But it prints 'ABCD' and stops. Do you have suggestions for what I should do? The new programs are listed below. The command lines for writing them to disk are:

dd if=/mnt/sda5/home/bilsch/jinx/bootn1.bin count=1 of=/dev/sda1 count=1
dd if=/mnt/sda5/home/bilsch/jinx/kern1.bin count=1 of=/dev/sda1 seek=1 count=1

bootn1.asm is as follows:

Code: Select all

bits 16
section .text
global _start

_start:

push	cs
pop	ds
push	ds
pop 	ss
mov 	sp,	0x7c00

mov	ax,		0x0e41	;A
int	0x10
mov	ax,		0x0e42	;B
int	0x10
mov	ax,		0x0e43	;C
int	0x10
mov	si,		0x100	;offset of buffer
mov	word [si],	0x10	;buffer size
mov	word [si+2],	1	;one sector

mov	word [si+4],	0x0000	;offset
mov	word [si+6],	0x07e0	;segment

mov	word [si+8],	2	;lba 2 in quadword
mov	word [si+10],	0	; mbr=lba0, this=lba1, read=lba2
mov	word [si+12],	0
mov	word [si+14],	0

mov	ah,		0x42	;extended read
;  dl is unchanged since start - set by BIOS
int	0x13
jc	Lhang			;CF=1=failed
mov	ax,		0x0e44	;D  CF=0=success
int	0x10		
call 	0x07e0:0x0000		;far call
Lhang:
jmp Lhang
times 510-($-$$) db 0
dw 0xAA55

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

kern1.bin is as folows:

bits 16
org 0x7e00
SECTION .text 
; segment regs were set in calling program, int 13 loads this at 07e0:0000
mov ax,0x0e31	;1
int 0x10
mov ax,0x0e32	;2
int 0x10
mov ax,0x0e33	;3
int 0x10

   jmp $		;jmp here infinite loop
 
times 512 -($-$$) db 0
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: load & execute next sector after bootsector

Post by Schol-R-LEA »

Do you mind me asking how you intend to determine if this is working correctly or not? Without some sort of output, it really isn't easy to tell unless you step through it in an emulator's debugger.

This reminds me, one of the many projects I have been putting off is cleaning up Verbum and getting it to the point where it actually does work with FAT12; I keep meaning to go back to it but I haven't done much with it in about ten years aside from moving it from Subversion to git and putting it on Github. Getting some additional eyes on it would help, too.
Last edited by Schol-R-LEA on Mon Apr 18, 2016 9:23 am, edited 2 times in total.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: load & execute next sector after bootsector

Post by Octocontrabass »

bilsch01 wrote:

Code: Select all

push	cs
pop	ds
push	ds
pop 	ss
Did you write the MBR? If not, you shouldn't rely on CS, because it could contain any value.
bilsch01 wrote:

Code: Select all

; mbr=lba0, this=lba1, read=lba2
Have you confirmed that /dev/sda1 starts at LBA 1 and not somewhere else?
bilsch01 wrote:

Code: Select all

call 	0x07e0:0x0000		;far call

Code: Select all

org 0x7e00
These two lines disagree with each other. Do you know why?
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: load & execute next sector after bootsector

Post by iansjack »

Your org directive in the second program is incorrect. It should be org 0x0. But the program is so simple that that should make no difference.

You seem to be loading the 3rd sector, not the second one.

Moral; run this under a debugger and look at what is actually loaded.

You talk about the "first partition". Is your drive actually partitioned? (Edit: Yes, it looks like you are dealing with a partitioned disk - or at least think you are - which explains the 2nd/3rd sector business. But in that case the first partition almost certainly doesn't start immediately after the MBR. A disk editor will let you check this.)
bilsch01
Member
Member
Posts: 42
Joined: Sat Dec 19, 2015 10:48 am

Re: load & execute next sector after bootsector

Post by bilsch01 »

Octocontrabass wrote:
bilsch01 wrote:

Code: Select all

push	cs
pop	ds
push	ds
pop 	ss
Did you write the MBR? If not, you shouldn't rely on CS, because it could contain any value.

I hadn't thought about it. The MBR code could be written by any of a number of utilities, but 'they' say the code jumps to 7c00 - I assumed that was standard PC rule everybody follows and that CS would be set accordingly. What code is legal for setting CS? Apparently not pop CS. Not mov cs,ax. What is it?
bilsch01 wrote:

Code: Select all

; mbr=lba0, this=lba1, read=lba2
Have you confirmed that /dev/sda1 starts at LBA 1 and not somewhere else?

Now that you mention it, I realize it starts at CHS 0,1,1 = lba 63. I see that is a problem with my code.
bilsch01 wrote:

Code: Select all

call 	0x07e0:0x0000		;far call

Code: Select all

org 0x7e00
These two lines disagree with each other. Do you know why?
I don't understand why. (07e0 times '16')=7e00. 7e00 + 0000 = 7e00. Doesnt org 7e00 mean add 7e00 to all the labels? That's what I need to do, isn't it? Please explain whats wrong.
bilsch01
Member
Member
Posts: 42
Joined: Sat Dec 19, 2015 10:48 am

Re: load & execute next sector after bootsector

Post by bilsch01 »

iansjack wrote:Your org directive in the second program is incorrect. It should be org 0x0. But the program is so simple that that should make no difference.

How will it know it is to be running at 7e00? Is that because I said to load it there with int 13, ah=42?

You seem to be loading the 3rd sector, not the second one.

Moral; run this under a debugger and look at what is actually loaded.

I've not had much luck getting gdb to run in qemu. That's all I tried so far.

You talk about the "first partition". Is your drive actually partitioned? (Edit: Yes, it looks like you are dealing with a partitioned disk - or at least think you are - which explains the 2nd/3rd sector business. But in that case the first partition almost certainly doesn't start immediately after the MBR. A disk editor will let you check this.)
Cam you tell me a good one that runs in linux? I tried LDE - I cant get meaningful display with LDE.
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: load & execute next sector after bootsector

Post by Combuster »

bilsch01 wrote:I don't understand why. (07e0 times '16')=7e00. 7e00 + 0000 = 7e00. Doesnt org 7e00 mean add 7e00 to all the labels? That's what I need to do, isn't it? Please explain whats wrong.
So your segment is 07e0 and adds 7e00 to everything, and you have an org that adds 7e00 to all the labels. What is two times 7e00?
"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
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: load & execute next sector after bootsector

Post by iansjack »

bilsch01 wrote:Cam you tell me a good one that runs in linux?
For pure assembler stuff like this, debugging right from boot, I would use SimNow ( http://developer.amd.com/tools-and-sdks ... simulator/ ) Once you do things properly and write your OS in C you need gdb. It's very easy to get this working with qemu.
glauxosdever
Member
Member
Posts: 501
Joined: Wed Jun 17, 2015 9:40 am
Libera.chat IRC: glauxosdever
Location: Athens, Greece

Re: load & execute next sector after bootsector

Post by glauxosdever »

Hi,

bilsch01 wrote:I don't understand why. (07e0 times '16')=7e00. 7e00 + 0000 = 7e00. Doesnt org 7e00 mean add 7e00 to all the labels? That's what I need to do, isn't it? Please explain whats wrong.
It seems you haven't understood what does the org directive do. It specifies the origin of the offset, not the segment, nor segment:offset. In other words, it specifies at what offset is the first byte of the loaded binary, so the offsets of respective labels are calculated correctly.

So, if you want to load at 0x7E00:
  • Either set segments to 0x07E0 and the offset of origin to 0x0000;
  • Either set segments to 0x0000 and the offset of origin to 0x7E00 (recommended).
The above list applies both to the far call and the program that is to be loaded.


Regards,
glauxosdever
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: load & execute next sector after bootsector

Post by onlyonemac »

bilsch01 wrote:I don't understand why. (07e0 times '16')=7e00. 7e00 + 0000 = 7e00. Doesnt org 7e00 mean add 7e00 to all the labels? That's what I need to do, isn't it? Please explain whats wrong.
You're correct that "org 7e00" means "add 7e00 to all the labels". But the labels are relative to your segment register, so "org" should be used to set the offset of the labels relative to the segment register. In other words, if your code starts at 7e00 and you set the segment register to 07e0 (i.e. a memory address of 7e00), then the instruction pointer is zero when it points to the first instruction in your code, so "org" should be zero; if, say, your code starts at 7e00 and you set the segment register to 07c0 (say you left it as it was from the first sector) then "org" should be 0200, because the code starts at an offset of 0200 from the address pointed to by the segment register.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: load & execute next sector after bootsector

Post by onlyonemac »

Octocontrabass wrote:
bilsch01 wrote:
bilsch01 wrote:

Code: Select all

; mbr=lba0, this=lba1, read=lba2
Have you confirmed that /dev/sda1 starts at LBA 1 and not somewhere else?
Hint: it probably doesn't.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Post Reply