Loading C kernel

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Tom

Loading C kernel

Post by Tom »

Hello, my FritzOS has pmode set up, but how do I go to my C kernel? I'm using Linux, and my boot sector is 512 bytes, it jumps to a 2nd loader & sets up Pmode and A20. I also need to know how to use DD to put my C kernel after the asm & 2nd asm loaders.

I'd use ints but ... i'm in PMode :-\ I'm going crazy trying to choose PMode or Real Mode. I'll also doc my os development very [glow=green,2,300]VERY[/glow]( as i've been doing )well so it'll be easy for others to learn, compile, & change FritzOS.

Thank you
roswell

Re:Loading C kernel

Post by roswell »

Hi,

I have written a bootloader that seems to work as yours.

1 step : 512b of asm code
Switch to big real mode, check memory, load the second step.

2 step : 512b of asm code
load a multiboot kernel that is stored just the sector after this one.


So I create a big binary image composed of : step1+step2+oskernel.

My disk is no more readable ( no FAT ), but this is not important for me.

This system works fine. I load my C kernel several times every day ( about 900Ko of code ).

If you want me to help you, just send me a mail : [email protected], or reply to this message.

roswell
frank

Re:Loading C kernel

Post by frank »

well,
If you are in pmode, and it jumps to your second sector (your kernel)
than it is not so hard...

Just use this code as basic code:

Code: Select all

asm("jmp start");

void start()
{

 while (1)        /* hang */
 {
 }
}
and check if it hangs... if it hangs then you've loaded your kernel.
if it didn't then it'll reboot.
Compile it as binary and put it in the second sector...
I always use an install.sh for that: (which I wrote myself, oufcourse)

Code: Select all

cd boot
nasm boot.asm -f bin
dd if=boot of=/dev/disk        # put it onto /dev/disk (change disk into your disk so /dev/hda,/dev/hdb,/dev/hdc)
cd ..

cd kernel
gcc -04 kern.c
ld -o kern -Ttext 0x1000 -e 0x0  kern.o
objcopy -R .note -R .comment -S -O binary kern kern.bin
dd if=kern.bin seek=1 of=/dev/disk    # put it on the second sector (change /dev/disk to your disk)
cd ..
Change -Ttext 0x1000 to the place where you loaded it...
I use 0x1000, but perhaps you loaded it into another place...
Also I use int 0x13 for loading the kernel...

Code: Select all

 .....
 mov bx,0x1000  ; 0x1000:0x0000 :)
 ......
 int 0x13
Then I switch to pmode and jump to the kernel :)

You can check if it works in an asm kernel too:

Code: Select all

org 0x1000
bits 32
jmp bla
bla: jmp bla            ; hang
Best,
Frank Anemaet :)
Tom

Re:Loading C kernel

Post by Tom »

I did that, frank, but it rebooted my computer :o
frank

Re:Loading C kernel

Post by frank »

I did that, frank, but it rebooted my computer
That has a reason :)
The reason is one of these
1. you did not switch to pmode correct (that makes the computer reboot)
2. the jumping went wrong or the loading....

Check if it works without the pmode stuff...
so like this:

Code: Select all

org 7c00h
jmp main
main: 
           mov [drive],dl

            ; load the kernel of the disk
             mov ah,0x02
             mov al,4                        ; kernel is 4 sectors for now :)
             mov ch,0
             mov cl,0
             mov cl,00000001b       ; first sector
             mov bx,0x1000          ; memory place
             mov dl,[drive]
             int 13 

            ; then jump to the kernel
            jmp 0x0000:0x10000
 
drive db 0
times 510-($-$$) db 0
sign dw 0xAA55

The kernel should look like this:

Code: Select all

org 1000h
jmp main
main: jmp main

times 510-($-$$) db 0
Then put it onto the disk:

Code: Select all

nasm bootsector1.asm -f bin
dd if=bootsector1 of=/dev/disk
nasm kernel.asm -f bin
dd if=kernel seek=1 of=/dev/disk
If it hangs, then you jumped to your kernel.
If not, somethings wrong....

If it works, switch to pmode and load the (C?) kernel :)


uhmmm... did you switch to pmode and then do int 13h?
Tom

Re:Loading C kernel

Post by Tom »

; * FritzOS: Fritz Operating System.
; * boot.asm: Boot FritzOS
; * Copyright (C) 2002 Tom Fritz
; *
; * This program is a part of the FritzOS kernel, and may be freely
; * copied under the terms of the GNU General Public License (GPL),
; * version 2, or at your option any later version.



;********************************************************************************



; Not much Kernels are commented very well, so i'll comment this one good.

; This is the Assembly Language source code file for the FritzOS booter.
; This program is run by the BIOS, and this program must end in 0xAA55
; for the BIOS. Also this program must be 512 bytes big.

; You need Linux to compile this.

; This program must be compiled with NASM. You can find it at SourceForge.net
; To compile this boot program look at the 'INSTALLING' file.

; This will put the boot program onto floppy /dev/fd0, or A:
; Make Sure You Have A Blank Floppy In fd0 Or A: Before You Do This!
;
; The .bin part is optional, but it can let you know that file is in the
; plain binary format. The BIOS needs the program in this format.

; This part tells NASM that right here is offset 0 .
; It's not really at offset 0, but it will be after it jumps to "start".

   jmp 07C0h:start      ; Goto start

;_____________________________________________________________________________________________________________


; Here is where the boot program starts.
start:
   ; Update the segment registers
mov ax, cs      ; Copy cs into ax
mov ds, ax      ; cs->ax->ds
mov es, ax      ; cs->ax->es

   jmp Running      ; Go to the running part of the bootsector

;_____________________________________________________________________________________________________________


; This is where the boot program runs.
Running:

; Load the second stage loader.
reset:            ; Reset the floppy drive
      mov ax, 0 ;
   mov dl, 0 ; Drive=0 (=A)
    int 13h ;
      jc reset
read:
    mov ax, 1000h ; ES:BX = 1000:0000
   mov es, ax ;
    mov bx, 0 ;

   mov ah, 2 ; Load disk data to ES:BX
   mov al, 5 ; Load 5 sectors
   mov ch, 0 ; Cylinder=0
   mov cl, 2 ; Sector=2
   mov dh, 0 ; Head=0
   mov dl, 0 ; Drive=0
   int 13h ; Read!

      jc read

cli            ; Stop BIOS interrups - because PMode can't use them in this manner

; Set Protected Mode ( PMode )
mov eax, CR0         
or eax, 0x1
mov CR0, eax

; Start A20
.1:   in   al, 0x64
   test   al, 2
   jnz   .1
   mov   al, 0xD1
   out   0x64, al
.2:   in   al, 0x64
   and   ax, byte 2
   jnz   .2
   mov   al, 0xDF
   out   0x60, al

; PMode needs a jmp, so here it is
jmp pmode

;____________________________________________________________________________________________________________

; We are in protected mode here:
[bits 32]
pmode:

;    jmp 1000h:0000 ; Jump to the C kernel

; This part makes sure the bootsector is 512 bytes.

   times 510-($-$$) db 0
   dw 0xAA55

; End of boot.asm
;_____________________________________________________________________________________________________

/* kernel.c: FritzOS C Kernel
Copyright (C) 2002 Tom Fritz
*/

#define WHITE_TXT 0x07 // white on black text

unsigned int k_printf(char *message, unsigned int line); // the message and then the line #

int _start()
{
    k_printf( "HI", 1 );



   return 0;
}

unsigned int k_printf(char *message, unsigned int line) // the message and then the line #
{
char *vidmem = (char *) 0xb8000;
unsigned int i=0;

i=(line*80*2);

while(*message!=0)
{
if(*message==0x2F) // check for the next line stuff
{
*message++;
if(*message==0x6e)
{
line++;
i=(line*80*2);
*message++;
if(*message==0)
{
return(1);
};
};
*message--; // got to go back, this is just a forward slash
};
vidmem=*message;
*message++;
i++;
vidmem=WHITE_TXT;
i++;
};

return(1);
};

nasm -f bin -o boot.bin boot.asm
gcc -c kernel.c -o kernel.o
ld -Ttext=0x1000 -o kernel kernel.o -e 0x0
objcopy -R .note -R .comment -S -O binary kernel kernel.bin
dd if=boot.bin of=/dev/fd0
dd if=kernel.bin seek=1 of=/dev/fd0
frank

Re:Loading C kernel

Post by frank »

Changes are bold :)

Code: Select all

[b]org 7c00h[/b]
[b]jmp start[/b]      ; Goto start


start:
   [b] mov [drive],dl         ; (a computer can have 3 floppydisks)[/b]
 
   ; Update the segment registers
     ;   mov ax, cs      ; Copy cs into ax
     ;   mov ds, ax      ; cs->ax->ds
     ;   mov es, ax      ; cs->ax->es
     [b]; try this instead:[/b]
     [b] xor ax,ax [/b]
     [b] mov ds,ax [/b]
     ; (codesegment is already loaded)

   jmp Running      ; Go to the running part of the bootsector

; This is where the boot program runs.
Running:

; Load the second stage loader.
reset:            ; Reset the floppy drive
            mov ax, 0x00   
      [b]  mov dl, [drive]          ; Drive [/b]
            int 13h            
            jc reset
read:
           
               mov bx, 1000h
               mov ah, 0x02          ; Load disk data to ES:BX
               mov al, 5                   ; Load 5 sectors
               mov ch, 0                 ; Cylinder=0
               mov cl, 2                  ; Sector=2
               mov dh, 0                ; Head=0
               mov dl, [drive]        ; Drive=0
               int 13h                    ; Read!
               jc read

               cli                             ;  Stop BIOS interrups -
                                                ;   because PMode can't use them 
                                                ;   in this manner

               ; Load the gdtr
           [b] lgdt[gdtr][/b]          ; you didn't have a gdt
               ; Set Protected Mode ( PMode )
               mov eax, cr0         
               or eax, 1   
               mov cr0, eax
               jmp dword codesel:pmode

; Start A20
; a20line is more than this see: ;http://www.mega-tokyo.com/os/os-faq-memory.html 
; anyway, I don't know if a20 line is necessary....
; (I just folowed the steps :)))

; We are in protected mode here:
[bits 32]
pmode:
 [b]
                                                          ; load them all with 32bit sel
                mov eax,datasel
                mov ss,eax
                mov ds,eax
                mov es,eax
                mov fs,eax
                mov gs,eax 

                mov ax,0x10
                mov ss,ax
                mov esp,0xFFFF      ; maxmimum
 
                mov dl,[drive]             ; we want to know what drive in                      
                                                      ; the kernel :)
 
                 jmp dword codesel:0x1000
[/b]              

;               jmp 1000h:0000      ; Jump to the C kernel

; Global descriptor table
; this tells the comp where
; all the segments (now selectors) are
gdtr
     dw gdt_end-1
      dd gdt
gdt
nullsel equ $-gdt
gdt0
           dd 0
           dd 0
codesel equ $-gdt
          dw 0ffffh
          dw 0
          db 0
          db 09ah
          db 0cfh
          db 0h
datasel equ $-gdt
         dw 0ffffh
         dw 0h
         db 0h
         db 092h
         db 0cfh
         db 0

gdt_end

; This part makes sure the bootsector is 512 bytes.

   [b] drive db 0                           ; store the drive[/b]
   times 510-($-$$) db 0
   dw 0xAA55

; End of boot.asm
;_____________________________________________________________________________________________________

I haven't test this code, I don't have a floppydrive ::)

Code: Select all


/* kernel.c: FritzOS C Kernel
  Copyright (C) 2002 Tom Fritz
*/
asm("jmp start");

void start()
{ 
 while (1){

  }

}
should hang :)
you returned, which means it does not know where
Tom

Re:Loading C kernel

Post by Tom »

Thank You ;D FritzOS boots up and sets PMode and loads GCC FritzOS kernel 8) :)
Post Reply