Page 10 of 17
Re:Where do i start??
Posted: Fri Nov 15, 2002 2:58 pm
by Schol-R-LEA
Berserk wrote:Ahh, don't know how to attach, guess i can't cos i'm not a member.
Then perhaps it is time you became one.
Also, not to put too fine a point on it, perhaps you should read (or re-read, if you already saw it)
this advice, for you own benefit and for the piece of mind of the rest of the members. You can catch more flies with honey than with vinegar, as the old saying goes.
Re:Where do i start??
Posted: Fri Nov 15, 2002 5:36 pm
by Berserk
Hey,
Sorry if i demanded code. I just really wanted to know how to do this. Thanls, Pype.Clicker.
There are just a few error in the code, and i fixed them (i think)
But there are also things like this CODE_SEGMENT_BASE_ADDRESS
i figured i was surposed to change this to the CODE_SEGMENT_BASE_ADDRESS. But what is this?
Do you mind explaining?? (Please)
And also the other things like that!
Here is the Code i use (i use nasm) I outputed an elf file using nasm, then liked it to my Kernel using the ld linker.
Here is the code, (edited by me, to be used as a linked asm function):
Code: Select all
[GLOBAL _SwitchMode]
_SwitchMode:
cli
pushad
mov ebx,[ebp+8] ;; get back the argument
mov ecx, .temp_real_mode
add ecx, CODE_SEGMENT_BASE_ADDRESS
mov dl,0x0f
and dl,cl
shr ecx,4 ;; compute an offset & a segment out of the linear address.
mov byte [.rm_offset],dl
mov word[.rm_segment],cx
jmp .pipeline_flush
.pipeline_flush:
mov eax,cr0
mov edx,eax
and eax,0x7fff, 0xfffe
mov cr0,eax
db JMP_FAR_OPCODE
.rm_offset db 0,0
.rm_segment dw 0
[BITS 16]
.temp_real_mode:
;; set up a valid stack segment and pointer for real mode
mov ax,bx
int 0x10
mov cr0,edx
[BITS 32]
jmp CODE32_SELECTOR : .back2pmode
.back2pmode:
popad
sti
Re:Where do i start??
Posted: Sat Nov 16, 2002 11:26 pm
by Berserk
Please,
If somebody could help, if you can't provide code, could somebody please label the existing code, so i can understand it better. I have been trying for the past day to switch modes change the graphics and switch back.
Please, somebody, help out
NOTE: I searched
www.google.com and
www.search.com, and i could only find information on how to switch to Protected Mode, no information on how to get out of it :'(
So please, Help out.
Ciao/
Re:Where do i start??
Posted: Sun Nov 17, 2002 9:35 am
by damonbrinkley
Berserk,
You must not have searched to hard on google. My first search came up with
http://www.nondot.org/sabre/os/files/ProtectedMode/segments.html and
http://www.nondot.org/~sabre/os/articles/ProtectedMode/ which have some information and code on switching to and from pmode. You need to learn how to search or something because my first search came up with tons of sites that show you how to do it. Maybe you should buy a book on OS development which would probably tell you how to do alot of this.
Re:Where do i start??
Posted: Mon Nov 18, 2002 1:37 am
by Pype.Clicker
Berserk wrote:
Hey,
But there are also things like this CODE_SEGMENT_BASE_ADDRESS
i figured i was surposed to change this to the CODE_SEGMENT_BASE_ADDRESS. But what is this?
This is a place to store your CS segment's base address in case it wasn't zero ...
Re:Where do i start??
Posted: Mon Nov 18, 2002 6:18 am
by Berserk
Could you explain the other things aswell, i am getting quite a bit of errors.
Sorry i don't have time to explain what they are.
I have to go.
Cya.
Re:Where do i start??
Posted: Mon Nov 18, 2002 9:44 am
by Pype.Clicker
1. make sure nothing wrong will happen during the process ...
Code: Select all
switch_mode:
cli
push ebp
mov ebp,esp
pushad
2. read the argument of the function (video mode to setup)
Code: Select all
mov ebx,[ebp+8] ;; get back the argument
3. compute the address for the real-mode jump (create segment:offset out of the linear address)... better have your code located under 1Mb barrier ...
Code: Select all
mov ecx, .temp_real_mode
add ecx, CODE_SEGMENT_BASE_ADDRESS
mov dl,0x0f
and dl,cl
shr ecx,4 ;; compute an offset & a segment out of the linear address.
3. stores the computed value. And yes, i *do* use self-modifying code. (i am nasty
Code: Select all
mov byte [.rm_offset],dl
mov word[.rm_segment],cx
4. as i modified the code, i must flush pipeline to have the change committed to the instruction cache. a simple jump just do it
Code: Select all
jmp .pipeline_flush
.pipeline_flush:
5. now the funky part : read machine status (CR0), store it in a temporary register (%edx -- better keep it saved), and clean the PE and PG bits.
Code: Select all
mov eax,cr0
mov edx,eax
and eax,0x7fff fffe
mov cr0,eax
6. the processor has now turned back in real mode ... we'll just issue a JMP segment:offset instruction to make it re-decode the instruction stream and reset a valid CS/IP pair. replace JMP_FAR_OPCODE with the right constant
Code: Select all
db JMP_FAR_OPCODE
.rm_offset db 0,0
.rm_segment dw 0
7. here come the real-mode code: calling the interrupt.
the interrupt call will require a valid stack to be set up. It is dependent on your OS design so i leave it up to you
Code: Select all
[code 16]
.temp_real_mode:
;; set up a valid stack segment and pointer for real mode
mov ax,bx
int 0x10
8. provided that EDX value has been kept, we restore the protected mode status and refresh the CPU queue for 32 bits execution ...
Code: Select all
mov cr0,edx
[code 32]
jmp CODE32_SELECTOR : .back2pmode
.back2pmode:
9. now we just have to do the right status resume and proudly return to the C code who called us ...
never tested, though ... but it should do it B)
Re:Where do i start??
Posted: Tue Nov 19, 2002 6:22 am
by Berserk
A few more questions. The code still doesn't work properly... First of all, i figure that you use nasm, then why do you put
Code: Select all
instead of [BITS 32]?? nasm doesnt understand this??
most of the code works, except for these things, could you explain it please......
where you put:
and eax,0x7fff fffe
whats wrong with this??
and could you give me an example of what i put here:
db JMP_FAR_OPCODE
that's about it for the errors, i just got another question:
Why didn't you enable interrupts when it goes into Real Mode?? isn't int 10h an interrupt??
Should i enable interrupts??
This is how i modified the code, it still doesn't work, but could you please, edit and add to this:
[code]
[GLOBAL _SwitchMode]
_SwitchMode:
[BITS 32]
cli
push ebp
mov ebp, esp
pushad
mov ebx, [ebp+8]
mov ecx, RealMode
add ecx, 0h
mov dl, 0x0F
and dl, cl
shr ecx, 4
mov byte[RM_offset], dl
mov word[RM_segment], cx
jmp FlushPipeline
FlushPipeline:
mov eax, cr0
mov edx, eax
and eax, 0x7FFF
mov cr0, eax
RM_offset db 0, 0
RM_segment dw 0
[BITS 16]
RealMode:
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x9000
mov ss, ax
mov sp, 0xfffe
mov ax, bx
int 0x10
mov cr0, edx
[BITS 32]
jmp 0x08:ProtectedMode
ProtectedMode:
popad
sti
Re:Where do i start??
Posted: Tue Nov 19, 2002 10:41 am
by Pype.Clicker
Berserk wrote:
A few more questions. The code still doesn't work properly... First of all, i figure that you use nasm, then why do you put
Code: Select all
instead of [BITS 32]?? nasm doesnt understand this??
[/quote]
i told you i didn't tested the code ... this is just a quick draft of what is to be done ... i though [code 32] was valid ... seems it's in another assembler .. yes . i use nasm ... a few monthes ago :-p
[quote]
most of the code works, except for these things, could you explain it please......
where you put:
and eax,0x7fff fffe
whats wrong with this??
[/quote]
i guess the assembler don't like the fact i split long words in 2x4 digits for readability ... remove the middle space
[quote]
and could you give me an example of what i put here:
db JMP_FAR_OPCODE
[/quote]
just put the opcode for a far jmp ... i don't have it here. it's in the Intel manuals (instructions list)
[quote]
that's about it for the errors, i just got another question:
Why didn't you enable interrupts when it goes into Real Mode?? isn't int 10h an interrupt??
Should i enable interrupts??
[/quote]
INT 10 is a software interrupt invocation and can be performed whatever the IF flag holds... CLI/STI are for HARDWARE INTERRUPT REQUEST and i want to keep them disabled so that your OS doesn't lose a timer tick or a keystroke while switching graphical mode (it would be bad if pressing CTRL+ALT+DEL at that time rebooted the system)
[quote]
This is how i modified the code, it still doesn't work, but could you please, edit and add to this:
[code]
RealMode:
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x9000
mov ss, ax
mov sp, 0xfffe
mov ax, bx
int 0x10
If you change the segment registers in real mode, i strongly suggest you save/restore them in your PMODE code ... otherwise, your popad instruction is not likely to be valid on selector 0x9000
Re:Where do i start??
Posted: Tue Nov 19, 2002 11:07 pm
by Berserk
Hi,
First i would like to say thank you to Pype.Clicker, But i still need help with this function:
First off all, i do not have the intel manuals :'(
So if somebody could tell me the opcode for a far jump.
And, also, this is the code i am going to use, could somebody please check through it, of course it doesn't work because i don't have the opcode thingy. Anyways, what is opcode??
Here is the Code, I am actually going to use this code, so please, somebody check it, and if anything is wrong with is, edit this code:
Code: Select all
[GLOBAL _SwitchMode]
_SwitchMode:
[BITS 32]
cli
push ebp
mov ebp, esp
pushad
mov ebx, [ebp+8]
mov ecx, RealMode
add ecx, 0h
mov dl, 0x0F
and dl, cl
shr ecx, 4
mov byte[RealMode_Offset], dl
mov word[RealMode_Segment], cx
jmp FlushPipeline
FlushPipeline:
mov eax, cr0
mov edx, eax
and eax, 0x7FFFFFFE ;0x7fff fffe
mov cr0, eax
;db JMP_FAR_OPCODE
RealMode_Offset db 0, 0
RealMode_Segment dw 0
[BITS 16]
RealMode:
mov ax, 0x9000
mov ss, ax
mov sp, 0xFFFE
mov ax, bx
int 0x10
mov cr0, edx
[BITS 32]
jmp 0x08:ProtectedMode
ProtectedMode:
popad
sti
Re:Where do i start??
Posted: Wed Nov 20, 2002 2:12 am
by Pype.Clicker
users/martin> ndisasm test.bin
00000000 EA2E163412 jmp 0x1234:0x162e
opcode for far jump is therefore 0xEA
(pretty disappointed i needed to tell it to you, though ...)
manuals are on intel.developer.com ... you definitely should get them and study them before you start with low-level stuffes
you still need to save/restore your stack:
something like
Code: Select all
mov [stack_safe+4],ss
mov [stack_safe],esp
...
lss esp,[stack_safe]
once again, i'm no more sure of the order of segment & offset, so better experiment it offline before reusing it blindly...
Re:Where do i start??
Posted: Wed Nov 20, 2002 11:47 pm
by Berserk
Hey Hey,
I am very grateful for all your help. BUT it STILL doesn't work :'( :'( :'( :'( :'( :'( :'( :'( :'( :'(
Here is my code, please take a look at it and help out...
I know i might be a bit of a hassle, but please buddy.....Help out.....
Here is the Code:
Code: Select all
[GLOBAL _SwitchMode]
_SwitchMode:
[BITS 32]
;Save Stack
Save_eax db 0
Save_edx db 0
Save_ss db 0
Save_sp db 0
Save_dl db 0
Save_ds db 0
Save_es db 0
Save_fs db 0
Save_gs db 0
Save_cx db 0
Save_cs db 0
Save_eip db 0
Save_esp db 0
Save_cl db 0
mov [Save_eax], eax
mov [Save_edx], edx
mov [Save_ss], ss
mov [Save_sp], sp
mov [Save_dl], dl
mov [Save_ds], ds
mov [Save_es], es
mov [Save_fs], fs
mov [Save_gs], gs
mov [Save_cx], cx
mov [Save_cs], cs
mov [Save_esp], esp
mov [Save_cl], cl
cli
push ebp
mov ebp, esp
pushad
mov ebx, [ebp+8]
mov ecx, RealMode
add ecx, 0h
mov dl, 0x0F
and dl, cl
shr ecx, 4
mov byte[RealMode_Offset], dl
mov word[RealMode_Segment], cx
jmp FlushPipeline
FlushPipeline:
mov eax, cr0
mov edx, eax
and eax, 0x7FFFFFFE ;0x7fff fffe
mov cr0, eax
db 0xEA
RealMode_Offset db 0, 0
RealMode_Segment dw 0
[BITS 16]
RealMode:
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x9000
mov ss, ax
mov sp, 0xFFFE
mov ax, bx
int 0x10
mov cr0, edx
[BITS 32]
jmp 0x08:ProtectedMode
;Restore Stack
mov eax, [Save_eax]
mov edx, [Save_edx]
mov ss, [Save_ss]
mov sp, [Save_sp]
mov dl, [Save_dl]
mov ds, [Save_ds]
mov es, [Save_es]
mov fs, [Save_fs]
mov gs, [Save_gs]
mov cx, [Save_cx]
mov cs, [Save_cs]
mov esp, [Save_esp]
mov cl, [Save_cl]
ProtectedMode:
popad
sti
Re:Where do i start??
Posted: Thu Nov 21, 2002 1:31 am
by Pype.Clicker
i would not like to sound too much arrogant, but i think you need some more ASM practice for the problem you're working on ...
1. you declared just bytes for all of your save-places ... this will not even let you assemble the above code without a complaint. If you're saving a 32-bits register, you need a 32-bits place, which is
dd, not
db.
2. You put the bytes to save your state at the beginning of the function, which means the CPU will try to execute them at function entry ... better leave them away like:
Code: Select all
section .data ;; or something alike: check nasm reference to be sure or just skip it
my_data1 dd 0
my_data2 dd 0
...
section .text
my_function:
;instructions to be executed for my_function
ret
3. why the hell do you save so much informations ? only the stack pointer needs to be written at a precise location : the rest can be left on the stack ... it will be much easier to write & understand ...
4. you cannot do the restore before you issued some
5. pick up a sheetapaper and a pencil and figure out what you're doing with the stack ... you saved ss:esp *prior* to the pushad stuff and you restore it *before* ... this means when you'll do a popad, your stack pointer will not have the informatijons to fill the registers (which content will be messed up) and your RET instruction will send you in a black hole ...
Re:Where do i start??
Posted: Fri Nov 22, 2002 7:59 pm
by Berserk
Hi,
So all i need to save is the stack pointer?? What is the stack pointer??
And i don't know assembler, only some of it, yes i know what your going to say, "Go learn assembler", but since only 2% of the code is asm, i will not learn asm.
Could you please give an example of what you are saying here, and i know, what people say, "First worry about making the OS, then Graphics", but no, i want to do this function first.
Cya, and thank you for bearing with me, i know, i am an absoloute beginner.
Ciao

Re:Where do i start??
Posted: Fri Nov 22, 2002 8:14 pm
by beyondsociety
Why don't you do some research before you start to post. Read some tutorials and get the intel manuals.
And yes, learn assembler. Or at least learn the basics. It will help.