Page 1 of 1

Real mode loader

Posted: Sun Apr 21, 2002 11:00 pm
by chendsh
Hello,
I used a REAL mode bootloader which is written by Mr. Daniel Marjamäki.
The Real mode loader just put the program to 0x10000, and jump to it
using retf.
I also wrote a test program which was compsed of two parts, one in NASM
and the other was in DJGPP.
When booting, the computer hangs or just to reboot again and again.
I compiled the ASM program into aout format and linked it with the
C part.
In fact, I changed to Protected mode before calling the C function.

Would you please tell me the reason? Thank you very much.

RE:eal mode loader

Posted: Mon Apr 22, 2002 11:00 pm
by Guest
>On 2002-04-22 22:33:26, chendsh wrote:
>Hello,
>I used a REAL mode bootloader which is written by Mr. Daniel Marjamäki.
>The Real mode loader just put the program to 0x10000, and jump to it
>using retf.
>I also wrote a test program which was compsed of two parts, one in NASM
>and the other was in DJGPP.
>When booting, the computer hangs or just to reboot again and again.
>I compiled the ASM program into aout format and linked it with the
>C part.
>In fact, I changed to Protected mode before calling the C function.
>
>Would you please tell me the reason? Thank you very much.
>

i like to see the asm code and c code
to get more information.

RE:eal mode loader

Posted: Mon Apr 22, 2002 11:00 pm
by chendsh
>i like to see the asm code and c code
>to get more information.
The ASM and C code is shown below:
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
[EXTERN _main]

[SECTION .text]
[BITS 16]
start: mov ax, 0x1000
mov ds, ax
mov es, ax

xor ebx,ebx
mov bx,ds ; 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

cli


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 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

; 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.
;
msg0: db "s t i l l i n r e a l m o d e ! "
msg1: db "E S , D S s t i l l r e a l m o d e ! "
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 ! "
msg4: db "b a c k t o B O R I N G o l d r e a l m o d e "

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:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
void main()
{
;

;


}

RE:real mode loader

Posted: Tue Apr 23, 2002 11:00 pm
by Schol-R-LEA
>On 2002-04-22 22:33:26, chendsh wrote:
>Hello,
>I used a REAL mode bootloader which is written by Mr. Daniel Marjamäki.
>The Real mode loader just put the program to 0x10000, and jump to it
>using retf.
>I also wrote a test program which was compsed of two parts, one in NASM
>and the other was in DJGPP.
>When booting, the computer hangs or just to reboot again and again.
>I compiled the ASM program into aout format and linked it with the
>C part.
>In fact, I changed to Protected mode before calling the C function.
>
>Would you please tell me the reason? Thank you very much.
>

A few probing questions to help get to the heart
of the matter:

1) Could you give more details on how you transfer control from the bootstrap to the loaded code, or perhaps post the boot code?

2) Have you tried outputting the assembly section
as a flat binary and loading just that?

3) How are you linking the two code sections?
Have you checked that it is producing flat binary
output?

4)In the version that does not call the C
program (i.e., the code you actually posted), do
you still link the C code in, or are you loading
just the assembly code?

5) In the call to the C code, you call
main() directly, rather than the default
initializer; are you sure that the linker isn't
including the initializer (though what effect that would have, I'm not sure)?

I'll admit, this is at the outer edge of my own
experience; you are actually further ahead than I
am, as I tend to be overly cautious in proceding
with actual code :-/ I simply am trying to think
of every possibility I already know of, with the
intention helping you eliminate the overlooked
'obvious' (which never is obvious, or it wouldn't
be overlooked). HTH.

RE:real mode loader

Posted: Tue Apr 23, 2002 11:00 pm
by Schol-R-LEA
Oh, one last thought: it may help to insert yet
another message into the code, or rather, two of
them; one in the boot loader itself, and one in
the loaded code *as the first thing the code
does*, before initializing the p-mode code at
all. Just as a way of increasing the granularity
of the debugging work.

But I'm sure you thought of that already.

that should have read 'decreasing the granularity'

Posted: Tue Apr 23, 2002 11:00 pm
by Schol-R-LEA
(n/t)

RE:real mode loader

Posted: Tue Apr 23, 2002 11:00 pm
by Guest
>On 2002-04-24 00:29:13, Schol-R-LEA wrote:
>>On 2002-04-22 22:33:26, chendsh wrote:
>>Hello,
>>I used a REAL mode bootloader which is written by Mr. Daniel Marjam臾i.
>>The Real mode loader just put the program to 0x10000, and jump to it
>>using retf.
>>I also wrote a test program which was compsed of two parts, one in NASM
>>and the other was in DJGPP.
>>When booting, the computer hangs or just to reboot again and again.
>>I compiled the ASM program into aout format and linked it with the
>>C part.
>>In fact, I changed to Protected mode before calling the C function.
>>
>>Would you please tell me the reason? Thank you very much.
>>
>
>A few probing questions to help get to the heart
>of the matter:
>
\\\\\\\\\\\\\\\\\\\\\\\\\\
Thanks for your kindness!
\\\\\\\\\\\\\\\\\\\\\\\\\\
>1) Could you give more details on how you transfer control from the bootstrap to the loaded code, or perhaps post the boot code?
>
\\\\\\\\\\\\\\\\\\\
I will post the boot loader

org 0x7C00 ; This is where BIOS put me

; ---------------------------------------------------------
; Main program
; ---------------------------------------------------------


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

; Load a program
call load

; Jump to the loaded program
mov ax, 0x1000
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,0x1000 ; ES:BX = 10000
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

>2) Have you tried outputting the assembly section
>as a flat binary and loading just that?
>
\\\\\\\\\\\\\\\\\
I am sure I linked the C section, too.
If you reach the very last line of last
article, you will find the small C source.

>3) How are you linking the two code sections?
>Have you checked that it is producing flat binary
>output?
>
\\\\\\\\\\\\\\\\\\\\\\\\
I used "ld 1.o 2.o --oformat binary ....."
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
>4)In the version that does not call the C
>program (i.e., the code you actually posted), do
>you still link the C code in, or are you loading
>just the assembly code?
>

>5) In the call to the C code, you call
>main() directly, rather than the default
>initializer; are you sure that the linker isn't
>including the initializer (though what effect that would have, I'm not sure)?
>
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
sorry, I dont understand you but I think this
is important. Could you explain it in detail?
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
>I'll admit, this is at the outer edge of my own
>experience; you are actually further ahead than I
>am, as I tend to be overly cautious in proceding
>with actual code :-/ I simply am trying to think
>of every possibility I already know of, with the
>intention helping you eliminate the overlooked
>'obvious' (which never is obvious, or it wouldn't
>be overlooked). HTH.
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
I just copy other person's sources into my program.
And I dont think I really understand them.

thanks Schol-R-LEA, I post the loader

Posted: Tue Apr 23, 2002 11:00 pm
by chendsh
>On 2002-04-24 05:09:27, Anonymous wrote:
>>On 2002-04-24 00:29:13, Schol-R-LEA wrote:
>>>On 2002-04-22 22:33:26, chendsh wrote:
>>>Hello,
>>>I used a REAL mode bootloader which is written by Mr. Daniel Marjamäki.
>>>The Real mode loader just put the program to 0x10000, and jump to it
>>>using retf.
>>>I also wrote a test program which was compsed of two parts, one in NASM
>>>and the other was in DJGPP.
>>>When booting, the computer hangs or just to reboot again and again.
>>>I compiled the ASM program into aout format and linked it with the
>>>C part.
>>>In fact, I changed to Protected mode before calling the C function.
>>>
>>>Would you please tell me the reason? Thank you very much.
>>>
>>
>>A few probing questions to help get to the heart
>>of the matter:
>>
>\\\\\\\\\\\\\\\\\\\\\\\\\\
>Thanks for your kindness!
>\\\\\\\\\\\\\\\\\\\\\\\\\\
>>1) Could you give more details on how you transfer control from the bootstrap to the loaded code, or perhaps post the boot code?
>>
> \\\\\\\\\\\\\\\\\\\
>I will post the boot loader
>
> org 0x7C00 ; This is where BIOS put me
>
>; ---------------------------------------------------------
>; Main program
>; ---------------------------------------------------------
>
>
>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
>
> ; Load a program
> call load
>
> ; Jump to the loaded program
> mov ax, 0x1000
> 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,0x1000 ; ES:BX = 10000
> 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
>
>>2) Have you tried outputting the assembly section
>>as a flat binary and loading just that?
>>
>\\\\\\\\\\\\\\\\\
>I am sure I linked the C section, too.
>If you reach the very last line of last
>article, you will find the small C source.
>
>>3) How are you linking the two code sections?
>>Have you checked that it is producing flat binary
>>output?
>>
>\\\\\\\\\\\\\\\\\\\\\\\\
>I used "ld 1.o 2.o --oformat binary ....."
>\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
>>4)In the version that does not call the C
>>program (i.e., the code you actually posted), do
>>you still link the C code in, or are you loading
>>just the assembly code?
>>
>
>>5) In the call to the C code, you call
>>main() directly, rather than the default
>>initializer; are you sure that the linker isn't
>>including the initializer (though what effect that would have, I'm not sure)?
>>
>\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
>sorry, I dont understand you but I think this
>is important. Could you explain it in detail?
>\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
>>I'll admit, this is at the outer edge of my own
>>experience; you are actually further ahead than I
>>am, as I tend to be overly cautious in proceding
>>with actual code :-/ I simply am trying to think
>>of every possibility I already know of, with the
>>intention helping you eliminate the overlooked
>>'obvious' (which never is obvious, or it wouldn't
>>be overlooked). HTH.
>\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
>I just copy other person's sources into my program.
>And I dont think I really understand them.
>

RE:eal

Posted: Tue Apr 23, 2002 11:00 pm
by blito
>On 2002-04-23 20:08:11, chendsh wrote:
>>i like to see the asm code and c code
>>to get more information.
>The ASM and C code is shown below:
>\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
>[EXTERN _main]
>
>[SECTION .text]
>[BITS 16]
>start: mov ax, 0x1000
> mov ds, ax
> mov es, ax
>
> xor ebx,ebx
> mov bx,ds ; 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
>
> cli
>
>
> 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 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
>
> ; 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.
>;
>msg0: db "s t i l l i n r e a l m o d e ! "
>msg1: db "E S , D S s t i l l r e a l m o d e ! "
>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 ! "
>msg4: db "b a c k t o B O R I N G o l d r e a l m o d e "
>
>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:
>
>\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
>void main()
>{
> ;
>
> ;
>
>
>}

You MUST clear the interrupt flag "cli"
and you have to mask the hardware interruptions
mov ah,0xff
out 0x21,ah
out 0xa1,ah

i think this could be your problem.
unless you define a valid IDT.

also you'll have to mask the NMI interrupt. i don't remember how to do it now. sorry.
i think it's an out to some port, 0x70 or 0x80.

blito.