Alright So I am confused with BIOS calls, Firstly is it possible to call a BIOS function from protected mode WITHOUT switching to real mode? Also do I have to mess with segment registers if my OS is to be booted up in unreal mode? And does UEFI support some legacy mode for BIOS. Such that I would be able to use all the interrupts through a UEFI machine?
And is there a BIOS call that returns the processor properties like "Intel(R) i386"
I have seen many OSes have this feature of telling the CPU properties like RAM,Processor, Model Number, but couldn't find how to do the same with my OS.
Help would be appreciated
Sid123
Question about BIOS calls
- Bender
- Member
- Posts: 449
- Joined: Wed Aug 21, 2013 3:53 am
- Libera.chat IRC: bender|
- Location: Asia, Singapore
Question about BIOS calls
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
(R3X Runtime VM)(CHIP8 Interpreter OS)
Re: Question about BIOS calls
You could've actually taken few minutes of time and read already existing topics on this forum addressing this very issue. There's couple dozens of those. All with the same question how to handle BIOS from protected mode.
Add: You're actually breaking forum rules by not doing that.
Add: You're actually breaking forum rules by not doing that.
Learn to read.
- ScropTheOSAdventurer
- Member
- Posts: 86
- Joined: Sun Aug 25, 2013 5:47 pm
- Location: Nebraska, USA
Re: Question about BIOS calls
No, because the functions depend on being in real mode to work.Firstly is it possible to call a BIOS function from protected mode WITHOUT switching to real mode?
You do have to mess with segment registers to get in unreal mode (at least that is what it looks like from the wiki entry).Also do I have to mess with segment registers if my OS is to be booted up in unreal mode?
You can use the BIOS as usual with UEFI enabled http://stackoverflow.com/questions/1510 ... interrupts.And does UEFI support some legacy mode for BIOS. Such that I would be able to use all the interrupts through a UEFI machine?
There isn't a BIOS call, but there is an instruction for this exact purpose: cpuid. You put some value into EAX, stating what you want, and then you use this instruction. For more information on what you put into EAX and other info on cpuid, see http://wiki.osdev.org/CPUID.And is there a BIOS call that returns the processor properties like "Intel(R) i386"
I have seen many OSes have this feature of telling the CPU properties like RAM,Processor, Model Number, but couldn't find how to do the same with my OS.
And finally, next time, PLEASE look up this stuff yourself before you go to the forum.
"Procrastination is the art of keeping up with yesterday."
Re: Question about BIOS calls
It is possible, but you would need an emulator or V86. There's work and learning to be done in any of those options. If you still need to use the BIOS, then it is better to understand some more of it to later replace that functionality (except for Super VGA modes, for which you will probably need to emulate the BIOS to set those modes).sid123 wrote:Alright So I am confused with BIOS calls, Firstly is it possible to call a BIOS function from protected mode WITHOUT switching to real mode?
Yes, but only once, and it isn't difficult. It just requires a very TINY and very well-known assembly snippet. What it does is just increase the limit of the data segments for DS, ES, FS and GS, from 65536 bytes (the normal 0xFFFF segment limit) to 4 Gigabytes (0xFFFFFFFF). There's a hidden part in the segment selectors that can be set in Protected Mode and that stays in Real Mode, and that is basically the trick. And also enabling the A20 line to have access to odd Megabytes.sid123 wrote:Also do I have to mess with segment registers if my OS is to be booted up in unreal mode?
There are 3 ways to enable the A20 line (fast A20, int 15, and with the keyboad controller). Here you can read more:
http://wiki.osdev.org/A20_Line
I don't know if there are recent machines with that gate already enabled by default, but by this time, it would have seemed the best choice and if I were to make a PC, I would have that gate enabled by default. Here you have the code to set Unreal Mode and enabling the A20 line with the keyboard controller. It may have some errors but it should be easy to fix if that's the case, and you get the idea of how easy it is:
Code: Select all
org 0
bits 16
;INIT: enable protected mode (time 1 of 2) to load GDT
;INIT: enable protected mode (time 1 of 2) to load GDT
;INIT: enable protected mode (time 1 of 2) to load GDT
start: cli ;{0}
lgdt [cs:GDT] ;Load GDT. This is how we would
;exactly access the GDT in
;real mode
mov ecx, CR0 ;Switch to protected mode
inc cx ;set PE bit
mov CR0, ecx ;{5} here we activate protected mode
;END: enable protected mode (time 1 of 2) to load GDT
;END: enable protected mode (time 1 of 2) to load GDT
;END: enable protected mode (time 1 of 2) to load GDT
;;INIT: enable A20
;;INIT: enable A20
;;INIT: enable A20
.5: in al, 0x64 ;Enable A20 {4A}. Port 0x64 is the
;KBC port at the motherboard.
test al, 2 ;See if bit 2 at this port is 1, which means
;that he KBC is not ready.
jnz .5 ;Repeat until but 2 of port 0x64 is 0, which means
;that the KBC is ready for commands.
mov al, 0xD1 ;This command is to write the status byte.
;This is the so-called *WRITE OUTPUT PORT*.
out 0x64, al ;Here we send it and it gets executed.
.6: in al, 0x64 ;Read the byte at port 0x64.
and ax, byte 2 ;See if this bit is 0.
;NOTE: this will leave AL to 0 at once, which
; will be used in the next
; INIT--END block.
jnz .6 ;Repeat until the KBC is ready
;(bit 2 to 0)
mov al, 0xDF ;Set the configuration bits to send.
out 0x60, al ;Send this parameter to the data port
;of the KBC. At this point is where the
;A20 line is enabled.
;;END: enable A20
;;END: enable A20
;;END: enable A20
;;INIT: configuration of memory and register parameters
;;INIT: configuration of memory and register parameters
;;INIT: configuration of memory and register parameters
mov ax, _SELDat32 ;Selector for 4Gb data seg. What we do here
;is to take the address of the second selector
;of the GDT.
;We are using the 8-bit register AL to hold the
;16-bit data selector number because AH is
;already set to 0, and with this we save 1 byte
;or so of boot space.
mov ds, ax ;{2} Extend limit for ds. Typically
;would get the value 0010h. (16)
mov es, ax ;Extend limit for es. ES would also
;be set to 16.
mov fs, ax
mov gs, ax
dec cx ;Switch back to real mode. From the start, ECX
;contained the value of CR0 with PE
;bit set. Here we disable the PE bit again,
;and we put it into CR0 in the next
;instruction.
mov CR0, ecx ;{5}
sti
;Here we are in Real Mode:
;Here we are in Real Mode:
;Here we are in Real Mode:
xor eax, eax ;Segment. 32 bits set to 0x0000
mov ds, ax ;DS (Data Segment) set to 0x0000
mov es, ax ;ES (Data Segment) set to 0x0000
mov fs, ax ;FS (Data Segment) set to 0x0000
mov gs, ax ;GS (Data Segment) set to 0x0000
;;END: configuration of memory and register parameters
;;END: configuration of memory and register parameters
;;END: configuration of memory and register parameters
;;END OF PROGRAM
;;END OF PROGRAM
;;END OF PROGRAM
;;END OF PROGRAM
;;END OF PROGRAM
;;END OF PROGRAM
;;END OF PROGRAM
;;END OF PROGRAM
;;;
ret
ret
ret
ret
ret
ret
ret
ret
;INIT: GDT
;INIT: GDT
;INIT: GDT
GDT:
_SELNull equ 0 ;WARNING: This selector, besides being the pointer to the GDT
GDT_size: ; is the null selector.
dw GDTsize
GDT_actualptr:
dd GDT
dw 0x0000
_SELCod32 equ 8
dw 0FFFFh ; bits 0-15 length
dw 00000h ; bits 0-15 base address
db 0 ; bits 16-23 base address
db 10011010b ; bits P,DPL,DT and type
db 11001111b ; bits G,D and bits 16-19 length
db 0 ; bits 24-31 base address
_SELDat32 equ 16 ;this is the "plain data selector"
dw 0FFFFh ; bits 0-15 length
dw 00000h ; bits 0-15 base address
db 0 ; bits 16-23 base address
db 10010010b ; bits P,DPL,DT and type
db 11001111b ; bits G,D and bits 16-19 length
db 0 ; bits 24-31 base address
GDT_end:
GDTsize equ (GDT_end-GDT)-1
;END: GDT
;END: GDT
;END: GDT
I think UEFI is supposed to completely replace the BIOS calls and overall environment. If you are to create or run an OS that boots the legacy way (BIOS), then UEFI will be out of the question. If you are to create or run an OS that relies on UEFI to boot, then the BIOS is out of the question. The one excludes the other.sid123 wrote:And does UEFI support some legacy mode for BIOS. Such that I would be able to use all the interrupts through a UEFI machine?
And is there a BIOS call that returns the processor properties like "Intel(R) i386"
I have seen many OSes have this feature of telling the CPU properties like RAM,Processor, Model Number, but couldn't find how to do the same with my OS.
Help would be appreciated
Sid123
There are BIOS calls to get a RAM map, and some other data. Things in the CMOS and the BDA can be still useful too.
To get information on the CPU, you will need to use CPUID, and testing actual capabilities would be the best, but if you won't use them or don't know how to use them, you will probably won't understand all of that is involved or how to gather that information.
YouTube:
http://youtube.com/@AltComp126
My x86 OS/software:
https://sourceforge.net/projects/api-simple-completa/
Donate to get more food/programming resources/computers:
https://www.paypal.com/donate/?hosted_b ... QS2YTW3V64
http://youtube.com/@AltComp126
My x86 OS/software:
https://sourceforge.net/projects/api-simple-completa/
Donate to get more food/programming resources/computers:
https://www.paypal.com/donate/?hosted_b ... QS2YTW3V64
- Bender
- Member
- Posts: 449
- Joined: Wed Aug 21, 2013 3:53 am
- Libera.chat IRC: bender|
- Location: Asia, Singapore
Re: Question about BIOS calls
Thank You Very much! Just had a query about CPUID,
It uses EAX which is a 32-bit register, but I want to do this in Real Mode (16Bit)
According to the osdev wiki, all 32bit registers are accessible in RM.
But I was wondering whether I could assign the value of a 32bit register (EAX) to a 16bit register(SI) I am afraid that it will generate a index range out of bounds stuff. So it's something like this
Now this should return "GenuineIntel" on PC right? Or is there something wrong?
It uses EAX which is a 32-bit register, but I want to do this in Real Mode (16Bit)
According to the osdev wiki, all 32bit registers are accessible in RM.
But I was wondering whether I could assign the value of a 32bit register (EAX) to a 16bit register(SI) I am afraid that it will generate a index range out of bounds stuff. So it's something like this
Code: Select all
MOV EAX,0 ;----We want the vendor id
CPUID ;----Call the instruction
;---Now according to Wikipedia CPUID returns stuff in EBX,ECX,EDX
MOV SI,EBX
CALL PRINTF
MOV SI,ECX
CALL PRINTF
MOV SI,EDX
CALL PRINTF
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
(R3X Runtime VM)(CHIP8 Interpreter OS)
Re: Question about BIOS calls
Use the 32 bit registers.As long as you don't read or write to those memory locations, nothing can go wrong. And you can you can still read/write [si] and [di]sid123 wrote: But I was wondering whether I could assign the value of a 32bit register (EAX) to a 16bit register(SI) I am afraid that it will generate a index range out of bounds stuff. So it's something like thisNow this should return "GenuineIntel" on PC right? Or is there something wrong?Code: Select all
MOV EAX,0 ;----We want the vendor id CPUID ;----Call the instruction ;---Now according to Wikipedia CPUID returns stuff in EBX,ECX,EDX MOV ESI,EBX CALL PRINTF MOV ESI,ECX CALL PRINTF MOV ESI,EDX CALL PRINTF