Where do i start??

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Schol-R-LEA

Re:Where do i start??

Post 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.
Berserk

Re:Where do i start??

Post 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

Berserk

Re:Where do i start??

Post 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 :D

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

Re:Where do i start??

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Where do i start??

Post 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 ...
Berserk

Re:Where do i start??

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Where do i start??

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

Code: Select all

     popad
     sti
never tested, though ... but it should do it B)
Berserk

Re:Where do i start??

Post 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
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Where do i start??

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

Re:Where do i start??

Post 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
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Where do i start??

Post 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...
Berserk

Re:Where do i start??

Post 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
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Where do i start??

Post 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

Code: Select all

 mov ds,YOUR_DATA_KERNEL_SELECTOR
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 ...
Berserk

Re:Where do i start??

Post 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 ;)
beyondsociety

Re:Where do i start??

Post 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.
Post Reply