add directory study
This commit is contained in:
233
study/sabre/os/files/Booting/gbootsect.txt
Normal file
233
study/sabre/os/files/Booting/gbootsect.txt
Normal file
@@ -0,0 +1,233 @@
|
||||
Bootsector authoring by Gareth Owen
|
||||
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
-=- gaz@athene.co.uk -=-
|
||||
|
||||
Requirements
|
||||
============
|
||||
During this article I assume that you have good knowledge of the
|
||||
assembly language and intel architecture.
|
||||
If not, read an assembly tutorial, they aren't hard to find...
|
||||
|
||||
Start
|
||||
=====
|
||||
|
||||
Creating your own bootsector is simpler than you may think,
|
||||
the only requirement is that the bootsector is 512 bytes long, and at
|
||||
offset 0x1FE (decimal=510), the word 0xAA55 is placed. This is the first
|
||||
thing the BIOS does when the PC boots up, it first looks on the first
|
||||
floppy drive at the first sector for 0xAA55 at the end, and if it finds it
|
||||
then it loads it into memory, and starts executing it, otherwise it trys the
|
||||
primary harddisk, and if that isn't found it just bombs out with an error.
|
||||
|
||||
You should place your boot sector at:
|
||||
Sector 1
|
||||
Cylinder 0
|
||||
Head 0
|
||||
|
||||
I recommend you start playing about with floppys first instead of your hard disk
|
||||
because the hard disk bootsector stores information about the file system if you
|
||||
are running DOS/Windows, if you overrite that, then you have just lost your
|
||||
hard disk contents :-)
|
||||
|
||||
The BIOS loads the bootsector at linear offset 0x7C00, the state of
|
||||
the registers are:
|
||||
|
||||
DL = Boot drive, 1h = floppy1, 80h = primary harddisk, etc
|
||||
CS = 0
|
||||
IP = 0x7c00
|
||||
|
||||
So instead of adding [ORG 7C00h] to the top of your file, you can add:
|
||||
|
||||
mov ax, 0x7C0
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
And that will set-up the segment registers so they point to the start of
|
||||
your bootsector..
|
||||
|
||||
Most boot sectors usually just store the boot drive, load the kernel
|
||||
from disk, and jump to it.. Some will also load protected mode.
|
||||
|
||||
Since most people find it easier looking at source code and figuring
|
||||
it out than reading documentation i have included sources for a boot
|
||||
sector and a boot sector writter.
|
||||
|
||||
Here is the bootsector...
|
||||
|
||||
;******************* START ************************
|
||||
|
||||
; Boot sector authoring example by Gareth Owen (gaz@athene.co.uk)
|
||||
; This should be accompanied with an article explaining bootsectors
|
||||
|
||||
[BITS 16] ; the bios starts out in 16-bit real mode
|
||||
[ORG 0] ; Data offset = 0
|
||||
|
||||
jmp start ; skip over our data and functions, we cannot execute data :-),
|
||||
; well, you can, but i am not held responsible for the results :)
|
||||
|
||||
; Boot sector authoring example by Gareth Owen (gaz@athene.co.uk)
|
||||
; This should be accompanied with an article explaining bootsectors
|
||||
|
||||
[BITS 16] ; the bios starts out in 16-bit real mode
|
||||
[ORG 0] ; Data offset = 0
|
||||
|
||||
jmp start ; skip over our data and functions, we cannot execute data :-),
|
||||
; well, you can, but i am not held responsible for the results :)
|
||||
|
||||
; -------------------------------------
|
||||
; Data used in the boot-loading process
|
||||
; ------------------------------------------------------------------------
|
||||
bootdrv db 0
|
||||
bootmsg db 'Gareth Owen',39,'s Boot Sector Example',13,10,0
|
||||
|
||||
rebootmsg db 'Press any key to reboot',13,10,0
|
||||
|
||||
; these are used in the processor identification
|
||||
processormsg db 'Checking for 386+ processor: ',0
|
||||
need386 db 'Sorry... 386+ required!',13,10,0
|
||||
found386 db 'Found!',13,10,0
|
||||
|
||||
whatever db 'Insert your code to do something here',13,10,0
|
||||
|
||||
;*******************************************
|
||||
; Functions we are going to use ...
|
||||
;*******************************************
|
||||
detect_cpu:
|
||||
mov si, processormsg ; tell the user what we're doing
|
||||
call message
|
||||
|
||||
; test if 8088/8086 is present (flag bits 12-15 will be set)
|
||||
pushf ; save the flags original value
|
||||
|
||||
xor ah,ah ; ah = 0
|
||||
push ax ; copy ax into the flags
|
||||
popf ; with bits 12-15 clear
|
||||
|
||||
pushf ; Read flags back into ax
|
||||
pop ax
|
||||
and ah,0f0h ; check if bits 12-15 are set
|
||||
cmp ah,0f0h
|
||||
je no386 ; no 386 detected (8088/8086 present)
|
||||
|
||||
; check for a 286 (bits 12-15 are clear)
|
||||
mov ah,0f0h ; set bits 12-15
|
||||
push ax ; copy ax onto the flags
|
||||
popf
|
||||
|
||||
pushf ; copy the flags into ax
|
||||
pop ax
|
||||
and ah,0f0h ; check if bits 12-15 are clear
|
||||
jz no386 ; no 386 detected (80286 present)
|
||||
popf ; pop the original flags back
|
||||
|
||||
mov si, found386
|
||||
call message
|
||||
|
||||
ret ; no 8088/8086 or 286, so ateast 386
|
||||
no386:
|
||||
mov si,need386 ; tell the user the problem
|
||||
call message
|
||||
jmp reboot ; and reboot when key pressed
|
||||
|
||||
; ********************************************************************
|
||||
message: ; Dump ds:si to screen.
|
||||
lodsb ; load byte at ds:si into al
|
||||
or al,al ; test if character is 0 (end)
|
||||
jz done
|
||||
mov ah,0eh ; put character
|
||||
mov bx,0007 ; attribute
|
||||
int 0x10 ; call BIOS
|
||||
jmp message
|
||||
done:
|
||||
ret
|
||||
; ********************************************************************
|
||||
getkey:
|
||||
mov ah, 0 ; wait for key
|
||||
int 016h
|
||||
ret
|
||||
|
||||
; ********************************************************************
|
||||
reboot:
|
||||
mov si, rebootmsg ; be polite, and say we're rebooting
|
||||
call message
|
||||
call getkey ; and even wait for a key :)
|
||||
|
||||
db 0EAh ; machine language to jump to FFFF:0000 (reboot)
|
||||
|
||||
dw 0000h
|
||||
dw 0FFFFh
|
||||
; no ret required; we're rebooting! (Hey, I just saved a byte :)
|
||||
|
||||
; *******************************************
|
||||
; The actual code of our boot loading process
|
||||
; *******************************************
|
||||
start:
|
||||
mov ax,0x7c0 ; BIOS puts us at 0:07C00h, so set DS accordinly
|
||||
mov ds,ax ; Therefore, we don't have to add 07C00h to all our
|
||||
data
|
||||
|
||||
mov [bootdrv], dl ; quickly save what drive we booted from
|
||||
|
||||
cli ; clear interrupts while we setup a stack
|
||||
mov ax,0x9000 ; this seems to be the typical place for a stack
|
||||
mov ss,ax
|
||||
mov sp,0xffff ; let's use the whole segment. Why not? We can :)
|
||||
sti ; put our interrupts back on
|
||||
|
||||
; Interestingly enough, apparently the processor will disable
|
||||
; interupts itself when you directly access the stack segment!
|
||||
; Atleast it does in protected mode, I'm not sure about real mode.
|
||||
|
||||
mov si,bootmsg ; display our startup message
|
||||
call message
|
||||
|
||||
call detect_cpu ; check if we've got a 386
|
||||
|
||||
.386 ; use 386 instructions from now on (I don't want to manually include
|
||||
; operand-size(66h) or address-size(67h) prefixes... it's annoying :)
|
||||
|
||||
mov si,whatever ; tell the user we're not doing anything interesting here
|
||||
call message
|
||||
call getkey
|
||||
|
||||
call reboot
|
||||
|
||||
times 510-($-$$) db 0
|
||||
dw 0xAA55
|
||||
|
||||
;******************** GBOOTSECT END *************************
|
||||
|
||||
Here is the code for writting the bootsector to a floppy disk.
|
||||
It has been compiled with DJGPP for DOS.
|
||||
It writes the file 'bootsect', onto Sector 1, Cylinder 0, Head 0 of
|
||||
the floppy drive.
|
||||
|
||||
//***************START****************
|
||||
#include <bios.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void main()
|
||||
{
|
||||
FILE *in;
|
||||
unsigned char buffer[520];
|
||||
|
||||
if((in = fopen("bootsect", "rb"))==NULL)
|
||||
{
|
||||
printf("Error loading file\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fread(&buffer, 512, 1, in);
|
||||
|
||||
while(biosdisk(3, 0, 0, 0, 1, 1, buffer));
|
||||
|
||||
fclose(in);
|
||||
}
|
||||
//*************END****************************
|
||||
|
||||
Well, if you still don't understand something, then mail me
|
||||
at gaz@athene.co.uk and i'll help you out
|
||||
|
||||
- Gareth Owen
|
||||
Reference in New Issue
Block a user