Hi,
I am continuing my 32-bit OS. The keyboard ISR was working all right. I added a getch function and that too worked well. Then I started adding command handling. Then all the hell broke loose. The characters are not even being displayed now!! Hellp!!! :(
Thomas Antony
[attachment deleted by admin]
Is this a DOS program? I noticed in your code you have 'int nn' instructions. I might be wrong but I think you do not have or use interupt calls in Win32 assembly. Correct me if I am wrong.
Note: I changed the title.
Let me enourage you in that, all worth while project(s) goes through phases like this.
At first Linux was a joke, now M$ thinks it's serious competition, to spend money for propaganda against it.
I don't the time to look at your code. But remember, code is like eating a big meal. You got to do it, a byte at a time.
Regards, P1 :8)
P1,
It's ok if he wants to improve his skills; to save poor people from buying M$ too expensive.
Thomas Anthony,
You're young, P1 it's understimating because you might make M$ fall. Kidding, anyways to start an Os you need to have a lot of
recruits to make it. Why not merge into a FREEWARE OS? If you want to improve your skills then go. But remember, everyone is
better than one. Also don't support SUN; their products had such weird run-times. They might demolish MS and Assembly all the
micro-processors lost. Nano-tech it's going to be smaller than micro-chips. Worthy OS are for those who have lots of people working
that doesn't have to do with MS and SUN. Imagine, a FREE school; is having better students than private ones. Not open source,
this misc guys will take credit over it. XP it's not so bad, they did publish compilers from C Toolkit and Masm. You see, MS still hasn't
betray the optimize native running. Instead of gaining all the credits; they are giving charity, making friends to learn MS tools.
That's why they publish PSDK.
Sun is out of the league, they're just being stubborn. Let's hope that SUN start making the nano computers like MS is doing with their OS. So, they don't need to fight and also, become friends. :clap:
Hi,
The ints I use are defined in my IDT. They are like a syscall. And I am making this OS as a hobby. So plz look at my code and see whats wrong.
[attachment deleted by admin]
Hi,
I finally found whats wrong!! Its really silly. I wasn't reading in enough sectors in the boot loader. The kernel was more than 7 sectors long and I was loading only 5 sectors!! I have fied it now!!
Thomas Antony
[attachment deleted by admin]
Hi Thomas I have found some links that it may help you,
http://lxr.linux.no/
http://www.masmforum.com/simple/index.php?topic=158.0
http://www.singlix.org/trdos/specs.html
Hi,
Statix Star, Thanx for the links. I will check them out. I have made my 32-bit OS upto the level of my old 16-bit kernel, i.e, with some basic command handling. I suppose I should work on the memory management now. I am using paging. I wrote a proc to enable paging but it resets the Cpu just like that. It doesn't even throw an Exception. Please tell me what is wrong with the code. It is NASM code.
%define PAGE_DIRECTORY 09C000h
%define PAGE_TABLE 09D000h
Init_Paging:
cli
xor ecx,ecx
xor edx,edx
; mov byte[ds:0B8070h],'P' ; some indicators to show me
; mov byte[ds:0B8071h],02h ; where it is not working
@pg_loop1:
cmp ecx,1024
je @pg_1
mov eax,edx
or eax,3 ; set supervisor, read/write
mov dword[PAGE_TABLE+ecx*4],edx
add edx,4096
inc ecx
mov byte[ds:0B8074h],'P'
mov byte[ds:0B8075h],cl
jmp @pg_loop1
@pg_1:
mov eax,PAGE_TABLE
or eax,3
mov [es:PAGE_DIRECTORY],eax
mov ecx,1
mov byte[ds:0B8078h],'P'
mov byte[ds:0B8079h],0Dh
@pg_loop2:
cmp ecx,1024
je @pg_2
mov dword[PAGE_DIRECTORY+ecx*4],02h ; 010 binary supervisor, not present
inc ecx
jmp @pg_loop2
@pg_2:
xor eax,eax
mov cr3,eax
mov byte[ds:0B8082h],'P'
mov byte[ds:0B8083h],0Eh
mov eax,[es:PAGE_DIRECTORY]
mov cr3,eax
mov eax,cr0
or eax,80000000h
mov cr0,eax ; <------------this resets the CPU !!
mov byte[ds:0B8082h],'P'
mov byte[ds:0B8083h],0Eh
ret
Thomas Antony
Hi,
I got it to work. There was a probelm in moveing the address into cr3. Anyway, I want to load my kernel to the 1mB mark. That is 100000h right. how do I do this using 16 bit int 13h b4 going into pmode. Do I use 1000h:0000 as the address?
Thomas Antony
That should work, but note there are ROMs around that area, so it's not very safe to do so. I would put it somewhere much lower, there's plenty of space from 1000h all the way up to 9FFFh :U (above this are used for vga, cga, rom shadows, power management, etc)
Hi Thomas,
If you need to load it at the 1MB mark from real mode, then I think you should take advantage of the so-called High Memory Area (HMA). The HMA is a 65,520 byte block of extended memory that can be accessed from real mode in the address range FFFF:0010 to FFFF:FFFF. The HMA is 65,520 bytes in length instead of 65,536 bytes because the logical addresses FFFF:0000 to FFFF:000F and F000:FFF0 to F000:FFFF represent the same physical addresses. The HMA is accessible only when the 21st address line (A20) is enabled. If the A20 address line is disabled, then by design addresses FFFF:0010 to FFFF:FFFF "wrap" to the beginning of memory.
This might be a dumb question. But almost all the hobby OSes I haves seen use paging. Why? Why not just use 32-bit protected mode? It's faster than using paging anyways.
Mark, the point is that until you get into 32-bit PM, you're stuck with whatever mode the cpu is currently in. That happens to be 16-bit segmented. As for paging, it's an option whether to use it or not, but virtual memory is difficult without it, and without virtual memory you're lacking in usable memory.
AHhh, I gotcha. I forgot about virtual memory. I am spoiled. I have 2GB in my system.
Hi,
Suppose I load the OS at 0FFFFh:0010h using int 13h. Then I switch to PMode in the bootloader itself. Then what offset should I jump to to get to the kernel? Also I have made a scrolling function(video.asm) that is not working very well. Plz check it out.
Thomas Antony
PS: Somebody said most OSes don't go beond the bootloader. Well mine has come a long way already. I was stumped once when the keyboard ISR didn't work. But now it is goign ok. This OS is a sort of a challenge for me.
The absolute address of the start of the HMA is FFFF0h + 10h = 100000h. I don't know where your jump destination would actually be.
I have no idea how this could be done, and I realize that it's generally not done by PM operating systems, but what about using some sort of arrangement that would allow your OS to call down to the real-mode BIOS. I think it should be possible because DOS extenders can pass interrupt calls down to real mode. Performance issues aside, the system BIOS and the VGA BIOS together contain a substantial amount of functionality that you would otherwise need to provide in your PM code.
Hi,
Many OSes I have with me implement it the same way as I do but it is not working for me. And how do I go about usijng the BIOS procs. Can you make a memory map like thing of it?
Thomas Antony
Hi Thomas,
I know very little about it. Possibly a RM stub somewhere in the bottom 1MB that would accept the parameters from the PM code, call the BIOS function, and return the results back to the PM code. You might be able to get some ideas from the DPMI spec (http://www.delorie.com/djgpp/doc/dpmi/).
Quote from: thomasantony on January 13, 2005, 07:30:05 AM
Suppose I load the OS at 0FFFFh:0010h using int 13h. Then I switch to PMode in the bootloader itself. Then what offset should I jump to to get to the kernel?
Once you're in PM, all of the segment registers hold invalid 'segments' which are now called 'selectors' because they work a little differently. (Which means you need to reload ALL segment registers with valid selectors before using them) What they actually do is index entires in your GDT (do you have one?? You do NEEEEEED one!!) so you need to jump to your system-level 32-bit code-segment selector in the GDT. It depends how you've set it up, but most people just put in one code selector, and one data selector, with both set for the whole 4GB space. Anyway, if your system code selector is the first in your GDT (index = 1; 0 is not used) then to get to the start of your kernel you need to do a far jump to selector:kernel_entry
Note: selectors are actually (index*8)
jmp far 08h:100000h
(syntax may be different, and it NEEDS to be a 32-bit offset too, so in 16-bit mode you'll probably need a 066h prefix)
Also, be warned that unless everything is perfectly in place, you'll see a brief flash of light before the computer reboots due to any number of exceptions. Which means it's time to look at your code VERY carefully to see what's wrong or what you've missed out. (This is the fun part!)
{If all this talk of GDT means nothing, please read up about it first}
Hi Tedd,
Thanx for the info abt the 100000h address
If you had managed to read the source of my OS(attached in the previous post), you would have seen that I had gone past the GDT long ago. Dont tell me abt those reboots. Aaaargghhhh!!! When I was setting up the IDt, I frequently had souch probs. I use Bochs and run it on the actual system only when a part is complete. I even have a working Keyboard ISR. I have a working command shell with a few commands. Now I am thinking whether I should be including filesystm support or memory management!! Its just that I was loading the OS at 0000:1000h and jumping to 08h:1000h. I heard that there is useful data in this memory region so I decided to move the into the HMA. But I didn't know how to convert the 16-bit seg:offset addres into prot mode linear offsets. Can you explain how to get the linear offsets from real mode seg:offset form.I know abt the selectors I only want the offset part.
Thomas Antony
Hi,
Okay, I have been bragging a little too much. I am working on my boot loader again. I am making it load fules using FAT12. I read some docs and understood and made a boot loader that worked. Now I want to enable the A20 address line. To be frank, I have read many tuts on that and have understood how to do it. I tried to implement my own code ad it didn't work. I have used other codeds also but they didn't work. I tried one given by victor at the old forum. It is in FASM, but it is not working for me.
Enable_A20:
cli
call Empty8024
in al,0D1h
out 64h,al
call Empty8024
in al, 0DFh
out 60h,al
sti
ret
Empty8024:
in al, 64h
test al,1
jz empty1
in al, 060h
jmp Empty8024
empty1:
test al,2
jnz Empty8024
retn 4
Can someone tell me how to do this? I want to make it really small so that I can also put pmode code in the same bootloader. Now its a bit cramped due to all the FAT things :) The main part about this thing I don't get much is the Empty buffer part. In an example I saw they used two different routines.
Thomas Antony
Hi Thomas,
The attachment contains an A20 address line enabler that I have been playing with over the last few days. It appears to work on my spare system, but it has not been well tested. It will not work under Window 2000 and probably not under Windows XP, and it cannot do anything useful under Windows 9x because the A20 address line is always enabled. It uses the most common method of enabling A20, and the method should work on most recent systems, but note that the HIMEM.SYS for the last versions of MS-DOS had ~15 A20 handlers to cover the entire range of hardware available at the time.
[attachment deleted by admin]
Hi,
Thanx, I will check out your code. I found this code at an OSDev forum. I don't know how it works but it is working. This is the code.
cli
in al, 0x92
or al, 0x02
out 0x92, al
sti
I am more comfortable using the code of which I know the working. If somebody knows abt the above procedure of enabling the A20 line, can someone explain to me? Like what hardware does ports 92h access? Is it the port of some new version of the keyboard controller?
Thomas Antony
Quote from: thomasantony on January 14, 2005, 06:06:47 AM
If you had managed to read the source of my OS(attached in the previous post)...
But I didn't know how to convert the 16-bit seg:offset addres into prot mode linear offsets. Can you explain how to get the linear offsets from real mode seg:offset form.I know abt the selectors I only want the offset part.
linear address = (segment * 16) + offset
Notes:
- 16 (decimal) = 10h
- this assumes the base for the given selector is zero, otherwise you need to add that on to find what address it really makes.
As for A20, MichaelW is right, there are at least 15 different ways to do it depending on what hardware there is. There are two or three most common ways which work for most systems, and all the others are for the different strange variations. Personally I just use the PS/2 method, which is nice and short and seems to work okay for most newer systems (not that I've tested many!)
I found that trying to pack too much into a tiny little bootloader isn't such a great idea. I managed to get a FAT12 loader in (handles clusters, cylinder boundaries, dma boundaries, etc) and that was it! So it's probably best to do a good bootloader and have that load other files in that do the real bootloading, then you can mess about with as many stupid ways as necessary to switch on A20 and setup everything else.
Edit: I think the one you've just posted is the PS/2 version I use. Can't remember exactly what it does :lol
I/O port 92h is PS/2 System Control Port A. I have experimented with using output bit0 of this port to perform a reset, and it worked, but I tried it on only a few systems. Output bit1 is supposed to control the A20 address line, but this is not the method recommended in my first edition of The Undocumented PC, which was published ~7 years after the PS/2 was released:
Quote
In 99% of PC systems, the keyboard controller is used to handle the A20 gate."
Frank van Gilluwe, the author of The Undocumented PC, is more or less an industry insider who enlisted the aid of other industry insiders, and tested a very wide variety of hardware. I tend to trust his recommendations. But the System Control Port method is much smaller and easier, and when I tested it just now it does work on my spare system.
enable_a20_ps2 proc
cli
in al, 92h
or al, 2
out 92h, al
sti
ret
enable_a20_ps2 endp
But it also occurs to me that if you are going to be doing much with the keyboard you will need most of the support routines required for A20 control via the keyboard controller, anyway.
Hi,
When was PS/2 released? What is its full form? (Play station 2? ;) ). Anyway, I might just as well ask another problem with my OS. This is a function I call to scroll the screen up one line
Scroll_Up:
cld
mov byte[0B8082h],'D'
mov byte[0B8083h],0Dh
mov esi,0B8000h+(80*2)
mov edi,0B8000h
mov ecx,(80*24*2)/4
rep movsd
mov edi,0B8000h+(80*24*2)
mov eax,0E200E20h
mov ecx,160/4
rep stosd
mov dword[VideoPtr],80*23*2 ; put it 2 lines above
ret
I call it from a putCR routine which is called when 13,10 is encountered in a string or when Enter key is pressed. The VideoPtr variable contains the current video offset in the form (160*y)+x (for bot characters and attributes).
call GetCursorXY
cmp eax,24
jle $+7
call Scroll_Up
The GetCursorXy translates the VideoPtr into X and Y. Its scroling off for ever
Thomas Antony
The IBM Personal System 2 was introduced in 1987, along with the VGA IIRC.
I cannot see any problem in the code you posted or in video.asm from your site. Have you considered coding these routines so they can be debugged in RM with no more than minimal changes? For example, these (old and slow) MASM procedures will work in PM or RM. The only change required is that ES must contain B800h for RM or a valid selector the display buffer for PM.
; ---------------------------------------------------------
; This proc, callable from PM, scrolls the screen up one
; line and fills the bottom line with spaces. Note that
; ES must contain a valid selector for the display buffer.
; ---------------------------------------------------------
ScrollUp proc uses ds
pusha
push es
pop ds
mov si, 160
mov di, 0
mov cx, 4000 - 160
cld
rep movsb
mov cx, 80
mov al, 20h
@@:
stosb
inc di ; Skip attribute byte
loop @B
popa
ret
ScrollUp endp
; ---------------------------------------------------------
; This proc, callable from PM, displays an asciiz string
; on the screen, updates the cursor, and scrolls the screen
; up as necessary. It expects the string to be located at
; DS:DX. It treats a backslash as a newline character.
; Note that ES must contain a valid selector for the
; display buffer.
; ---------------------------------------------------------
PutStr proc
pusha
mov si, dx
charloop:
lodsb
or al, al
jz update_cursor
cmp al, '\'
jnz putc
mov dl, 160 ; Cursor offset = coff + 160 - coff % 160
mov ax, coff
div dl
shr ax, 8
add coff, 160
sub coff, ax
jmp SHORT ckend
putc:
mov di, coff
stosb
add coff, 2
ckend:
cmp coff, 4000
jb @F
call ScrollUp
mov coff, 4000
sub coff, 160
@@:
jmp SHORT charloop
update_cursor:
mov al, 0fh ; Index for cursor location low
mov dx, 3d4h ; CRTC index register
out dx, al
DELAY
mov ax, coff
shr ax, 1 ; Adjust for odd/even addressing
mov dx, 3d5h ; CRTC data register
out dx, al
DELAY
mov al, 0eh ; Index for cursor location high
mov dx, 3d4h ; CRTC index register
out dx, al
DELAY
mov ax, coff
shr ax, 9 ; Adjust for odd/even addressing
mov dx, 3d5h ; CRTC data register
out dx, al
popa
ret
PutStr endp
Okay, I lied :bg
This is what I'm using (it uses the keyboard port - which is what IBM did to 'fix' the A20 problem in the first place.)
;enable A20
mov dx,64h
.w1:
in al,dx
test al,2 ;wait for port to be ready again
jnz .w1
mov al,0D1h
out dx,al
.w2:
in al,dx
test al,2 ;wait for port
jnz .w2
mov al,0DFh
out 60h,al
I think if you use the PS/2 method, check whether that set it, if not use this one. That should cover most systems out there. If it still doesn't work, then it's one of those oddball ones :bdg
Also, here's yet another screen scrolly routine ::)
(the proc/endproc (and uses) are just macros that I made (nasm), so don't worry aobut them)
scrollup proc
uses esi,edi
mov esi,0B80A0h
mov edi,0B8000h
xor ecx,ecx
.lp:
mov eax,[esi+ecx]
mov edx,[esi+ecx+4]
mov [edi+ecx],eax
mov [edi+ecx+4],edx
add ecx,8
cmp ecx,0F00h
jl .lp
;clear the bottom line!!
mov eax,07200720h
.clr
mov [edi+ecx],eax
mov [edi+ecx+4],eax
add ecx,8
cmp ecx,0FA0h
jl .clr
ret
endproc
Thanx!! :U I will check out those codes
Thomas Antony :U
Hi!I have a problem that you had earlier...i try to enable paging,but then a reset is occired.i created a page directory with one entry,and a page table with 1024 entries while i am in real mode,and when i am in protected i change CR3 and set the PG bit.and after this nothing.....any help???
Hi,
I have put off the emeory manager for some time. Here is the code I used to enable paging. It doesn't reset AFAIK. It maps only the first 4 megs of RAM
Thomas Antony
[attachment deleted by admin]