OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 25, 2024 3:24 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: From Bootloader to Kernel?
PostPosted: Wed May 24, 2006 11:00 pm 
Offline
Member
Member

Joined: Wed May 24, 2006 11:00 pm
Posts: 39
I wrote a simple (and I mean simple) kernel in C, and a simple bootloader in NASM. The bootloader is in binary format which means, no externals. So, how do I get into my kernel, if I can't call it from my bootloader.

Thanks in advance.


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Wed May 24, 2006 11:00 pm 
Offline

Joined: Fri Dec 02, 2005 12:00 am
Posts: 6
I have the same problem. I compile mine in DJGPP. What is the right way to compile in DJGPP. What switches should one use when linking with ld without it turning into a Windows executable.


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Wed May 24, 2006 11:00 pm 
Offline

Joined: Tue May 09, 2006 11:00 pm
Posts: 16
@Fear:

You have to have your bootloader load your kernel into memory and then "jmp" to the memory address you loaded it to. (You wrote it in assembly, right?) Some more info about your bootloader might help, but I don't this this should be too difficult.

@obandu:

I use COFF format for my DJGPP output. Do you need to mix in assembly as well? Even if you don't, you should read "Mixing Assembly and C" over in the howtos section. It has a good example in the beginning of what you'll need to do.
Link: http://www.osdev.com/howtos/1/index.html

More specifically, you should probably make a batch file for compiling things along these lines:

(for C only)
gcc -ffreestanding -c -o kernel.o kernel.c
ld -Ttext 0x100000 --oformat binary -o kernel.bin kernel.o

You may have to add lines for more than one file:

(for C and (N)asm)
gcc -ffreestanding -c -o mix_c.o mix_c.c
nasm -f coff -o mix_asm.o mix_asm.asm
ld -Ttext 0x100000 --oformat binary -o kernel32.bin mix_c.o mix_asm.o


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Wed May 24, 2006 11:00 pm 
Offline
Member
Member

Joined: Wed May 24, 2006 11:00 pm
Posts: 39
So, how would I load my C kernel into memory? I think it's 'int 13', but I have no idea what functions to pass it, etc.


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Wed May 24, 2006 11:00 pm 
Offline

Joined: Tue May 09, 2006 11:00 pm
Posts: 16
The primary responsibility of the bootloader is to load the rest of the things into memory. It is indeed int 13h; for a reference on this google for Ralf Brown's interrupt list. If you are just learning os programming, I would suggest that you use a ready-made bootloader. I use John Fine's. If you need protected mode for DJGPP-generated (or other 32-bit) code, use bootf02. For real mode (16-bit), I think the correct loader (for floppy) is in bootr01.zip.

Link:http://my.execpc.com/~geezer/johnfine/


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Wed May 24, 2006 11:00 pm 
Offline
Member
Member

Joined: Wed May 24, 2006 11:00 pm
Posts: 39
Wow, that was like the most useful response I could have gotten, never thought of using a prewritten bootloader. Thanks, I'll get on that now.


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Wed May 24, 2006 11:00 pm 
Offline

Joined: Tue May 09, 2006 11:00 pm
Posts: 16
Sure thing. You may wish to revisit the bootloader once you have some experience, but sectors and tracks are not the easiest things to deal with for a beginner.


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Wed May 24, 2006 11:00 pm 
Offline

Joined: Fri Dec 02, 2005 12:00 am
Posts: 6
Thanks to "osprogram". What I have been missing is the --oformat binary

The code now looks more reasonable via ms-dos debug.exe. I will now test it with real booting.


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Thu May 25, 2006 11:00 pm 
Offline
Member
Member

Joined: Wed May 24, 2006 11:00 pm
Posts: 39
Wow, I feel major stupid. I can't even do this with a premade bootsector. Either way, I don't procrastinate. Is there a resource where I can learn to load my Kernel from a binary file (no external refrences)?

_________________
The last time I wrote one of these, I put some thought in it...


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Thu May 25, 2006 11:00 pm 
Offline

Joined: Tue May 09, 2006 11:00 pm
Posts: 16
NASM sample bootsector from John Fine:
Code:
; boot12.asm  FAT12 bootstrap for real mode image or loader
; Version 1.0, Jul 5, 1999
; Sample code
; by John S. Fine  [email protected]
; I do not place any restrictions on your use of this source code
; I do not provide any warranty of the correctness of this source code
;_____________________________________________________________________________
;
; Documentation:
;
; I)    BASIC features
; II)   Compiling and installing
; III)  Detailed features and limits
; IV)   Customization
;_____________________________________________________________________________
;
; I)    BASIC features
;
;    This boot sector will load and start a real mode image from a file in the
; root directory of a FAT12 formatted floppy or partition.
;
;    Inputs:
; DL = drive number
;
;    Outputs:
; The boot record is left in memory at 7C00 and the drive number is patched
; into the boot record at 7C24.
; SS = DS = 0
; BP = 7C00
;_____________________________________________________________________________
;
; II)   Compiling and installing
;
;  To compile, use NASM
;
;  nasm boot12.asm -o boot12.bin
;
;  Then you must copy the first three bytes of BOOT12.BIN to the first three
;  bytes of the volume and copy bytes 0x3E through 0x1FF of BOOT12.BIN to
;  bytes 0x3E through 0x1FF of the volume.  Bytes 0x3 through 0x3D of the
;  volume should be set by a FAT12 format program and should not be modified
;  when copying boot12.bin to the volume.
;
;  If you use my PARTCOPY program to install BOOT12.BIN on A:, the
;  commands are:
;
;  partcopy boot12.bin 0 3 -f0
;  partcopy boot12.bin 3e 1c2 -f0 3e
;
;  PARTCOPY can also install to a partition on a hard drive.  Please read
;  partcopy documentation and use it carefully.  Careless use could overwrite
;  important parts of your hard drive.
;
;  You can find PARTCOPY and links to NASM on my web page at
;  http://www.erols.com/johnfine/
;_____________________________________________________________________________
;
; III)  Detailed features and limits
;
;   Most of the limits are stable characteristics of the volume.  If you are
; using boot12 in a personal project, you should check the limits before
; installing boot12.  If you are using boot12 in a project for general
; distribution, you should include an installation program which checks the
; limits automatically.
;
; CPU:  Supports any 8088+ CPU.
;
; Volume format:  Supports only FAT12.
;
; Sector size:  Supports only 512 bytes per sector.
;
; Drive/Partition:  Supports whole drive or any partition of any drive number
; supported by INT 13h.
;
; Diskette parameter table:  This code does not patch the diskette parameter
; table.  If you boot this code from a diskette that has more sectors per
; track than the default initialized by the BIOS then the failure to patch
; that table may be a problem.  Because this code splits at track boundaries
; a diskette with fewer sectors per track should not be a problem.
;
; File position:  The file name may be anywhere in the root directory and the
; file may be any collection of clusters on the volume.  There are no
; contiguity requirements.  (But see track limit).
;
; Track boundaries:  Transfers are split on track boundaries.  Many BIOS's
; require that the caller split floppy transfers on track boundaries.
;
; 64Kb boundaries:  Transfers are split on 64Kb boundaries.  Many BIOS's
; require that the caller split floppy transfers on track boundaries.
;
; Cluster boundaries:  Transfers are merged across cluster boundaries whenever
; possible.  On some systems, this significantly reduces load time.
;
; Cluster 2 limit:  Cluster 2 must start before sector 65536 of the volume.
; This is very likely because only the reserved sectors (usually 1) and
; the FAT's (two of up to 12 sectors each) and the root directory (usually
; either 15 or 32 sectors) precede cluster 2.
;
; Track limit:  The entire image file must reside before track 32768 of the
; entire volume.  This is true on most media up to 1GB in size.  If it is a
; problem it is easy to fix (see boot16.asm).  I didn't expect many people
; to put FAT12 partitions beyond the first GB of a large hard drive.
;
; Memory boundaries:  The FAT, Root directory, and Image must all be loaded
; starting at addresses that are multiples of 512 bytes (32 paragraphs).
;
; Memory use:  The FAT and Root directory must each fit entirely in the
; first 64Kb of RAM.  They may overlap.
;
; Root directory size:  As released, it supports up to 928 entries in the
; root directory.  If ROOT_SEG were changed to 0x7E0 it would support up
; to 1040.  Most FAT12 volumes have either 240 or 512 root directory
; entries.
;_____________________________________________________________________________
;
; IV)   Customization
;
;   The memory usage can be customized by changing the _SEG variables (see
; directly below).
;
;   The file name to be loaded and the message displayed in case of error
; may be customized (see end of this file).
;
;   The ouput values may be customized.  For example, many loaders expect the
; bootsector to leave the drive number in DL.  You could add "mov dl,[drive]"
; at the label "eof:".
;
;   Some limits (like maximum track) may be removed.  See boot16.asm for
; comparison.
;
;   Change whatever else you like.  The above are just likely possibilities.
;_____________________________________________________________________________


; Change the _SEG values to customize memory use during the boot.
; When planning memory use, remember:
;
; *)  Each of ROOT_SEG, FAT_SEG, and IMAGE_SEG must be divisible by 0x20
;
; *)  None of ROOT, FAT or IMAGE should overlap the boot code itself, or
;     its stack.  That means: avoid paragraphs 0x7B0 to 0x7DF.
;
; *)  The FAT area must not overlap the IMAGE area.  Either may overlap
;     the ROOT area;  But, if they do then the root will not remain in
;     memory for possible reuse by the next stage.
;
; *)  The FAT area and the root area must each fit within the first 64Kb
;     excluding BIOS area (paragraphs 0x60 to 0xFFF).
;
; *)  A FAT12 FAT can be up to 6Kb (0x180 paragraphs).
;
; *)  A FAT12 root directory is typically either 0x1E0 or 0x400 paragraphs
;     long, but larger sizes are possible.
;
; *)  The code will be two bytes shorter when FAT_SEG is 0x800 than when it
;     is another value.  (If you reach the point of caring about two bytes).
;
%define ROOT_SEG   0x60
%define FAT_SEG      0x800
%define IMAGE_SEG   0x1000

%if ROOT_SEG & 31
  %error "ROOT_SEG must be divisible by 0x20"
%endif
%if ROOT_SEG > 0xC00
  %error "Root directory must fit within first 64Kb"
%endif
%if FAT_SEG & 31
  %error "FAT_SEG must be divisible by 0x20"
%endif
%if FAT_SEG > 0xE80
  %error "FAT must fit within first 64Kb"
%endif
%if IMAGE_SEG & 31
  %error "IMAGE_SEG must be divisible by 0x20"
%endif

; The following %define directives declare the parts of the FAT12 "DOS BOOT
; RECORD" that are used by this code, based on BP being set to 7C00.
;
%define   sc_p_clu   bp+0Dh      ;byte  Sectors per cluster
%define   sc_b4_fat   bp+0Eh      ;word  Sectors (in partition) before FAT
%define   fats      bp+10h      ;byte  Number of FATs
%define dir_ent      bp+11h      ;word  Number of root directory entries
%define   sc_p_fat   bp+16h      ;word  Sectors per FAT
%define sc_p_trk   bp+18h      ;word  Sectors per track
%define heads      bp+1Ah      ;word  Number of heads
%define sc_b4_prt   bp+1Ch      ;dword Sectors before partition
%define drive      bp+24h      ;byte  Drive number

   org   0x7C00

entry:
   jmp   short begin

; --------------------------------------------------
; data portion of the "DOS BOOT RECORD"
; ----------------------------------------------------------------------
brINT13Flag     DB      90H             ; 0002h - 0EH for INT13 AH=42 READ
brOEM           DB      'MSDOS5.0'      ; 0003h - OEM ID - Windows 95B
brBPS           DW      512             ; 000Bh - Bytes per sector
brSPC           DB      1               ; 000Dh - Sector per cluster
brSc_b4_fat   DW      1               ; 000Eh - Reserved sectors
brFATs          DB      2               ; 0010h - FAT copies
brRootEntries   DW      0E0H      ; 0011h - Root directory entries
brSectorCount   DW      2880      ; 0013h - Sectors in volume, < 32MB
brMedia         DB      240      ; 0015h - Media descriptor
brSPF           DW      9               ; 0016h - Sectors per FAT
brSc_p_trk   DW      18              ; 0018h - Sectors per head/track
brHPC           DW      2      ; 001Ah - Heads per cylinder
brSc_b4_prt   DD      0               ; 001Ch - Hidden sectors
brSectors       DD      0           ; 0020h - Total number of sectors
brDrive      DB      0               ; 0024h - Physical drive no.
      DB      0               ; 0025h - Reserved (FAT32)
      DB      29H             ; 0026h - Extended boot record sig (FAT32)
brSerialNum     DD      404418EAH       ; 0027h - Volume serial number
brLabel         DB      'Joels disk '   ; 002Bh - Volume label
brFSID          DB      'FAT12   '      ; 0036h - File System ID
;------------------------------------------------------------------------


begin:
   xor   ax, ax
   mov   ds, ax
   mov   ss, ax
   mov   sp, 0x7C00
   mov   bp, sp
   mov   [drive], dl   ;Drive number

   mov   al, [fats]   ;Number of FATs
   mul   word [sc_p_fat]   ; * Sectors per FAT
   add   ax, [sc_b4_fat]   ; + Sectors before FAT
            ;AX = Sector of Root directory

   mov   si, [dir_ent]   ;Max root directory entries
   mov   cl, 4
   dec   si
   shr   si, cl
   inc   si      ;SI = Length of root in sectors

   mov   di, ROOT_SEG/32   ;Buffer (paragraph / 32)
   call   read_16      ;Read root directory
   push   ax      ;Sector of cluster two
%define sc_clu2 bp-2      ;Later access to the word just pushed is via bp

   mov   dx, [dir_ent]   ;Number of directory entries
   push   ds
   pop   es
   mov   di, ROOT_SEG*16

search:
   dec   dx      ;Any more directory entries?
   js   error      ;No
   mov   si, filename   ;Name we are searching for
   mov   cx, 11      ;11 characters long
   lea   ax, [di+0x20]   ;Precompute next entry address
   push   ax
   repe cmpsb      ;Compare
   pop   di
   jnz   search      ;Repeat until match

   push word [di-6]   ;Starting cluster number

   mov   ax, [sc_b4_fat]   ;Sector number of FAT
   mov   si, [sc_p_fat]   ;Length of FAT
   mov   di, FAT_SEG/32   ;Buffer (paragraph / 32)
   call   read_16      ;Read FAT

next:
   pop   bx      ;Cluster number
   mov   si, bx      ;First cluster in this sequence
   mov   ax, bx      ;Last cluster in this sequence

.0:
   cmp   bx, 0xFF8   ;End of file?
   jae   .2      ; Yes
   inc   ax      ;Last cluster plus one in sequence

   ;Look in FAT for next cluster
   mov   di, bx      ;Cluster number
   rcr   bx, 1      ;1.5 byte entry per cluster
            ;bx = 0x8000 + cluster/2
            ;c-bit set for odd clusters

   mov   bx, [bx+di+FAT_SEG*16-0x8000]
   jnc   .1
   shr   bx, 1
   shr   bx, 1
   shr   bx, 1
   shr   bx, 1
.1:   and   bh, 0xF

   cmp   ax, bx      ;Is the next one contiguous?
   je   .0      ;Yes: look further ahead
.2:   sub   ax, si      ;How many contiguous in this sequence?
   jz   eof      ;None, must be done.

   push   bx      ;Save next (eof or discontiguous) cluster
   
   mov   bl, [sc_p_clu]   ;Sectors per cluster
   mov   bh, 0      ;  as a word
   mul   bx      ;Length of sequence in sectors
.3:   mov   di, IMAGE_SEG/32 ;Destination (paragraph / 32)
   add   [.3+1], ax    ;Precompute next destination
   xchg   ax, si      ;AX = starting cluster ;SI = length in sectors
   dec   ax
   dec   ax      ;Starting cluster minus two
   mul   bx      ; * sectors per cluster
   add   ax, [sc_clu2]   ; + sector number of cluster two
   adc   dl, dh      ;Allow 24-bit result

   call   read_32      ;Read it
   jmp   short next   ;Look for more

eof:
   jmp   IMAGE_SEG:0

error:   mov   si, errmsg   ;Same message for all detected errors
   mov   ax, 0xE0D   ;Start message with CR
   mov   bx, 7
.1:   int   10h
   lodsb
   test   al, al
   jnz   .1
   xor   ah, ah
   int   16h      ;Wait for a key
   int   19h      ;Try to reboot

read_16:
   xor   dx, dx

read_32:
;
; Input:
;    dx:ax = sector within partition
;    si    = sector count
;    di    = destination segment / 32
;
; The sector number is converted from a partition-relative to a whole-disk
; (LBN) value, and then converted to CHS form, and then the sectors are read
; into (di*32):0.
;
; Output:
;    dx:ax  updated (sector count added)
;    di     updated (sector count added)
;    si = 0
;    bp, ds preserved
;    bx, cx, es modified

.1:   push   dx         ;(high) relative sector
   push   ax         ;(low) relative sector

   add   ax, [sc_b4_prt]      ;Convert to LBN
   adc   dx, [sc_b4_prt+2]

   mov   bx, [sc_p_trk]      ;Sectors per track
   div   bx         ;AX = track ;DX = sector-1
   sub   bx, dx         ;Sectors remaining, this track
   cmp   bx, si         ;More than we want?
   jbe   .2         ;No
   mov   bx, si         ;Yes: Transfer just what we want
.2:   inc   dx         ;Sector number
   mov   cx, dx         ;CL = sector ;CH = 0
   cwd            ;(This supports up to 32767 tracks
   div   word [heads]      ;Track number / Number of heads
   mov   dh, dl         ;DH = head

   xchg   ch, al         ;CH = (low) cylinder  ;AL=0
   ror   ah, 1         ;rotate (high) cylinder
   ror   ah, 1
   add   cl, ah         ;CL = combine: sector, (high) cylinder

   sub   ax, di
   and   ax, byte 0x7F      ;AX = sectors to next 64Kb boundary
   jz   .3         ;On a 64Kb boundary already
   cmp   ax, bx         ;More than we want?
   jbe   .4         ;No
.3:   xchg   ax, bx         ;Yes: Transfer just what we want
.4:   push   ax         ;Save length
   mov   bx, di         ;Compute destination seg
   push   cx
   mov   cl, 5
   shl   bx, cl
   pop   cx
   mov   es, bx
   xor   bx, bx         ;ES:BX = address
   mov   dl, [drive]      ;DL = Drive number
   mov   ah, 2         ;AH = Read command
   int   13h         ;Do it
   jc   error
   pop   bx         ;Length
   pop   ax         ;(low) relative sector
   pop   dx         ;(high) relative sector
   add   ax, bx         ;Update relative sector
   adc   dl, dh
   add   di, bx         ;Update destination
   sub   si, bx         ;Update count
   jnz   .1         ;Read some more
   ret

errmsg   db   10,"Error Executing FAT12 bootsector",13
   db   10,"Press any key to reboot",13,10,0

size   equ   $ - entry
%if size+11+2 > 512
  %error "code is too large for boot sector"
%endif
   times   (512 - size - 11 - 2) db 0

filename db   "LOADER  BIN"      ;11 byte name
   db   0x55, 0xAA      ;2  byte boot signature


This should do it for you. Compile it using "nasm -o boot12.bin boot12.asm".

Next, execute "debug". At the modified prompt, type the following sequence to put the bootsector on the floppy( you are doing things on a floppy, right?) :
n boot12.bin (return)
l 0 (return)
w 0 0 0 1 (return)

This code will load a 16-bit binary in "loader.bin" on the floppy drive and execute it. Put whatever you want into a binary file (i.e. your kernel) and the bootsector will load it for you.

The best way for you to learn to wirte a bootsector is to look at those that others have written. I'd find a good guide on floppy disk geometry and FAT12 structure, and use Ralf Brown for the guide to int 13h. Although I do think you'd be better off getting some experience in assembly and other OS programming before dabbling in bootsectors.


Last edited by osprogram on Thu May 25, 2006 11:00 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Thu May 25, 2006 11:00 pm 
Offline
Member
Member

Joined: Wed May 24, 2006 11:00 pm
Posts: 39
What do you mean by, 'Put whatever you want into a binary file'? Do you mean, put whatever I want into a binary file, and then do the above sequence to move it to the floppy, or what?


Last edited by Fear on Thu May 25, 2006 11:00 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Fri May 26, 2006 11:00 pm 
Offline

Joined: Wed May 03, 2006 11:00 pm
Posts: 3
GRUB - Grand Unified Bootloader is also a good one to use.

By the way, a great way to setup a test environment is to create a .iso containing your kernel image as well as the eltorito grub stage. Then, you can point a vmware image to boot your .iso. This enables you to quickly boot and test changes. VMWare provides an entire virtual machine, bios and all, as an app on your desktop. The commands to boot your kernel once grub is loaded are:
root (cd)
kernel = /MyKernel.bin
boot


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Sat May 27, 2006 11:00 pm 
Offline
Member
Member

Joined: Thu Jul 07, 2005 11:00 pm
Posts: 1546
if I'm correct then that source code don't work with the most recent version of nasm (don't remeber if it is 32bit or 16bit that don't work)


when i had my 16bit OS i used something called boot12.bin maybe try googling for it

_________________
My new NEW blag


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Mon May 29, 2006 11:00 pm 
Offline

Joined: Tue May 09, 2006 11:00 pm
Posts: 16
hckr: That is the source code for boot12.bin. I don't know about the compilation issues; I'll upload a working copy tonight.

Fear: By "whatever you want", I mean put your kernel (in binary format) there.


Top
 Profile  
 
 Post subject: Re: From Bootloader to Kernel?
PostPosted: Mon May 29, 2006 11:00 pm 
Offline
Member
Member

Joined: Tue Oct 26, 2004 11:00 pm
Posts: 144
Location: Australia
if you want to be nasty you can format an MS-DOS system disk and rewrite msdos.sys hehe

_________________
Two things are infinite: The universe and human stupidity. But I'm not quite sure about the universe.
--- Albert Einstein


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: awik, Google [Bot], rdos and 207 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group