nasm+DJGPP problem in my kernel
Posted: Sun May 12, 2002 11:00 pm
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
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