LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-28-2009, 02:07 PM   #1
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
How to bootload a kernel


ok, i have been writing this kernel
and i am getting ready to test it


the question is, is how do you bootload it from a diskette
its about 3000 bytes long and is run in real mode
 
Old 09-28-2009, 03:42 PM   #2
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
More information is required. There are a couple of ways that come to mind, depending on whether the diskette has a filesystem installed, or not.

If you have a filesytem, and the kernel is just a file somewhere on the filesystem, then your bootloader can find the file on disk, read all of it into memory, somewhere and then execute a jump or call to the entry point of the kernel. This requires your bootloader to have knowledge of the filesytem type, and some way of locating the file within the filesystem. You can arrange that the bootloader always looks for a standard filename at a standard place in the filesystem, or have it read some kind of configuration data.

If you do not have a filesystem on the diskette, then you would assume the kernel to occupy some fixed number of blocks at a fixed location on the disk, and again, load it into memory and execute its entry point.

With a standard PC BIOS, the BIOS will check an ordered list of bootable devices, and load the first physical sector of the device into real-mode memory at address 07C0:0000. It will then pass execution to the code loaded at that address. This would be your bootloader, or at least the first stage of it.

Here is a simple example from the archives to get you started (excerpt posted in previous thread).
Code:
;
;   Boot-n-Load
;      
;   Bootable floppy.  BIOS loads one sector, executes it.  The
;   executable loads the next level of code.
;
;   To build & use (DOS Batch file):
;       
;;  ;;            NASM16 -f bin -o bnl1.bin -l bnl1.lst bnl1.asm
;;  ;;            NASM16 -f bin -o bnl2.bin -l bnl2.lst bnl2.asm
;;  ;;            copy  /b bnl1.bin+bnl2.bin bnl.bin
;;  ;;            rawrite2 -f bnl.bin -d A -n
;

LEVEL2_SEG      equ     0x9000
LEVEL2_OFF      equ     0x0000

[BITS 16]
[ORG 0]

BnL_start:
;
;   We know the absolute address, but some BIOSes use different
;   SEG:OFF combos.  This makes sure we are using offsets that agree
;   with our ORG statement
;
    jmp     0x07c0:BnL_Go       

BnL_HelloMsg:
    db      'BnL ver 0.1',0x0d,0x0a,0

BnL_Go:
    mov     ax, cs
    mov     es, ax
    mov     ds, ax
;
;   Set up a stack
;
    cli
    mov     sp, 0xffff
    mov     ax, LEVEL2_SEG
    mov     ss, ax
    sti
    
    mov     si, BnL_HelloMsg    ; Print msg
BnL_SayHello:
    lodsb                       ; AL=memory contents at DS:SI
    
    cmp     al, 0               ; If AL=0 then done talking
    je      BnL_ResetDisk       ; go on to next step
    
    mov     ah, 0x0E            ; Print AL
    mov     bx, 7               ; text attribute/colour
    int     10h                 ; BIOS Print Char
    
    jmp     BnL_SayHello        ; Print next character
    
;
;   Load the next piece of code from sector 2, 3...
; 

BnL_ResetDisk:

    mov     ax, 0
    int     0x13            ;
    jc      BnL_ResetDisk
    
BnL_Reload:
    mov     ax, LEVEL2_SEG  
    mov     es, ax          ; SEgment address for destination
    mov     ah, 02          ; BIOS Int 13h func: Read disk
    mov     al, 4           ; sector count
    mov     bx, LEVEL2_OFF  ; Address OFFSET for destination (ES:BX --> dest)
    mov     ch, 0           ; Disk cylinder
    mov     cl, 2           ; Sector (numbered from 1)
    mov     dh, 0           ; Head
    mov     dl, 0           ; Drive

    int     0x13
    jc      BnL_Reload


    jmp     LEVEL2_SEG:LEVEL2_OFF

TIMES 510-($-$$) db 0x90
    dw      0AA55h

;
;=========================================================================
;   The following code is loaded from disk sector(s) following 
;   the sector 1 code loaded and invoked by the BIOS.
;   We jump to this code from the bootstrap loader above.
;

    mov     ax, cs
    mov     es, ax
    mov     ds, ax

    mov     si, BnL2_HelloMsg
BnL2_SayHello:
    lodsb                       ; AL=memory contents at DS:SI
    
    cmp     al, 0               ; If AL=0 then done talking
    je      BnL2_Go             ; go on to next step
    
    mov     ah, 0x0E            ; Print AL
    mov     bx, 7               ; text attribute/colour
    int     10h                 ; BIOS Print Char
    
    jmp     BnL2_SayHello       ; Print next character


BnL2_Go:
    jmp     $

BnL2_HelloMsg:
    db      'Now using level2 code', 0

times 1022-($-$$) db 0xff
dw 0AA55h
--- rod.

Last edited by theNbomr; 09-28-2009 at 11:27 PM.
 
Old 09-28-2009, 08:07 PM   #3
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Original Poster
Rep: Reputation: 231Reputation: 231Reputation: 231
the floppy actually has a custom file system on it
but anything under sector #500 is empty and fine for raw kernel and boot loader
 
Old 09-28-2009, 08:19 PM   #4
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Original Poster
Rep: Reputation: 231Reputation: 231Reputation: 231
btw you are a very helpful nice person
too bad not evreyone is like you
 
Old 09-28-2009, 08:24 PM   #5
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Original Poster
Rep: Reputation: 231Reputation: 231Reputation: 231
uhoh i dont have nasm16 and rawrite2
 
Old 09-28-2009, 11:33 PM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
You can get nasm for DOS or Linux. If you are using DOS, you can get rawrite, which performs essentially what you would use dd for in Linux.

BTW, the code I posted was originally broken into two separate source code modules, as a test that the two object modules could be installed and operated as separate entities, just like a a bootloader is supposed to work. In the real world, the second half, which is loaded by the first half, would be either the kernel itself, or a smarter piece of bootloader code, which is what grub does.

Your questions bring on a bit of nostalgia. Happy to be able to help.

--- rod.

Last edited by theNbomr; 09-28-2009 at 11:38 PM.
 
Old 09-29-2009, 12:01 AM   #7
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Original Poster
Rep: Reputation: 231Reputation: 231Reputation: 231
why is it 1024 bytes
when the floppy sector is 512
is that normal?
 
Old 09-29-2009, 01:03 AM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
No reason, really. It was somewhat of an experiment, so I probably chose some number that was merely more than a single sector. I think 'normal' is just whatever way you choose. Bootloaders are a bit of an esoteric subject.
--- rod.
 
Old 09-29-2009, 01:04 AM   #9
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Original Poster
Rep: Reputation: 231Reputation: 231Reputation: 231
does it actually boot load because it looks like it has a infinite loop at the end (jmp $)
btw did you write it?
 
Old 09-29-2009, 01:11 AM   #10
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Yes, it goes into an infinite loop. The second half is simply a stub with a message displayed to prove that the code is invoked. As I said before, in a real scenario, you would put your kernel image there, or a smarter part of the bootloader.

Yes, I wrote it.

--- rod.

Last edited by theNbomr; 09-29-2009 at 10:57 AM.
 
Old 09-29-2009, 01:20 AM   #11
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Original Poster
Rep: Reputation: 231Reputation: 231Reputation: 231
ok,
since i am a newbie when it comes to bootloading
so when you have time can you guide me thru it?
i am really not trying to be a pain i am just not good at pre boot stuff
Quote:
outhouse
A place to retreat for quiet contemplation for as long as you can hold your breath.
"Damn! I went to the outhouse because I THOUGHT I had to pinch a loaf.."
just had to do it
 
Old 09-29-2009, 02:08 AM   #12
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Well, it's simple really.
The code makes a jump that loads the code segment register, sets up a proper stack, and then enters a loop printing characters until it reaches the terminating null byte (like a C string). It then loads two segments from the disk, just like you've written your code to do. The address of the buffer that the BIOS puts the two sectors of data into is the same as the target entry point which the bootloader uses to execute the second stage of booting; message is printed, and then enters an infinite loop. Remove the code following the comment line

;
;=========================================================================
; The following code is loaded from disk sector(s) following '

and insert your kernel with entry point at byte 0 (will have to contain position independent code). The two modules can be concatenated on disk using the batch file fragments in the comments, or with dd if you use Linux.

--- rod.

Last edited by theNbomr; 09-29-2009 at 02:09 AM.
 
Old 09-29-2009, 02:32 AM   #13
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Original Poster
Rep: Reputation: 231Reputation: 231Reputation: 231
will this be ok to start the kernel?:
Code:
    .MODEL TINY
    .CODE
    extrn _main:far

START:
jmp _main
END START
will it find the entry point?
 
Old 09-29-2009, 10:55 AM   #14
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
In general, yes. It depends on what assembler you use. Various assemblers use various types of assembler directives, but the principle of your code looks right to me. One issue may be convincing the linker that your small bit of code is loaded first in the order, with an entry point at 0000. Not too sure what influence you get with that, and I'm sure it depends on what toolchain you use.
--- rod.
 
Old 09-29-2009, 12:11 PM   #15
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Original Poster
Rep: Reputation: 231Reputation: 231Reputation: 231
heres how i do it:
tasm run.asm
tlink /n run.obj+kernel.obj
note: "/n" means do not use stanrard libraries during linking
i will try the bootloader again
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How can I tell which bootload is in use? thekillerbean Linux - General 4 02-06-2007 10:26 PM
LXer: Howto: build Linux kernel module against installed kernel w/o full kernel source tree LXer Syndicated Linux News 0 09-03-2006 08:21 PM
Kernel 2.4 in Zipslack (Waring: unable to open an initial console | Kernel Panic...) kurtamos Linux - General 2 05-10-2006 12:58 PM
Bootload problem lilo/grub neorion Mandriva 5 08-27-2004 08:24 PM
Please help: bootload on floppy ffang Linux - Newbie 2 08-27-2003 12:39 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:41 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration