[c++] Bootsektor

Hallo Forum,

ihr kennt es ja lle bei den Betriebsystemem, ´den Bootsektor.

Jetzt wollt ich fragen, ob es Tutorials dazu gibt, beispielsweise, wenn ich eine Ausgabe erzeugen will wie Hello World oder sowas beim Starten des PCS. Kennt da einer eine interresannte Seite.

Hallo,

C++ kannste da vergessen. Aber in ASM geht das wunderbar. Auf Diskette ist das am einfachsten. Da muss nur die Bootsignatur 0xAA55 in den Bootsektor geschrieben werden, dann wird der Sektor vom BIOS ausgeführt.

Beispiel:[code]Begin:
CLI ; disable interrupts

  MOV AX, 0x7C0           ; and prepare registers
  MOV DS, AX
  MOV ES, AX
  MOV FS, AX
  MOV GS, AX

  MOV AX, 0x9000           ; prepare stack
  MOV SS, AX
  MOV SP, 0xFFFF

  STI 

  ; place your code here

  TIMES 510-($-$$) DB 0
  DW 0xAA55                     ;boot signature[/code]Ist ein Auszug aus meinem Bootloader, der komplette Code ist auch auf meiner Seite.

Die Textausgabe geht dann z.B. über Interrupt 10h.

Gute Seiten zu dem Thema:
http://www.lowlevel.net.tc (Deutsch)
http://www.osdev.org (Englisch)

N43

Hallo N43, ich habe folgendes gefunden:
BOOTSEC.ASM
[php]
;
; BOOTSEC.ASM
; This program cannot be larger than 512 bytes, because this is
; the size of one sector.
;
; Copyright (c) 1997 by Michael Neumann (neumann@s-direktnet.de)
;
; To create BOOTSEC.H:
; ==> TASM BOOTSEC.ASM
; ==> TLINK BOOTSEC
; ==> EXE2HEXC BOOTSEC.EXE BOOTSEC.H
;
; ==> change in BOOTSEC.H ‚xxxxxx‘ to ‚bootbuf‘
; ==> compile MK_BOOT.CPP and execute it with an
; formatted disk in drive A
;

; If BIOS has load itself into memory and had check all hardware,
; it loads the first physical sector from A: or from C: into memory
; at the location 0000:7C00, and starts at this point.
; Registers:
; DL = bootdrive
; CS = 0
; SS = 0
; (E)IP = 7C00h
; (E)SP = 7C00h
;

OFFS = 7C00h

; You have to add OFFS or 7C00h whenever an offset is used.
; For example:
; normal: mov bx,OFFSET Message
; in bootsector: mov bx,OFFS+OFFSET Message

; I first tryed to do this by writing ORG 7C00h, but this is a big
; error, because the created EXE-file is larger than 32K
; (normaly less than 1K), and the most of the 32K are zeros.

CODE SEGMENT
ASSUME CS:CODE,DS:CODE
ORG 00h
sti
cld
push cs
pop ds

; load es:di with 0B800h:0000h (text-screen memory)
mov di,0B800h
mov es,di
xor di,di

; clear the screen
mov cx,2000 ; 80*25 words
mov ax,2700h+’ ’ ; green-white, space
rep stosw

mov si,OFFS+OFFSET OsMsg
mov ah,1Fh ; background blue
xor di,di ; destination

; writes text
@@begin:
lodsb
or al,al
jz short @@ende
stosw
jmp short @@begin
@@ende:

; wait for key
xor ax,ax
int 16h

OsMsg DB ‚LCOS Version 1.00 - Little Coders Operating System Cpr(c) 1997 by Little-Coders‘,0

CODE ENDS

END
[/php]

MK_BOOT.CPP
[php]
int Versuche, i;
union REGS regs;
struct SREGS sregs;

#include „bootsec.h“ // this is the program which will be written
// to the bootsector

void DiskReset()
{
regs.h.ah = 0;
regs.h.dl = DISK_DRIVE;
int86( 0x13, &regs, &regs );
}

int WriteSektors( BYTE anz, BYTE drive, BYTE seite, BYTE seknum, BYTE spur, char *buf)
{
Versuche = ANZ_VERSUCHE;
do {
regs.h.ah = 3;
regs.h.al = anz;
regs.h.dl = drive;
regs.h.dh = seite;
regs.h.cl = seknum;
regs.h.ch = spur;
regs.x.bx = FP_OFF( buf );
sregs.es = FP_SEG( buf );
int86x( 0x13, &regs, &regs, &sregs );
if( regs.x.cflag )
{
DiskReset();
–Versuche;
if( Versuche == 0 ) return -1;
}
else Versuche = 0;
} while( Versuche != 0 );
return 0;
}

void main()
{
cout << „Create a bootsector in drive A [1.44 HD].“ << endl <<
„Press to create or any other key to cancel.“ << endl;

if( getch() != ’ ’ )
{
cout << „Abort creating bootsector!!!“ << endl;
return;
}

cout << „Writing bootsector…“;
if( WriteSektors( 1, DISK_DRIVE, 0, 1, 0, bootbuf ) == -1 )
{
cout << " Error!" << endl;
return;
}
cout << " ready." << endl;
cout << endl << „Please reboot your computer with the disk in drive A.“ << endl;
}

[/php]

und das hier:
BOOTSEC.H
[php]
unsigned char bootbuf[119] =
{
0xFB, 0xFC, 0x0E, 0x1F, 0xBF, 0x00, 0xB8, 0x8E, 0xC7, 0x33, 0xFF, 0xB9,
0xD0, 0x07, 0xB8, 0x20, 0x27, 0xF3, 0xAB, 0xBE, 0x26, 0x7C, 0xB4, 0x1F,
0x33, 0xFF, 0xAC, 0x0A, 0xC0, 0x74, 0x03, 0xAB, 0xEB, 0xF8, 0x33, 0xC0,
0xCD, 0x16, 0x4C, 0x43, 0x4F, 0x53, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6F, 0x6E, 0x20, 0x31, 0x2E, 0x30, 0x30, 0x20, 0x2D, 0x20, 0x4C, 0x69,
0x74, 0x74, 0x6C, 0x65, 0x20, 0x43, 0x6F, 0x64, 0x65, 0x72, 0x73, 0x20,
0x4F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x53, 0x79,
0x73, 0x74, 0x65, 0x6D, 0x20, 0x20, 0x43, 0x70, 0x72, 0x28, 0x63, 0x29,
0x20, 0x31, 0x39, 0x39, 0x37, 0x20, 0x62, 0x79, 0x20, 0x4C, 0x69, 0x74,
0x74, 0x6C, 0x65, 0x2D, 0x43, 0x6F, 0x64, 0x65, 0x72, 0x73, 0x00
};
[/php]

Hallo,

das C++ Programm schreibt lediglich den Inhalt von bootbuf in den ersten Sektor einer Diskette. Der Code, der dann ausgeführt wird ist der der ASM-Datei.

Wenn du entsprechenden Aufwand betreibst kannst du auch C-Code im Bootloader verwenden. Nur hast du lediglich 512 Byte zur Verfügung.

Der Bootloader lädt in der Regel einen C-Kernel. Manche schreiben ihn auch in C++ oder Pascal. Du musst dann aber selber die main() Funktion aufrufen. Sonst gibt das mit allerwahrscheinlichkeit einen Absturz.

Zum Textausgeben: Du befindest dich nach dem Starten des PCs im RealMode. Hast also Zugriff auf alle BIOS-Interrupts (nicht auf den DOS-Interrupt 21h). Das heißt du kannst Text nicht einfach ausgeben, sondern musst dich um die Ausgabe jedes einzelnen Zeichens kümmern.

Den folgenden Code verwende ich in meinem Bootloader, ist aber eher schwer zu verstehen, wenn man kein ASM kann.

[code] WriteString:

  PUSHA                      ; save registers

.WLoop:

  LODSB                      ; get next charackter
  OR AL, AL                  ; end of string reached? (AL == 0)
  JZ SHORT .DONE               ; if true then jump
  MOV AH, 0x0E               ; print charackter
  MOV BH, 0x00
  MOV BL, 0x07
  INT 0x10                   ; using INT 10h
  JMP SHORT .WLoop           ; next charackter

.DONE:

  POPA                       ; restore all registers
  RET                        ; return[/code]Die Speicheradresse des Strings muss in dem SI-Register gespeichert werden.

N43