Kernel Dev In assembly & C -
i trying create simple kernel using assembly , c on linux using bochs. problem each time try calling c code assembly code emulator gives me error , resets simulation. when start in 16 bit real mode use code
global _start [bits 16] _start: mov [boot_drive] , dl mov bp , 0x7000 mov sp , bp mov bx , 0x0000 ;load 5 sectors 0x0000(es):0x9000(bx) mov es , bx mov bx , kernel_offset mov dh , 15 mov dl , [boot_drive] call disk_load mov dx , [es:kernel_offset] call print_hex call switch_to_pm jmp $
and after switching protected mode code
[bits 32] extern kmain begin_pm: ;print char vram testing , printed, means switch has suceeded mov ebx , vram_address mov al , 'h' mov [ebx] , al mov al , 0x07 inc ebx mov [ebx] , al call kmain jmp $
and c function nothing empty one
about commands using use these
nasm $asm_file_name.asm -f elf -o $asm_file_name.o gcc -ffreestanding -c $c_file_name.c -o $c_file_name.o ld -o $c_file_name.bin -ttext 0x7c00 $asm_file_name.o $c_file_name.o --oformat binary dd status=noxfer conv=notrunc if=$c_file_name.bin of=$floppy_name.img
i don't problem. ideas ?
note: using following gdt , switch_to_pm functions
;gdt gdt_start: gdt_null: dd 0x0 dd 0x0 gdt_code: ;the code segment descriptor ; base = 0x0 , limit = 0xfffff , ; 1 st flags : ( present )1 ( privilege )00 ( descriptor type )1 -> 1001 b ; type flags : ( code )1 ( conforming )0 ( readable )1 ( accessed )0 -> 1010 b ; 2 nd flags : ( granularity )1 (32 - bit default )1 (64 - bit seg )0 ( avl )0 -> 1100 b dw 0xffff ; limit (bits 0 -15) dw 0x0 ; base (bits 0 -15) db 0x0 ; base ( bits 16 -23) db 10011010b ; 1st flags , type flags db 11001111b ; 2nd flags , limit (bits 16 -19) db 0x0 ; base ( bits 24 -31) gdt_data: ; data segment descriptor ; same code segment except type flags : ; type flags : ( code )0 ( expand down )0 ( writable )1 ( accessed )0 -> 0010 b dw 0xffff ; limit ( bits 0 -15) dw 0x0 ; base ( bits 0 -15) db 0x0 ; base ( bits 16 -23) db 10010010b ; 1 st flags , type flags db 11001111b ; 2 nd flags , limit ( bits 16 -19) db 0x0 ; base ( bits 24 -31) gdt_end: ; reason putting label @ end of ; gdt can have assembler calculate ; size of gdt gdt decriptor ( below ) ; gdt descriptior gdt_descriptor: dw gdt_end - gdt_start - 1 dd gdt_start ; size of our gdt , less 1 ; of true size ; start address of our gdt ; define handy constants gdt segment descriptor offsets , ; segment registers must contain when in protected mode. example , ; when set ds = 0 x10 in pm , cpu knows mean use ; segment described @ offset 0 x10 ( i.e. 16 bytes ) in our gdt , in our ; case data segment (0 x0 -> null ; 0 x08 -> code ; 0 x10 -> data ) code_seg equ gdt_code - gdt_start data_seg equ gdt_data - gdt_start [bits 16] switch_to_pm: cli lgdt[gdt_descriptor] mov eax , cr0 or eax , 0x1 mov cr0 , eax jmp code_seg:init_pm [bits 32] init_pm: mov ax , data_seg mov ds , ax mov ss , ax mov es , ax mov fs , ax mov gs , ax mov ebp , 0x9000 mov esp , ebp jmp begin_pm
call kmain
try find function @ address if whole code loaded @ 0x7c00. however, code in entirety loaded disk 0x9000. need ask linker fix address uses address kmain
.
or better, @alexeyfrunze suggests, load code starting second sector place in memory directly after first sector loaded bios.
Comments
Post a Comment