• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

[c++] Bootsektor

Status
Für weitere Antworten geschlossen.

gollum1990

Neues Mitglied
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.
 
Werbung:
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
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 ([email protected])
;
; 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

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 <Space> 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;
}

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
};
 
Werbung:
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
Die Speicheradresse des Strings muss in dem SI-Register gespeichert werden.


N43
 
Zuletzt bearbeitet:
Status
Für weitere Antworten geschlossen.
Zurück
Oben