[SOLVED] Bootloader fails on a real pc

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.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader fails on a real pc

Post by DavidCooper »

OK - I've got the hex dump now

Code: Select all

00001f0 0000 0000 0000 0000 0000 0000 0000 aa55 - there's the end of sector 1
Let's now see what code's actually in the second sector:-

Code: Select all

0000200 05ea 0080 be00 800e 1ce8 e900 fffd 7453
0000210 6761 2065 2032 6168 2073 6562 6e65 6c20
0000220 616f 6564 2e64 ac00 c008 0974 0eb4 ff30... etc.
ea is a far jump instruction, jumping to 5 128 0 0 (decimal address and segment, byte by byte), landing on the "be" which is which is a load SI instruction, loading it with 800e... I don't recognise this code at all. Do you?

It then has a near call instruction (e8) calling something 28 bytes further on. When it rets from that it does a near jump (e9) 253 255 back to itself, so it enters an infinite loop running the same jump over and over again.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
Bietje
Member
Member
Posts: 100
Joined: Wed Apr 20, 2011 6:57 am

Re: Bootloader fails on a real pc

Post by Bietje »

DavidCooper wrote:OK - I've got the hex dump now

Code: Select all

00001f0 0000 0000 0000 0000 0000 0000 0000 aa55 - there's the end of sector 1
Let's now see what code's actually in the second sector:-

Code: Select all

0000200 05ea 0080 be00 800e 1ce8 e900 fffd 7453
0000210 6761 2065 2032 6168 2073 6562 6e65 6c20
0000220 616f 6564 2e64 ac00 c008 0974 0eb4 ff30... etc.
ea is a far jump instruction, jumping to 5 128 0 0 (decimal address and segment, byte by byte), landing on the "be" which is which is a load SI instruction, loading it with 800e... I don't recognise this code at all. Do you?

It then has a near call instruction (e8) calling something 28 bytes further on. When it rets from that it does a near jump (e9) 253 255 back to itself, so it enters an infinite loop running the same jump over and over again.
That last infinite loop can be the end loop to hang the cpu..

Code: Select all

jmp $
I have added a new hexdump and sources. I use vid mem for text printing now. Something strange:
  • Works great in kvm (like usual)
    When booting on a real pc, the jump fails. It prints an A + a square
It only prints the square when booting from real hardware..

edit:
I walked trough every opcode of the second stage and checked them with the intel manuals and they seem to be right. Have I over looked anything?
Attachments
testloader.zip
New sources + hexdump
(1.73 KiB) Downloaded 67 times
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader fails on a real pc

Post by DavidCooper »

Here are the 256 text screen chars, displayed 16 per row and 16 columns. There are a few different squares, so you need to look at its size and position relative to the A to work out which one it is. What was it actually meant to be displaying?
Attachments
screen chars.JPG
screen chars.JPG (21.32 KiB) Viewed 1873 times
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader fails on a real pc

Post by DavidCooper »

By the way, I can only open the hex file, so could you post the source for it here please.

Edit: I see from the hex that the second sector starts by sending a green E to the screen which should replace the A. I'll start reading the boot sector now.

Edit 2: I've read the whole thing now so I don't need the source, but print it here anyway for other people to look at. When the square appears, does it replace the A and what colour is it? Try changing the colour to 12 (decimal) to see if it appears as a red square - I want to know if the code in the second sector is running but is somehow partly corrupted after being loaded in on real hardware. Change the screen address in DI to 2 as well so that it doesn't overwrite the A.

Edit 3: I've checked every byte of it and it looks fine, but you need to put back in the bit testing to see if the load was successful so that it redoes it if there's an error. While you're at it, change the stack address to 7c00 rather than 7bfe - it'll work faster later on when you're in 32 bit mode (and it will never actually write to the byte at 7c00). What kind of device are you using to try to boot this from? I'm assuming it's still a USB flash drive. The code in this version seems to be treating it like a floppy disk, so it would be useful if someone else who does the same thing could confirm that it ought to work that way.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
Bietje
Member
Member
Posts: 100
Joined: Wed Apr 20, 2011 6:57 am

Re: Bootloader fails on a real pc

Post by Bietje »

I have run through the machine code also.. couldn't find anything I did not expect. Also I changed the stack pointer to 0x7c00. I boot using an USB flash drive and on my netbook it prints the A + a square. It seems to be ascii char 0xFE (the last one on your image). BUT if a friend of mine boots it displays just the (green) A. And when I boot with my main machine it prints the A + a newline.. :| The square is filled whiteish (the white bios interupts use, vid mem white is really white).

Edit:
The strange char being printed can be caused by the fact that I dw the magic word 55aa. And the opcode for stos(w) is.. aa. And since es still points to the vid mem offset it could be possible.. I'll test that now.

stage 1

Code: Select all

ORG 0x7C00
[BITS 16]

_start: ; entry point
	jmp 0x0:.flush
.flush:
	xor ax, ax
	mov ax, cs
	mov ds, ax
	mov es, ax
	mov ss, ax
	mov sp, 0x7C00
	mov [bootdisk], dl


.reset:
	xor ax, ax
	mov dl, [bootdisk]
	int 0x13
	jc .reset

.read:
	mov ah, 0x2
	mov al, 1 ; read some sectors
	xor cx, cx
	mov cl, 2
	xor dx, dx
	mov dl, [bootdisk]
	
	; setup buffer
	xor bx, bx
	mov es, bx
	mov bx, 0x7e00
	int 0x13
	jc .read

	test ah, ah
	jnz .reset

	cmp al, 0x1
	jne .reset

	mov ax, 0b800h
	mov es, ax
	xor di, di
	mov al, 65
	mov ah, 0xc
	stosw

	jmp 0x0:0x7e00

	bootdisk db 0

times 510 - ($ - $$) db 0
dw 0xAA55
Stage 2

Code: Select all

ORG 0x7E00
[BITS 16]
stage2:
	mov ax, 0xb800
	mov es, ax
	xor di, di
	mov al, 69
	mov ah, 0xc
	stosw
	jmp $

times 512 - ($ - $$) db 0
Last edited by Bietje on Wed May 11, 2011 2:01 pm, edited 1 time in total.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader fails on a real pc

Post by DavidCooper »

I think the white square is just something not related to your code at all, other than that it's using the values left in ES and DI after the A was written to the screen. The second sector probably isn't loading at all, but to make sure you need to put something into it (some ASCII) and try reading it from the boot sector code, sending it directly to the screen.

Are you using an old flash drive which may have a worn-out second sector with a faulty byte in it? There used to be a relatively low limit to how many times you can write to flash memory before it fails, and I've no idea how much the technology has improved since.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
Bietje
Member
Member
Posts: 100
Joined: Wed Apr 20, 2011 6:57 am

Re: Bootloader fails on a real pc

Post by Bietje »

DavidCooper wrote:I think the white square is just something not related to your code at all, other than that it's using the values left in ES and DI after the A was written to the screen. The second sector probably isn't loading at all, but to make sure you need to put something into it (some ASCII) and try reading it from the boot sector code, sending it directly to the screen.
You mean that I should define (db (DefineByte)) some ascii values in the second sector, read the second sector into memory and use a pointer to that memory to print the ascii values which i DBed?

I can almost start a shop in usb drives, so I will look for the newest and try that one.
Last edited by Bietje on Wed May 11, 2011 2:14 pm, edited 2 times in total.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader fails on a real pc

Post by DavidCooper »

Bietje wrote:The strange char being printed can be caused by the fact that I dw the magic word 55aa. And the opcode for stos(w) is.. aa. And since es still points to the vid mem offset it could be possible.. I'll test that now.
No - stosw is ab. The 55aa is in the right place in sector 1 and the far jump must jump past it.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader fails on a real pc

Post by DavidCooper »

Bietje wrote:
DavidCooper wrote:I think the white square is just something not related to your code at all, other than that it's using the values left in ES and DI after the A was written to the screen. The second sector probably isn't loading at all, but to make sure you need to put something into it (some ASCII) and try reading it from the boot sector code, sending it directly to the screen.
You mean that I should define (db (DefineByte)) some ascii values in the second sector, read the second sector into memory and use a pointer to that memory to print the ascii values which i DBed?
If that's the right way to do it with assembler, then yes. (I just write bytes directly into machine memory in the same form as it will be when it runs, and then I save the contents of memory to a storage device.)
I can almost start a shop in usb drives, so I will look for the newest and try that one.
It's certainly worth trying it.
The strange character where caused by the magic word (aa -> opcode for stos) so I set es back to zero right before I jump now.
The aa can certainly post a byte, and it's likely that the colour byte has already been set by the BIOS for that part of the screen, but I can't see how it could be run as the jump goes past it.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader fails on a real pc

Post by DavidCooper »

Another trick would be to poke some code into the memory at 7e00 from within the boot sector so that that poked code will run after the far jump if the second sector fails to load in on top of it. You could try the following set of bytes (all decimal): 191 160 128 184 0 176 142 192 184 88 14 171 - it should print a yellow X to the start of the second line of the screen.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
Bietje
Member
Member
Posts: 100
Joined: Wed Apr 20, 2011 6:57 am

Re: Bootloader fails on a real pc

Post by Bietje »

Bietje wrote:You mean that I should define (db (DefineByte)) some ascii values in the second sector, read the second sector into memory and use a pointer to that memory to print the ascii values which i DBed?.
That made my pc blink the cursor a few times and then load grub.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader fails on a real pc

Post by DavidCooper »

Bietje wrote:
Bietje wrote:You mean that I should define (db (DefineByte)) some ascii values in the second sector, read the second sector into memory and use a pointer to that memory to print the ascii values which i DBed?.
That made my pc blink the cursor a few times and then load grub.
That probably means your code to read and display it had a bug in it, so you'll have to post that now. I'm assuming the second sector's code is the same as it was apart from the ASCII stuff and the jump over it.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader fails on a real pc

Post by DavidCooper »

I've just remembered that when I looked at some of your source code on the other site, you had a table at the start of the boot sector specifying a whole lot of things such as sectors per FAT. I think that table has to be there if you're booting from a USB device. Have all your attempts to boot your netbook (or PC - I'm not sure what you said it was) been with versions with that table missing from the boot sector?

Check this thread: http://board.flatassembler.net/topic.php?t=12389 and make sure your table's correct (the important box has a slider on the right which you need to move to see all the content).
Last edited by DavidCooper on Wed May 11, 2011 2:55 pm, edited 1 time in total.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
Bietje
Member
Member
Posts: 100
Joined: Wed Apr 20, 2011 6:57 am

Re: Bootloader fails on a real pc

Post by Bietje »

DavidCooper wrote:Another trick would be to poke some code into the memory at 7e00 from within the boot sector so that that poked code will run after the far jump if the second sector fails to load in on top of it. You could try the following set of bytes (all decimal): 191 160 128 184 0 176 142 192 184 88 14 171 - it should print a yellow X to the start of the second line of the screen.
I have got this working now. Still prints the square after the X tho. So this proves that I can read and write to the memory and that there is some bug in reading the correct sector..
Bietje
Member
Member
Posts: 100
Joined: Wed Apr 20, 2011 6:57 am

Re: Bootloader fails on a real pc

Post by Bietje »

DavidCooper wrote:I've just remembered that when I looked at some of your source code on the other site, you had a table at the start of the boot sector specifying a whole lot of things such as sectors per FAT. I think that table has to be there if you're booting from a USB device. Have all your attempts to boot your netbook been with versions with that table missing from the boot sector?

Check this thread: http://board.flatassembler.net/topic.php?t=12389 and make sure your table's correct (the important box has a slider on the right which you need to move to see all the content).
So I need that table in my first sector, and an empty fat in the second sector at the end?

Edit: going to get some sleep now..
Last edited by Bietje on Wed May 11, 2011 3:21 pm, edited 2 times in total.
Post Reply