OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 18, 2024 11:37 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: MBR does'nt load my kernel
PostPosted: Sun Jan 29, 2017 2:48 pm 
Offline

Joined: Sun Jan 29, 2017 2:36 pm
Posts: 10
Hello !

I'm trying to make a simple MBR wich loads a kernel. This is copied to a USB drive to be run by my PC. Here is my code :
Code:
; bootsect.asm
;
; Simple MBR
;  Loaded by the BIOS at 0000:7C00
;  Real Mode addressing
;
;  Loads the Kernel at 0x1000
;

BITS 16
org 0x0

jmp start
%include "afficher.inc"
start:

; init segments
   mov ax, 0x07C0
   mov ds, ax
   mov es, ax
   mov ax, 0x8000
   mov ss, ax
   mov ax, 0xF000
   mov sp, ax      ; stack 0x8F000 -> 0x80000
   
   mov [drv], dl   

   mov si, msgBS
   call afficher

; loading kernel at 0x1000, int 13h, f42h
load:
   mov si, msgLK
   call afficher

   mov ah, 0x42
   mov si, DAP
   mov dl, [drv]
   int 0x13
   jb load
   
   mov si, msgSK
   call afficher

   jmp dword 0x100:0x0

; data
msgBS: db "REMERY bootsect is running.", 13, 10, 0
msgLK: db "Loading kernel at 0x1000 ...", 13, 10, 0
msgSK: db "Starting Kernel ...", 13, 10, 0
drv: db 0

; Disk Address Packet for kernel loading
DAP:
   db 0x10   ; dap lenght
   db 0x0   ; unused, 0
   dw 0x1   ; number of sectors to be readed (1)
   dw 0x0   ; offset
   dw 0x100   ; segment   
   dd 0x1   ; LBA address of the kernel
   dd 0x0
   
; NOP until 510 bytes long
   times 510-($-$$) db 144
    dw 0xAA55 ; "this is a MBR"



I'm testing it with qemu and it work fine, my kernel is running perfectly but when i'm trying to run it on my computer, the MBR says "Loading kernel as 0x1000 ..." one time and then it seems that it's not doing anything. It seems that the copying process is "blocked" and I don't know why ...
Hope you will understand me (I'm French, i think you've noticed) and that you will help me finding a solution ! Thanks !


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Sun Jan 29, 2017 3:20 pm 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
I haven't reviewed the entire code, but you mention it is supposed to be an MBR, and the MBR doesn't load the kernel. The MBR also has to have a partition table at byte 0x1BE, which contains of four partition entries, each describing one partition:
Code:
partition_structure:
   .active         db 0x00      ; set to 0x80 for bootable partition
   .start_chs      db 0
            db 0
            db 0
   .type         db 0x00      ; filesystem type on this partition
   .end_chs      db 0
            db 0
            db 0
   .lba         dd 0      ; starting LBA sector
   .size         dd 0      ; size in sectors

The MBR checks through the partition table looking for an active partition; a partition which has bit 7 (value 0x80) set in the "active" flag. If so, it loads one sector referenced by the "LBA" field, to 0x0000:0x7C00 and executes it, passing the BIOS drive number in DL and a pointer to the booted partition in DS:SI. To do so, however, the MBR has to copy itself from 0x7C00 to somewhere else, to make space for the boot sector. A traditional place to put the MBR in is 0x0060:0x0000 (linear 0x600).
The loaded boot sector then saves the boot drive and the boot partition that has been passed to it by the MBR, and then it parses the required file system structures to load the kernel file or second stage bootloader, depending on your design.

Sample MBR that does everything I mentioned. Notice the partition table in the bottom.

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Sun Jan 29, 2017 3:49 pm 
Offline

Joined: Sun Jan 29, 2017 2:36 pm
Posts: 10
Ok but the code that I wrote is copied on the first sector of an USB Drive in Super Floppy mode and so it's supposed to be detected by the BIOS (and that's what happens) and loaded at 0x7C00. This part of the plan work perfectly fine (obviously because it's the job the BIOS). But then this should load a simple routine which just says "Hey, kernel is speaking !" at 0x1000, using int 0x13 function 0x42, as you can see in the code I shared. But, apparently this works fine when i'm testing it with qemu, but when i'm booting my computer with the USB Drive, it seems that the execution "stops" when it tries to copy the kernel code at 0x1000. So, do you know why ?

In fact, when i'm booting my PC from the USB Drive it displays:
REMERY bootsect is running.
Loading kernel as 0x1000 ...
_

At just wait the end of the universe.


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Sun Jan 29, 2017 4:08 pm 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
Booting from USB comes in two different flavors: floppy emulation mode and hard disk mode. There really is a CD emulation mode, but since you're not using an ISO, that is irrelevant.
Anyway, the BIOS will look at the first sector (LBA sector 0) of the USB and search for an MBR partition table, as I explained above. If an MBR partition table is present, the BIOS will emulate the USB as a hard disk, giving it boot drive number 0x80 in DL and allowing you to read/write using functions 0x42 and 0x43, respectively, and identify the drive using function 0x48.
If an MBR partition table is not present, the BIOS will emulate a floppy disk, giving you boot drive number 0x80 and allowing you to use functions 2 and 3 to read and write, respectively, and you can detect the drive geometry by using function 0x08. Then, you can convert your LBA sectors into C/H/S using this algorithm:
Code:
Temp = LBA / (Sectors per Track)
Sector = (LBA % (Sectors per Track)) + 1
Head = Temp % (Number of Heads)
Cylinder = Temp / (Number of Heads)

Since you are working in assembly, when you divide two numbers using DIV instruction, the result is stored in EAX/AX/AL and the remainder (or modulus) is in EDX/DX/DL.

My guess is that you really don't want to use a floppy drive (nobody does, seriously, it's 2017), and therefore you'll need a proper MBR to "convince" the BIOS that you can boot from a hard disk.
I've already said this in another post, but USB booting for starters isn't good, because once you get out of 16-bit mode, the BIOS's emulation wouldn't be there for you to make your life easier; instead, you'll need to write a driver for every major USB host controller (UHCI, OHCI, EHCI and xHCI) as well as a driver for the USB hub and the USB mass storage devices, with its various protocols, to ensure the broadest hardware compatibility.

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Sun Jan 29, 2017 4:28 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
Although omarrx024 is right about MBR and it's purpose, it is possible to but kernel loader code there without partitioning table (only the last two byte magic mandatory). No floppy emulation involved.
Other than that, your current memory layout limits your kernel's size in 6C00h bytes. I'd suggest to put everything in the first 64k, and load your kernel afterwards, like this:
Code:
.. 7C00h stack
7C00h..8000h loader code (512)
8000h .. your kernel

The other solution is relocating your code, that's what the original MBR does (to 600h). So in your case, keeping the starting address I'd suggest something like
Code:
..E00h stack
E00h..1000h relocated loader code
1000h.. your kernel

For loading sectors you use an lba packet, that way you won't have to worry about CHS calculation. Also you can load up to 63 sectors with one packet (maybe more on some BIOSes).


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Sun Jan 29, 2017 4:31 pm 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
bzt wrote:
Although omarrx024 is right about MBR and it's purpose, it is possible to but kernel loader code there without partitioning table (only the last two byte magic mandatory). No floppy emulation involved.

He'll still need a valid partition table to emulate a hard disk instead of a floppy disk.

bzt wrote:
For loading sectors you can use an lba packet, that way you won't have to worry about CHS calculation. Also you can load up to 63 sectors with one packet (maybe more on some BIOSes).

He'll still need to emulate a hard disk to use the packet functions, to do so which he needs a valid MBR partition table, and the limitation of the packet functions is that the disk IO operation cannot cross a segment boundary, and there no real defined value, such as 63 or 127. It just depends on the values in the "segment" and "offset" fields.

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Mon Jan 30, 2017 7:33 am 
Offline

Joined: Sun Jan 29, 2017 2:36 pm
Posts: 10
It seems that omarrx024 was right because I added a simple partition table to my MBR code, like that :

Code:
; Nothing new until here


   jmp 0x0:0x1000

; data
msgBS: db "REMERY bootsect is running.", 13, 10, 0
msgLK: db "Loading kernel at 0x1000 ...", 13, 10, 0
msgSK: db "Starting Kernel ...", 13, 10, 0
drv: db 0

; Disk Address Packet for kernel loading
DAP:
   db 0x10   ; dap lenght
   db 0x0   ; unused, 0
   dw 0x1   ; number of sectors to be readed (1)
   dw 0x1000   ; offset
   dw 0x0   ; segment   
   dd 0x1   ; LBA address of the kernel
   dd 0x0
   
; NOP until 446 bytes long
   times 446-($-$$) db 144
   
; Partition table
part1:
   db 0x80   ; active partition
   db 0xFF   ; CHS addresses set to max
   db 0xFF
   db 0xFF
   db 0x7F ; custom file system
   db 0xFF
   db 0xFF
   db 0xFF
   db 0x1   ; LBA address start of partiton
   db 0x1   ; Length of partiton in sectors
   
   
; 0x00 until 510 bytes long
   times 510-($-$$) db 0x00
    dw 0xAA55 ; "this is a MBR"



http://wiki.osdev.org/Partition_Table was my main source. It works fine with qemu.
When I'm booting my PC with the USB Drive, it seems that the kernel code is copied at 0x1000 because the MBR displays "Starting Kernel ..." but my jmp to the kernel code must be wrong or something like that because the kernel doesn't "start". I'm trying to fix this, if you have an idea of what's going wrong, share it ! :-)


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Mon Jan 30, 2017 10:51 am 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
URemery wrote:
Code:
; Partition table
part1:
   db 0x80   ; active partition
   db 0xFF   ; CHS addresses set to max
   db 0xFF
   db 0xFF
   db 0x7F ; custom file system
   db 0xFF
   db 0xFF
   db 0xFF
   db 0x1   ; LBA address start of partiton
   db 0x1   ; Length of partiton in sectors

The LBA address and length of partition in sectors are 32-bit DWORDs, and not bytes. The last two lines of your partition table should be:
Code:
   dd 1
   dd 1      ; although 1 sector (512 bytes) is small for a partition?


URemery wrote:
When I'm booting my PC with the USB Drive, it seems that the kernel code is copied at 0x1000 because the MBR displays "Starting Kernel ..." but my jmp to the kernel code must be wrong or something like that because the kernel doesn't "start". I'm trying to fix this, if you have an idea of what's going wrong, share it ! :-)

Let's have a look at the first few lines of your kernel. Your MBR loads the kernel and sets CS to 0x0000 and IP to 0x1000. Does your kernel have ORG 0x1000 at the beginning? Does it have DS and ES as 0x0000?

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Mon Jan 30, 2017 11:29 am 
Offline

Joined: Sun Jan 29, 2017 2:36 pm
Posts: 10
Ok now my MBR is launching the kernel by
Code:
jmp 0x100:0x0


And I have increased the length of the partition, it was 1 sector long just to test it.

There is the little routine that we assume to be the kernel :
Code:
; kernel.asm
;
; Simple kernel, loaded 0x1000
; Displays a message
;

BITS 16
org 0x0

jmp start
%include "afficher.inc"
start:

; init segments
   mov ax, 0x100
   mov ds, ax
   mov es, ax
; init stack
   mov ax, 0x8000
   mov ss, ax
   mov sp, 0xf000
   
; displays
   mov si, msg00
   call afficher
   
end:
jmp end
   
msg00: db "Kernel is speaking !", 13, 10, 0



Is this ok with the "jmp" instruction ?

But how can it work on qemu and do not when I'm booting my computer ? Is qemu configuration wrong or is there a "BIOS trick" ?


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Mon Jan 30, 2017 12:02 pm 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
According to your MBR, the kernel is loaded from LBA sector 1. How are you putting the kernel on that sector? How are you putting the disk image into your USB stick?
You should do something like this, replacing "X" with the name of your USB stick:
Code:
sudo dd if=mbr.bin bs=512 conv=notrunc count=1 of=/dev/sdX
sudo dd if=kernel.bin bs=512 conv=notrunc seek=1 of=/dev/sdX

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Mon Jan 30, 2017 12:30 pm 
Offline

Joined: Sun Jan 29, 2017 2:36 pm
Posts: 10
I was doing :
Code:
cat bootsect kernel /dev/zero | dd of=/dev/sdb1 bs=512 count=2


I think that it's equivalent to your method by to be sure I tried to copy the files like you and tried to boot a couple of times. The first time it worked as I have said before "Starting Kernel ..." and nothing happened. But, during the other attempts, after "Starting Kernel ...", random characters were printed on the screen and the computer beeped (there is an int to do this, is there ?) so i think that the execution does not continues at the right place in RAM.

It's really strange because with qemu, everything works fine but when i'm booting, it does something ... weird. Were can be the difference between these 2 situations ? That's the question ...

EDIT:
To test with qemu, I do :
Code:
sudo qemu-system-i386 -hda /dev/sdb1


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Mon Jan 30, 2017 12:54 pm 
Offline

Joined: Sun Jan 29, 2017 2:36 pm
Posts: 10
Ok problem solved !! Sooo stupid mistake !
I was doing
Code:
cat mbr kernel /dev/zero | dd of=/dev/sdb1 bs=512 count=2

So data was copied on the first partition of the USB stick, which starts at the 2nd sector of the disk, and so all the data was shifted 1 sector "to the right" !
By doing
Code:
cat mbr kernel /dev/zero | dd of=/dev/sdb bs=512 count=2

everything works well !

Thanks for your help ! :-)


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Tue Jan 31, 2017 7:57 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
omarrx024 wrote:
He'll still need a valid partition table to emulate a hard disk instead of a floppy disk.

Well, not on my test machine. When my code starts running, DL is 80h (so not a floppy) before the partition table is parsed or checked. But I agree there should be a PT just in case, maybe some BIOSes are looking for loadable flag (all the other information in PT is disk dependent, cannot be used as magic bytes for identification).

omarrx024 wrote:
He'll still need to emulate a hard disk to use the packet functions, to do so which he needs a valid MBR partition table, and the limitation of the packet functions is that the disk IO operation cannot cross a segment boundary, and there no real defined value, such as 63 or 127. It just depends on the values in the "segment" and "offset" fields.

No emulation needed (or more precisely it's implemented in BIOS and it's transparent from our perspective. Some BIOSes just use USB and others have separate USB-Floppy and USB-HDD options. I'm talking about USB-HDD option only).
About CHS, I can't get what you mean, sorry. The sole purpose of LBA is to have a single sector number address space and forget about CHS entirely (also meaning you can access sectors with LBA that are out of CHS addressing space on large disks). You should check for LBA presistance, although it's a very safe assumption than even old hardware has it. The limit for maximum number of sector to be read was defined by me according to my experiences on real hardware. It's not a standard or something, just my observation. But I can assure you, it has nothing to do with segments.

@URemery: well done!


Top
 Profile  
 
 Post subject: Re: MBR does'nt load my kernel
PostPosted: Tue Jan 31, 2017 8:59 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
bzt wrote:
When my code starts running, DL is 80h (so not a floppy) before the partition table is parsed or checked.

The partition table is parsed and checked by the BIOS before your code starts running.

bzt wrote:
But I agree there should be a PT just in case, maybe some BIOSes are looking for loadable flag (all the other information in PT is disk dependent, cannot be used as magic bytes for identification).

They're not using magic numbers. They're parsing the partition table, and either switching to floppy disk mode or refusing to boot at all if your partition table is invalid. Here's some of the things I've seen BIOSes check:

  • No partition starts before LBA 1
  • No partition starts or ends after the last valid LBA
  • No partition overlaps any other partition
  • CHS values match their corresponding LBA values (calculated with 255 heads and 63 sectors per track, rounding down to the last whole cylinder if necessary)
  • Exactly one partition is marked bootable


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot], Majestic-12 [Bot] and 119 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group