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?
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:Also do I have to mess with segment registers if my OS is to be booted up in unreal 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.
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
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
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.
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.