Develop a Bootloader In Assembly
I've already done a part of my OS in Assembly, but now I want to build a own bootloader for it too instead of using GRUB. When I was developing my test OS in Assembly I remember that I boot it like this:
org 0x7c00
bits 16
; OS Kernel Here
times 510 - ($-$$) db 0
dw 0xAA55
This I've already know. Now I 开发者_如何转开发want to use this and execute the "real" OS that will be a *.bin file written to the 2nd sector of the floppy. Then I want to know somethings
- How can I do a bootloader in Assembly to execute what will be starting on the 2nd sector of the floppy?
- I need to add anything to the Assembly source that will be placed on the 2nd sector of the floppy?
You use int 0x13
to load in the required number of sectors and jump to the location you have place the new code. There is nothing you need to do in the second stage, but you will want to make sure that you set DS
to be valid for wherever you load the code.
Example from my little OS archive:
/* BIOS loads the sectors into es:bx */
pushw $STAGE1_WORKSEG
popw %es
movw $STAGE1_OFFSET, %bx
read_stage1:
/* Try to read in a few sectors */
movb $0x2, %cl /* Sector */
movb $0x0, %ch /* Cylinder */
movb $0x0, %dh /* Head */
movb $0x0, %dl /* Drive */
movb $0x2, %ah /* BIOS read function */
/* How many sectors to load */
movb $STAGE1_SIZE, %al
int $0x13
jnc read_stage1_done
/* Reset drive */
xorw %ax, %ax
int $0x13
jmp read_stage1
read_stage1_done:
/* Perform a long jump into stage1 */
ljmp $STAGE1_WORKSEG, $STAGE1_OFFSET
call halt
halt:
/*
* Function: halt
* Synopsis: Sends the processor into a permanent halted status
* Notes:
* The only way out of this is to manually reboot
*/
hlt /* Halt the processor */
jmp halt
That's in GAS format so you'll want to reverse the operand order because it looks like you're using NASM from the times
instruction. The variable names should be self-explanatory.
If you're developing a hobby OS then http://forum.osdev.org/
is a good place to get support from others doing the same thing. It's a bit more specialised than stackoverflow and a lot of OS stuff can be quite esoteric.
While in 16-bit mode you can use the code below to load your kernel from disk into memory:
disk_load:
push dx
mov ah, 0x02
mov al, dh
mov ch, 0x00
mov dh, 0x00
mov cl, 0x02
int 0x13
jc disk_error
pop dx
cmp dh, al
jne disk_error
ret
disk_error:
mov bx, DISK_ERROR_MSG
call print_string
jmp $
DISK_ERROR_MSG db "Disk read error !", 0
load_kernel:
mov bx, MSG_LOAD_KERNEL
call print_string
mov bx, KERNEL_OFFSET
mov dh, 54
mov dl, [BOOT_DRIVE]
call disk_load
ret
精彩评论