Kernel using C
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
Kernel using C
Hi all, its been a while since I posted something on this forum.
I had been practicing OS development to a small extent using assembly. Now, I wanna do it using C(for more productivity). Can anyone please write a small kernel(which prints "H" on the screen) which can be compiled using gcc?
I tried all the stuff at www.osdever.net but nothing seemed to work. Also, if possible a link for linker scripting(I hope thats what it is called).
Regards,
Nitin
I had been practicing OS development to a small extent using assembly. Now, I wanna do it using C(for more productivity). Can anyone please write a small kernel(which prints "H" on the screen) which can be compiled using gcc?
I tried all the stuff at www.osdever.net but nothing seemed to work. Also, if possible a link for linker scripting(I hope thats what it is called).
Regards,
Nitin
Regards
Nitin
Nitin
And if you're on Windows, you'll want to setup Cygwin to be able to use a cross compiler (GCC?) to support executable formats like ELF (commonly-used in OSdevving)
http://www.osdev.org/wiki/GCC_Cross-Compiler
http://www.osdev.org/wiki/GCC_Cross-Compiler
Like this?
--t0xic
Code: Select all
int x, y;
int putc( unsigned char c )
{
unsigned char *vidmem = (char*)0xb8000;
vidmem[ (y*2)+x ] = c;
}
int main( void )
{
putc('h');
}
t0xic wrote:Like this?
--t0xicCode: Select all
...a tiny "kernel"...
I think he could have thought of that code by himself if he did a small kernel in assembly. I think he wants some help to get him started doing it in C, like setting up the toolsets (maybe a cross compiler), linking scripts etc.
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
nice program . But, man I want this to be loadable as an image(floppy image).t0xic wrote:Like this?
--t0xicCode: Select all
int x, y; int putc( unsigned char c ) { unsigned char *vidmem = (char*)0xb8000; vidmem[ (y*2)+x ] = c; } int main( void ) { putc('h'); }
Regards
Nitin
Nitin
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
I was doing some R&D (rewrite and diagnose ), but bochs just flickers
kernel_start.asm
kernel.c
link.ld
doit.sh
Its not working. Plz help
kernel_start.asm
Code: Select all
[BITS 16]
[global start]
start:
xor ax, ax
mov ds, ax
mov es, ax
cli
lgdt [gdtinfo]
mov eax, cr0
or al,1
mov cr0, eax
mov bx,10000b
mov ds, bx
mov ss, bx
mov esp,0x9200
call _k_main
[BITS 32]
[extern _k_main]
jmp $
gdt dd 0,0
code db 0xFF, 0x00, 0x00, 0x7C00, 0, 10011010b, 11000000b, 0
datastack db 0xff, 0xff, 0, 0, 0, 10010010b, 11001111b, 0
gdt_end:
gdtinfo:
dw gdt_end - gdt - 1
dw gdt
Code: Select all
#define WHITE_TXT 0x07 // white on black text
void k_clear_screen();
unsigned int k_printf(char *message, unsigned int line);
void update_cursor(int row, int col);
_k_main() // like main in a normal C program
{
//k_clear_screen();
k_printf("Hi!\nHow's this for a starter OS?", 0);
};
void k_clear_screen() // clear the entire text screen
{
char *vidmem = (char *) 0xb8000;
unsigned int i=0;
while(i < (80*25*2))
{
vidmem[i]=' ';
i++;
vidmem[i]=WHITE_TXT;
i++;
};
};
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=='\n') // check for a new line
{
line++;
i=(line*80*2);
*message++;
} else {
vidmem[i]=*message;
*message++;
i++;
vidmem[i]=WHITE_TXT;
i++;
};
};
return(1);
};
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x0007C00;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .;
}
Code: Select all
nasm -f aout kernel_start.asm -o ks.o
gcc -c kernel.c -o kernel.o
ld -T link.ld -o kernel.bin ks.o kernel.o
Regards
Nitin
Nitin
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
It seems to me you are writing a bootsector. Two issues with that:
1: it needs the signature
2: it must be 512 bytes
your code doesn't satisfy requirement 1. That means several bioses including bochs' will not boot it under normal circumstances. the second requirement is violated due to the aligning to 4096-byte boundaries between sections. It means that only the first 512 bytes of the code section are ever loaded but the variables (initialized and uninitialized) contain garbage. Even then you don't know wether you have all of the code in memory.
The rule of thumb is: The bootsector must be 100% asm.
I suggest you read the babysteps or alternatively reconsider GRUB as your bootloader as the current setup is fundamentally flawed.
1: it needs the signature
2: it must be 512 bytes
your code doesn't satisfy requirement 1. That means several bioses including bochs' will not boot it under normal circumstances. the second requirement is violated due to the aligning to 4096-byte boundaries between sections. It means that only the first 512 bytes of the code section are ever loaded but the variables (initialized and uninitialized) contain garbage. Even then you don't know wether you have all of the code in memory.
The rule of thumb is: The bootsector must be 100% asm.
I suggest you read the babysteps or alternatively reconsider GRUB as your bootloader as the current setup is fundamentally flawed.
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
Ok that signature thing, currently I am just running bochs with signature test disabled.
Also I read some manuals from Redhat and wrote this little thing. Have a look plz. Although the result is the same, it works when I use an asm instead of a C program.
kernel_start.asm
kernel.c
link.ld
Please refer the bold letters in the kernel_start.asm code and suggest corrections
Also I read some manuals from Redhat and wrote this little thing. Have a look plz. Although the result is the same, it works when I use an asm instead of a C program.
kernel_start.asm
Code: Select all
[BITS 16]
[global start]
start:
xor ax, ax
mov ds, ax
mov es, ax
mov ax,0xb800
mov es,ax
mov byte ah,[man]
mov byte [es:0x00],ah
cli
lgdt [gdtinfo]
mov eax, cr0
or al,1
mov cr0, eax
mov bx,10000b
mov ds, bx ; [b]if i dont put jmp $ before this then bochs restarts :([/b]
mov ss, bx
mov esp,0x9200
jmp 08h:temp
[BITS 32]
[extern _k_main]
temp:
call _k_main
jmp $
man db 'w'
gdt dd 0,0 ; entry 0 is always unused
code db 0xff, 0xff, 0, 0, 0, 10011010b, 11000000b, 0 ; code buffer
datastack db 0xff, 0xff, 0, 0, 0, 10010010b, 11001111b, 0 ;
gdt_end:
gdtinfo:
dw gdt_end - gdt - 1
dw gdt
Code: Select all
_k_main() // like main in a normal C program
{
char *vidmem = (char *) 0xb8000;
vidmem[0] = 'k';
}
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
. = 0x7C00;
.text : {ks.o(.text)}
.text : {kernel.o(.text)}
.comment : {kernel.o(.comment)}
}
Regards
Nitin
Nitin