Page 2 of 4
Re: Bootloader fails on a real pc
Posted: Tue May 10, 2011 4:26 pm
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.
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 4:06 am
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..
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?
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 11:31 am
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?
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 11:35 am
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.
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 1:46 pm
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
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 1:59 pm
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.
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 2:06 pm
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.
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 2:09 pm
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.
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 2:15 pm
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.
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 2:24 pm
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.
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 2:28 pm
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.
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 2:34 pm
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.
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 2:42 pm
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).
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 2:52 pm
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..
Re: Bootloader fails on a real pc
Posted: Wed May 11, 2011 2:53 pm
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..