Author Topic: what is a "lmsw" ?  (Read 27533 times)

Offline codeferever

  • Jr. Member
  • *
  • Posts: 21
what is a "lmsw" ?
« on: October 01, 2010, 04:27:12 AM »
when we are going to jmp into the protected mode,what must be done is set PE :
Code: [Select]
mov ax,0x0001  ;set PE which is at the first bit in CR0
lmsw ax  ;Assum IDT and GDT have been loaded into IDTR and GDTR,but what it means?
jmpi 0,8  ;Take attention now the segment address is segment selector,and can nasm compile this instruction?

And when we need a descripter,can we define like this:
Code: [Select]

.word 0x07ff   ; It says 8Mb-limited_length=2047(2048*4096=8Mb),what it means?
.word 0x0000  ;base address
.word 0x9a00 ;code segment can r/x
.word 0x00c0 ;4Kb per


or may just like this:
Code: [Select]
dw 0x07ff
dw 0x0000
dw 0x9a00
dw 0x00c0

and shall we load gdt like this:
lgdt lgdt_48 ;lgdt_48 is a symbol
Code: [Select]
.word 0x7ff
.word 0x7c00+gdt,0

in my boot,I will copy kernel from floppy to 0x10000,but I have not written for it ,is it right to compile my boot like this?
nasm -f obj -o boot.obj boot.asm
an there is a "..start" at the first line.
« Last Edit: October 01, 2010, 06:07:38 AM by codeferever »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: what is a "lmsw" ?
« Reply #1 on: October 01, 2010, 02:48:00 PM »
We've come full circle and are back to translating as86 code, eh?

"lmsw" is an instruction, "load machine status word". Kind of a 286 thing, but I guess it'll still work. I'd just use cr0:

Code: [Select]
mov eax, cr0
or al, 1
mov cr0, eax

I translated "jmpi" in your very first as86 example as "jmp go:BOOTSEG". That was incorrect. Should have been "jmp BOOTSEG:go"! You asked me why my code didn't work? That's one of the reasons (there may be more!). Here, you want "jmp 8:???" - if you've loaded your kernel to 0x10000, "jmp 8:0x10000" perhaps. Or "jmp 8:start32" if you've got a label...

I guess your code descriptor is okay... I don't know why you want an 8-meg limit... A "flat memory model" usually uses a base of zero and a limit of 4G-1 for each descriptor.

Your gdt needs to consist of, at minimum, a null descriptor, a code descriptor, and a data descriptor. The null descriptor is never used - can be zeros, but often the "gdt pointer" (you're apparently calling it "lgdt_48" - "gdtr" is a commonly used name) is stored there, just to save a few bytes. Leaving it separate is probably clearer. This six-byte area consists of two bytes of "size" (0x7FF does not look correct to me), followed by four bytes of address. The as86 code needs 0x7C00 in there, since it was assembled at "org 0" (if I understand it correctly). Since, I understand, you've got "org 0x7C00", you shouldn't need any adjustment here. This is a "linear" address - doesn't involve a segment - unlike almost every other address you'll encounter on x86. Nasm syntax to load it would be:

Code: [Select]
lgdt [lgdt_48]

You do need the "[]"!

I seriously doubt if you want to assemble your bootsector as "-f obj"!  I still haven't downloaded that Linux 0.12 code. I suspect that what they're doing is either feeding ld86 with a "linker script", or doing something like "-T.text=0x0" on the command line to ld86. Take a look at their Makefile to find out. If you wanted to emulate that, Nasm has a "-f as86" output format which might be useful (I've never used it - it does accept "..start", according to the manual). I would suggest assembling with "-f bin". "-f obj" won't accept "org", and "-f bin" won't accept "..start", so it'll make a difference! Alink may be able to combine several OMF objects to a binary image, but I don't know how to do it (or even if it's possible). I'd stick to "-f bin".

Anyway, "lmsw" is an instruction...

Best,
Frank





Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: what is a "lmsw" ?
« Reply #2 on: October 01, 2010, 03:00:33 PM »
The null descriptor is never used - can be zeros

can should, if not must be zeros.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: what is a "lmsw" ?
« Reply #3 on: October 01, 2010, 04:54:24 PM »
I dunno... pretty common to stash "gdtr" (what Codeferever is calling "lgdt_48") there.

Best,
Frank


Offline codeferever

  • Jr. Member
  • *
  • Posts: 21
Re: what is a "lmsw" ?
« Reply #4 on: October 02, 2010, 02:34:40 PM »
I have got a probably still with the memory map,here is the code:
Code: [Select]
;-----------------------------------------------------
keyboard_handle:
pusha

;I wonder if there are two regs,one for control,another for data I/O
;is it a serial port?
;why 0x64,I cannot find the answer in the memory map...

wait_pressed:
in  al, 0x64
and al, 0x01
jz  wait_pressed

in  al,0x60

call write_char

mov al, 0x20
out 0x20, al

popa
iret
;-----------------------------------------------------

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: what is a "lmsw" ?
« Reply #5 on: October 02, 2010, 03:13:22 PM »
"in" and "out" instructions refer to ports (i/o space), not memory. 0x64 is keyboard status, 0x60 is keyboard data, 0x20 is programmable interrupt controller (we're signaling EOI - end of interrupt - so another one can be handled). See Ralf's "ports.lst".

Best,
Frank


Offline codeferever

  • Jr. Member
  • *
  • Posts: 21
Re: what is a "lmsw" ?
« Reply #6 on: October 02, 2010, 04:47:34 PM »
Thank you,Frank
I have describe a US-keyboard map here,but don't know how to get a char from it :(
I think they are not right:
mov al,[keymap:al]
mov al,[keymap]:al
mov al,keymap:al
etc
And
in al,0x60
before the movement...
Code: [Select]
;------------------------
;US-normal keymap
keymap:
                         db  0,27
db "1234567890-="
db  127,9
db "qwertyuiop[]"
db  13,0
db "asdfghjkl;'"
db  0,0
db  "\\zxcvbnm,./"
db  0,0,0,0,32
db  16,1,0
db  0,0,0,0,0
db  0,0,0,0,0,0,0
db  0
db  10,1,0
;------------------------

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: what is a "lmsw" ?
« Reply #7 on: October 02, 2010, 08:23:35 PM »
Right idea, but "al" isn't going to do anything for you. Try:

Code: [Select]
mov al, [keymap + eax]

making sure that the upper bits of eax are cleared, of course.

The keyboard controller will generate an interrupt when a key is released, as well as when a key is pressed - high bit of al will be set. In most cases, this can be ignored, but if the shift key, for example, is pressed... you want to keep track of that until it's releases. Bios uses a bit in a byte of the "bios data area" (0x417 if I recall correctly) to indicate shift key is "still pressed". Maybe use a different keymap for that?

Worse, I seem to recall that certain keys cause multiple bytes to be generated. Seems to me that "sys-req" is particularly bad. I think it's 0xE0 that indicates that this is about to happen, but I may not remember that right...

What you've got should give you some response to the keyboard, anyway...

Best,
Frank


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: what is a "lmsw" ?
« Reply #8 on: October 03, 2010, 04:36:38 AM »
You mentioned using Bochs... It occurs to me that you might want to look at this:

http://code.google.com/p/peter-bochs/

Perhaps you're already using it. I haven't tried it - wrong version of Java (and I just don't like emulators much). I'll give it a try when I upgrade... Seems like a nice guy - posts to the newsgroups once in a while...

Best,
Frank