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 |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
|
09-28-2009, 02:07 PM
|
#1
|
Senior Member
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
|
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
|
|
|
09-28-2009, 03:42 PM
|
#2
|
LQ 5k Club
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
|
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.
|
|
|
09-28-2009, 08:07 PM
|
#3
|
Senior Member
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Original Poster
|
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
|
|
|
09-28-2009, 08:19 PM
|
#4
|
Senior Member
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Original Poster
|
btw you are a very helpful nice person
too bad not evreyone is like you
|
|
|
09-28-2009, 08:24 PM
|
#5
|
Senior Member
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Original Poster
|
uhoh i dont have nasm16 and rawrite2
|
|
|
09-28-2009, 11:33 PM
|
#6
|
LQ 5k Club
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
|
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.
|
|
|
09-29-2009, 12:01 AM
|
#7
|
Senior Member
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Original Poster
|
why is it 1024 bytes
when the floppy sector is 512
is that normal?
|
|
|
09-29-2009, 01:03 AM
|
#8
|
LQ 5k Club
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
|
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.
|
|
|
09-29-2009, 01:04 AM
|
#9
|
Senior Member
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Original Poster
|
does it actually boot load because it looks like it has a infinite loop at the end (jmp $)
btw did you write it?
|
|
|
09-29-2009, 01:11 AM
|
#10
|
LQ 5k Club
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
|
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.
|
|
|
09-29-2009, 01:20 AM
|
#11
|
Senior Member
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Original Poster
|
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
|
|
|
09-29-2009, 02:08 AM
|
#12
|
LQ 5k Club
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
|
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.
|
|
|
09-29-2009, 02:32 AM
|
#13
|
Senior Member
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Original Poster
|
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?
|
|
|
09-29-2009, 10:55 AM
|
#14
|
LQ 5k Club
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
|
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.
|
|
|
09-29-2009, 12:11 PM
|
#15
|
Senior Member
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Original Poster
|
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
|
|
|
All times are GMT -5. The time now is 10:41 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|