Home arrow Forums
OSDEV Forums  


hazelnoot
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
16 bit x86 c kernel - 2006/03/09 14:19 hi!

i have a little problem with my "os":
i have written a 16 bit bootloader what loads a 16 bit code! this bootloader is working! i have tested it with a asm kernel! now bcc have generated me the following 16 bit asm code:
(c code:
int main(){
char *text = "Hi I am the Railex Kernel";
char *vidMem = (char*) 0xA800;

while(*text){
*vidMem = *text;
*vidMem++;
*vidMem = 7;
*vidMem++;
*text++;
}

return 0;
}
)

Code:


! 9 int main(){

use16 486

export _main
_main:
! 10 char *text = "Hi I am the Railex Kernel";
push bp
mov bp,sp
push di
push si
dec sp
dec sp
mov bx,#.1
mov -6[bp],bx
! 11 char *vidMem = (char*) 0xA800;
dec sp
dec sp
mov ax,#$A800
mov -8[bp],ax
! 12
! 13 while(*text){
jmp .3
.4:
! 14 *vidMem = *text;
mov bx,-6[bp]
mov si,-8[bp]
mov al,[bx]
mov [si],al
! 15 *vidMem++;
mov bx,-8[bp]
inc bx
mov -8[bp],bx
! 16 *vidMem = 7;
mov bx,-8[bp]
mov al,*7
mov [bx],al
! 17 *vidMem++;
mov bx,-8[bp]
inc bx
mov -8[bp],bx
! 18 *text++;
mov bx,-6[bp]
inc bx
mov -6[bp],bx
! 19 }
! 20
! 21 return 0;
.3:
mov bx,-6[bp]
mov al,[bx]
test al,al
jne .4
.5:
.2:
xor ax,ax
add sp,*4
pop si
pop di
pop bp
ret
! 22 }
! 23
.data
.1:
.6:
.ascii "Hi I am the Railex Kernel"
.byte 0
.bss

! 0 errors detected


now i have assembled and linked it with the following lines:
bcc -S kernel.c -o kernel.asm <-- the c file
as86 kernel.asm -o kernel.o
ld86 kernel.o -o kernel

when i boot my pc with this kernel it does not work
i see the output of my bootloader that he loads the kernel but then my pc is frezed only the cursor blinks

waht is the reason of my problem?

thanx
hazelnoot!
  | | The administrator has disabled public write access.
OSDEV
Community
Advertisement
   
gaf
User

Platinum Osdever
Posts: 153
graph
Karma: 10  
Re: 16 bit x86 c kernel - 2006/03/10 05:39 Hello hazelnoot,
first of all the address of the video-memory is 0xB8000 and not 0xA0000. These are physical addresses and, as you can see, they're longer than 4 digits and thus too big to fit into a single 16bit register. This is why segmentation has to be used to access the video-memory in real-mode:
DS gets loaded with 0xB800 (physical address/16) and AX with the character's offset in the video-buffer. Your compiler however can't know this why is why it just loads the address to AX:
Code:
mov     ax,#$A800  

mov -8[bp],ax ; AX is stored on the stack as a local variable

To tell the compiler to use segmentation, you have to declare vidmem as a far pointer (refere to your compiler's documation to find out how exactly this is done) and then initialize it with the physical address of the video-memory, which is 0xB8000.

There's by the way another thing about your C code that you should fix:
Code:
while(*text)

{
*vidMem = *text;
*vidMem++;
*vidMem = 7;
*vidMem++;
*text++;
}


Due to the operator's priorities *var_name++ is the same as *(var_name++), which increases the value of the pointer by one, so that it points to the next element, and then dereferences the pointer. The latter step is somewhat redundant as nothing more is done with the dereferenced pointer, so that you could aswell simply write var_name++ - or even better ++var_name, which increases the pointer's value right away, rather then after the line has been executed, so that no temporary variable is needed. To increase the value of the element your pointer points to you by the way have to write (*var_name)++.

Code:
var_a = ++var_b

1. var_b = var_b + 1
2. var_a = var_b

var_a = var_b++
1. var_a = var_b
2. var_b = var_b + 1


You might thus simply write your print loop like this:
Code:
while(*text)

{
*vidMem++ = *text++;
*vidMem++ = 7;
}


Maybe this also sorts out some of the rather awkward assembly code your compiler produces..

regards,
gaf
  | | The administrator has disabled public write access.
hazelnoot
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re: 16 bit x86 c kernel - 2006/03/11 09:42 hi thanx for your answer!
but i have one problem i think the bcc(http://dir.filewatcher.com/d/NetBSD/1.5/m68k/bcc-95.3.12.tgz.92909.html) didn't understand "far"! do you know a good 16 bit c compiler for linux or does somebody know how i can use "far" with this compiler?
thx!

hazelnoot

ps: the man page of the bcc: http://floppsie.comp.glam.ac.uk/Glamorgan/gaius/web/m2f.html
  | | The administrator has disabled public write access.
gaf
User

Platinum Osdever
Posts: 153
graph
Karma: 10  
Re: 16 bit x86 c kernel - 2006/03/12 08:51 According to a tutorial on vga programming (tutorial, code) that I found on the internet, bcc really doesn't seem to support the far keyword. The trick seems to be to tell the compiler to use the large memory model in which all pointers are by default far, so that the whole lower MB can be accessed directly:
Code:
char* vidmem = (char*) 0xB8000000L;   /* seg=0xB800 offset=0x0000 */

bcc -ml -S kernel.c -o kernel.asm /* ml = large memory model */

regards,
gaf
  | | The administrator has disabled public write access.
DRF
User

Platinum Osdever
Posts: 123
graphgraph
Karma: 1  
Re: 16 bit x86 c kernel - 2006/03/16 16:19 Bit off topic but if your in 16bit real mode you can use the BIOS to print characters to the screen. I just find the BIOS easier to work with if I'm in real mode, but you will have to access the graphics memory in a similar way as your doing now in protected mode.

But in real mode here is a quick paste of a small example bootloader I wrote some time back. The code should be the same or similar in the kernel.

[BITS 16] ; 16 bit code generation
[ORG 0x7C00] ; Origin location

; Main program
main: ; Label for the start of the main program

mov ax,0x0000 ; Setup the Data Segment register
; Location of data is DS:Offset
mov ds,ax ; This can not be loaded directly it has to be in two steps.
; 'mov ds, 0x0000' will NOT work due to limitations on the CPU

mov si, HelloWorld ; Load the string into position for the procedure.
call PutStr ; Call/start the procedure

jmp $ ; Never ending loop

; Procedures
PutStr: ; Procedure label/start
; Set up the registers for the interrupt call
mov ah,0x0E ; The function to display a chacter (teletype)
mov bh,0x00 ; Page number
mov bl,0x07 ; Normal text attribute

.nextchar ; Internal label (needed to loop round for the next character)
lodsb ; I think of this as LOaD String Block
; (Not the real meaning of the command! is LOaD Single Byte)
; Loads [SI] into AL and increases SI by one
; Check for end of string '0'
or al,al ; Sets the zero flag if al = 0
; (OR outputs 0's where there is a zero bit in the register)
jz .return ; If the zero flag has been set go to the end of the procedure.
; Zero flag gets set when an instruction returns 0 as the answer.
int 0x10 ; Run the BIOS video interrupt
jmp .nextchar ; Loop back round tothe top
.return ; Label at the end to jump to when complete
ret ; Return to main program

; Data

HelloWorld db 'Hello World',13,10,0

; End Matter
times 510-($-$$ db 0 ; Fill the rest with zeros
dw 0xAA55 ; Boot loader signature

This is a complete example bootloader so you will have to change some things obviously, but the print string function should work in a kernel if you want to learn from this example and write a similar function as an alternative.

Further info on int 10 function E:

INT 10,E - Write Text in Teletype Mode

AH = 0E
AL = ASCII character to write
BH = page number (text modes)
BL = foreground pixel color (graphics modes)

returns nothing

- cursor advances after write
- characters BEL (7), BS (8), LF (A), and CR (D) are
treated as control codes
- for some older BIOS (10/19/81), the BH register must point
to the currently displayed page
- on CGA adapters this function can disable the video signal while
performing the output which causes flitter.


From HelpPC. (download link is on the bonafide website osdever.net it's a DOS .com file but the documents are all plain txt and the .com file is just the vewer)

Hope this helps, but this is just to make you aware of the alternatives if you didn't already know (or other people reading this thread don't know) and if your happy doing it your way then continue doing it that way.

Daniel
  | | The administrator has disabled public write access.

A WebArticles site. Sponsored by Evoleto. Motorola V525 / Business Directory / Delaware Incorporation / Home Made Bazaar