Hello,
I linked a C program and a Asm program into a binary kernel.
The Asm changes from Real mode into Protected mode and then
calls the C program, which is named _main.
The C part is complied into COFF format using DJGPP , and the
Asm part is compiled into AOUT format using NASM.
When the C program is called , the computer just restarts.
I have posted the problem before, but no resolution works.
Please point out the real problem. Thanks in advance.
These are the two programs and the loader.
1.11111111111111111111111111111111111111111111
C part
int main()
{
return 0;
}
2.222222222222222222222222222222222222222222222
ASM part
[GLOBAL start]
[SECTION .text]
[BITS 16]
start: ;mov ax, 0x7e0
;mov ds, ax
;mov es, ax
; mov al, 0xff
; out 0x21, al
; out 0xa1, al
mov ax, 0xb800
mov es, ax
mov word [es:8], 0x645
; xor ebx,ebx
;mov bx,cs ; BX=segment
;shl ebx,4 ; BX="linear" address of segment base
;mov eax,ebx
;mov [gdt2 + 2],ax ; set base address of 32-bit segments
;mov [gdt3 + 2],ax
;shr eax,16
;mov [gdt2 + 4],al
;mov [gdt3 + 4],al
; mov [gdt2 + 7],ah
; mov [gdt3 + 7],ah
lea eax,[gdt + ebx] ; EAX=PHYSICAL address of gdt
mov [gdtr + 2],eax
;output something here
mov ax, 0xb800
mov es, ax
mov word [es:4], 0x643
;output something here
mov ax, 0xb800
mov es, ax
mov word [es:6], 0x644
cli
o32 lgdt [gdtr]
;
; Set the PE [protected mode enable] bit in register CR0 to begin the
; switch to protected mode.
;
mov eax,cr0
or al,1
mov cr0,eax
jmp SYS_CODE_SEL:do_pm ; jumps to do_pm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Alert! Now in 32-bit protected mode.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
[BITS 32]
do_pm:
mov ax,SYS_DATA_SEL
mov ds,ax
mov ss,ax
mov gs, ax
mov fs, ax
;xor eax, eax
;mov ax, sp
;mov esp , eax
mov ax,LINEAR_SEL
mov es,ax
; questionable PM code here
mov byte [es:dword 0xB8000],'0'
; more questionable PM code here
mov byte [es:dword 0xB8002],'1'
; still more questionable PM code here
mov byte [es:dword 0xB8004],'2'
; (you get the picture)
mov byte [es:dword 0xB8006],'3'
lea esi,[msg2] ; -> "Finally in protected mode!"
mov edi,0xB8000 + (80 * 3 + 4) * 2 ; row 3, column 4
mov ecx,52
cld
rep movsb
;call a c program
[EXTERN _main]
; pusha
call _main
; popa
; lea esi, [msg3]
; mov edi,0xB8000 + (80 * 4 + 5) * 2 ; row 4, column 5
; mov ecx,38
; cld
; rep movsb
hang: jmp hang
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The alternating spaces are treated as attribute bytes by the video
; hardware. This makes the messages an eye-catching black on green.
;
msg2: db "F i n a l l y i n p r o t e c t e d m o d e ! "
msg3: db "C a l l e d a C p r o g r a m ! "
gdtr: dw gdt_end - gdt - 1 ; GDT limit
dd gdt ; (GDT base gets set above)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; global descriptor table (GDT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; null descriptor
gdt: dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; type
db 0 ; limit 19:16, flags
db 0 ; base 31:24
; linear data segment descriptor
LINEAR_SEL equ $-gdt
dw 0xFFFF ; limit 0xFFFFF
dw 0 ; base 0
db 0
db 0x92 ; present, ring 0, data, expand-up, writable
db 0xCF ; page-granular, 32-bit
db 0
; code segment descriptor
SYS_CODE_SEL equ $-gdt
gdt2: dw 0xFFFF ; limit 0xFFFFF
dw 0 ; (base gets set above)
db 0
db 0x9A ; present, ring 0, code, non-conforming, readable
db 0xCF ; page-granular, 32-bit
db 0
; data segment descriptor
SYS_DATA_SEL equ $-gdt
gdt3: dw 0xFFFF ; limit 0xFFFFF
dw 0 ; (base gets set above)
db 0
db 0x92 ; present, ring 0, data, expand-up, writable
db 0xCF ; page-granular, 32-bit
db 0
gdt_end:
3.33333333333333333333333333333333333333333333333333333333
loader
org 0x7C00 ; This is where BIOS put me
; ---------------------------------------------------------
; Main program
; ---------------------------------------------------------
[bits 16]
[SECTION .text]
start:
; Setup the stack.
; We can't allow interrupts while we setup the stack
cli ; Disable interrupts
mov ax, 0x9000 ; Put stack at 0x90000
mov ss, ax ; SS = 9000 and
mov sp, 0 ; SP = 0000 => Stack = 90000
sti ; Enable interrupts
; Remember the bootdrive information provided in DL
mov [bootdrv], dl
mov ax,0x0600 ; BIOS-function clear/scroll window
mov cx,0x00 ; define window to be cleared from 0,0
mov dx,0x174F ; to 23,79
mov bh,0 ; fillcolor = 0
int 10h ; clear screen
;output something
mov ax, 0xb800
mov es, ax
mov word [es:0], 0x641
; Load a program
call load
;output something
mov ax, 0xb800
mov es, ax
mov word [es:2], 0x642
; Jump to the loaded program
mov ax, 0x7e0
mov es, ax
mov ds, ax
push ax
mov ax, 0
push ax
retf
; ---------------------------------------------------------
; Functions and variables used by our bootstrap
; ----------------------------------------------------------
bootdrv db 0 ; This variable will contain the bootdrive id
; Load a program from the bootdrive
load:
; Reset the diskdrive (Interrupt 13h, 0)
push ds ; Store DS
mov ax, 0 ; Select function (Reset Disk)
mov dl, [bootdrv] ; Drive to reset
int 13h ; Reset it!
pop ds ; Restore DS
jc load ; Failed -> Try again
load1:
mov ax,0x7e0 ; ES:BX = 7e00
mov es,ax
mov bx, 0
; Read disksectors (Interrupt 13h, 2)
mov ah, 2 ; Select function (Read disk sectors)
mov al, 5 ; read 5 sectors
mov cx, 2 ; Cylinder=0, sector=2
mov dx, 0 ; head=0, drive=0
int 13h ; ES:BX = data from disk
jc load1 ; failed -> Try again
retn
times 512-($-$$)-2 db 0
dw 0AA55h
; times 512-($-$$) db 0
nasm+DJGPP problem in my kernel
RE:nasm+DJGPP problem in my kernel
I use nealy the same sheme :
an asm loader which loads
an asm second stage and a c kernel
The second stage goes into protected mode and jumps
to the c kernel. It does work.
If I did understand you have _TWO_ files :
an asm loader and an asm-c kernel.
What I would like to know is how you linked your
asm program and your c program.
(I thought djgpp coff output could not be linked
with a 16 bits file)
an asm loader which loads
an asm second stage and a c kernel
The second stage goes into protected mode and jumps
to the c kernel. It does work.
If I did understand you have _TWO_ files :
an asm loader and an asm-c kernel.
What I would like to know is how you linked your
asm program and your c program.
(I thought djgpp coff output could not be linked
with a 16 bits file)
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
RE:nasm+DJGPP problem in my kernel
I suspect a missing stack / invalid stack pointer in your program ...
After you jump in PMODE, you switch your stack segment to your generic data segment, but there is no reajustment of your stack pointer. I can't guarantee this is why it hangs (because unless you have important values at DATA_SEL:0x0000ff00 .. 0x0000ffff, you probably won't overwrite anything important), but if replacing your call _main by a push/pop makes it hang, then you definitively have a stack problem.
Consider having a
align 4
bottom_of_stack:
resd SIZE_OF_STACK
top_of_stack:
mov esp,top_of_stack
After you jump in PMODE, you switch your stack segment to your generic data segment, but there is no reajustment of your stack pointer. I can't guarantee this is why it hangs (because unless you have important values at DATA_SEL:0x0000ff00 .. 0x0000ffff, you probably won't overwrite anything important), but if replacing your call _main by a push/pop makes it hang, then you definitively have a stack problem.
Consider having a
align 4
bottom_of_stack:
resd SIZE_OF_STACK
top_of_stack:
mov esp,top_of_stack
RE:nasm+DJGPP problem in my kernel
At a quick glance, the main problem I see is that you don't seem to load the ds register. Also, you may not be linking the object files in the correct order. You want to make sure that your ASM is first in the binary output. If you post your problems at flashdaddee.com, there will be more of us that can help you out.