Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Facebook Sign In with Google Sign In with OpenID

Categories

We have migrated to a new platform! Please note that you will need to reset your password to log in (your credentials are still in-tact though). Please contact lee@programmersheaven.com if you have questions.
Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

How to Switch into Protected Mode

pdp8pdp8 Posts: 4Member
[size=4]I need to make modifications to [b]BIOS[/b] code which runs at [u]PowerUp[/u] or [u]Boot[/u] time and I need to access more than the lower 1,048,576 bytes of memory.

Is it possible to switch into [b]Protected Mode[/b] at this time in order to access more memory? If so, how? What is the instruction sequence?

Alternatively, can anyone suggest a different approach?


Thanks,
Bob.
[/size]

Comments

  • MT2002MT2002 Posts: 1,444Member
    To switch to protected mode, you must be running in ring 0. Just set the correct bit in cr0:

    [code]
    ;16 bit code...

    cli ; always disable interrupts
    mov eax, cr0
    or eax, 1
    mov cr0, eax
    jmp codedesc:pmode

    bits 32

    pmode:[/code]

    There is a little bit more involved though: You need to first create a global descriptor table and install that first before going into protected mode.

    While protected mode will help you access more memory, it is not related to accessing above the 1MB mark. To access more then 1MB physical memory you need to enable the A20 gate via the BIOS or keyboard controller.

    Im going to point you to two chapters in my series as they cover both topics better:

    [link=http://www.brokenthorn.com/Resources/OSDev8.html]OSDev series tutorial 8: Protected Mode[/link]
    [link=http://www.brokenthorn.com/Resources/OSDev9.html]OSDev series tutorial 9: Direct hardware programming and A20[/link]

    Please keep in mind that you cannot use any interrupts in pmode (At least without some hardware reprogramming) nor use any BIOS interrupts without having to switch into unreal mode or real mode.

  • BretBret Posts: 114Member
    : To switch to protected mode, you must be running in ring 0. Just set
    : the correct bit in cr0:
    :
    : [code]:
    : ;16 bit code...
    :
    : cli ; always disable interrupts
    : mov eax, cr0
    : or eax, 1
    : mov cr0, eax
    : jmp codedesc:pmode
    :
    : bits 32
    :
    : pmode:[/code]:
    :
    : There is a little bit more involved though: You need to first create
    : a global descriptor table and install that first before going into
    : protected mode.
    :
    : While protected mode will help you access more memory, it is not
    : related to accessing above the 1MB mark. To access more then 1MB
    : physical memory you need to enable the A20 gate via the BIOS or
    : keyboard controller.
    :
    : Im going to point you to two chapters in my series as they cover
    : both topics better:
    :
    : [link=http://www.brokenthorn.com/Resources/OSDev8.html]OSDev series
    : tutorial 8: Protected Mode[/link]
    : [link=http://www.brokenthorn.com/Resources/OSDev9.html]OSDev series
    : tutorial 9: Direct hardware programming and A20[/link]
    :
    : Please keep in mind that you cannot use any interrupts in pmode (At
    : least without some hardware reprogramming) nor use any BIOS
    : interrupts without having to switch into unreal mode or real mode.

    Since you say you're dealing with BIOS code (as opposed to OS or other code that gets loaded after the BIOS), you also need to remember to put the CPU back into real mode after you're done messing around. OS's expect the CPU to be in real mode when they start loading -- I'm not sure any OS will load if the CPU is in protected mode.
  • pdp8pdp8 Posts: 4Member
    Thank-you MT2002 and Bret. This gives me enough information to get started.

    All I need to do is read several bytes of data from the upper end of the 4GB address space, where an MD5 message digest of the bios will have been stored.

    The intent is to compare the current MD5 with the pre-stored value to ensure that the BIOS has not been tampered with.
  • BretBret Posts: 114Member
    : Thank-you MT2002 and Bret. This gives me enough information to get
    : started.
    :
    : All I need to do is read several bytes of data from the upper end of
    : the 4GB address space, where an MD5 message digest of the bios will
    : have been stored.
    :
    : The intent is to compare the current MD5 with the pre-stored value
    : to ensure that the BIOS has not been tampered with.

    So, you're not actually writing BIOS code -- you're just wanting to look at some of the data that the BIOS has already stored. That's a different situation. You can usually use INT 15h, Function 87h to copy data from any part of memory to conventional memory where you can look at it with a regular DOS program. You still need to set up some Descriptor Tables just like you do if you switch into protected mode yourself, but the BIOS takes care of all the mode-switching and copying and interrupt handling for you.

    Attached is some sample code on how to do that, in a format compatible with the A86 assembler (the one I use).
  • pdp8pdp8 Posts: 4Member
    : So, you're not actually writing BIOS code -- you're just wanting to
    : look at some of the data that the BIOS has already stored.

    No, not exactly. I am modifying an existing local module for the BIOS (custom BCM) that is called from the main bios code after completion and before the OS, which resides on a compact flash, is loaded. My code, which is loaded at 0D000h, calculates an MD5 over itself as well as certain values that are stored beginning at bios address 60000h; these values are stored there by an offline utility program when the BIOS chip is created. The data stored there includes an MD5 of the bios itself and of the OS compact flash, etc. If the calculated MD5 does not match the pre-stored value, then I issue an error message and do not load the OS.

    I have verified that the entire 80000h bytes of the bios can be read from addresses 0xFFF80000-0xFFFFFFFF as this is either an exact image of the bios chip or the bios chip ROM itself (I'm not sure which.) In either case, I figure that if I can switch the CPU into protected mode from my bios code, I should be able to read what I need from that upper memory.

    Another complication which is probably superfluous to this discussion, but is important nonetheless, is that the BCM binary plus my module's binary are compressed by a program MKROM.exe from Whizpro Technology, which apparently no longer exists so I have been unable to contact them to ask questions. There is a website http://www.whizpro.com.tw which appears to be abandoned, as the only email contact there is inactive. If it were not for this compression, the data stored at 0x60000 could be stored internal to my module by the offline utility program and there would be no problem.

    I must admit that, although I have been writing code for over 40 years, this is one of the more challenging projects I have encountered. It is my first foray into the bios so obviously I'm not an expert in that area, but expect that I will be before this is done. -:)

    Thanks again Bret, for your help.
    Bob.



  • jeffleydajeffleyda Posts: 390Member
    just a minor word of caution - depending on what OS you're loading after your module has finished up, you will likely need to switch the CPU back into real mode for the hand-off to the OS to work properly. I'd think most all OSes are expecting the CPU to be in plain ole real mode at boot.
Sign In or Register to comment.