So I switch into Pmode and I call my kernel when

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Ryu

Re:So I switch into Pmode and I call my kernel when

Post by Ryu »

When your producing objects you need to define each section or segment, I take it that the [bits 32] directive is only valid after you declared a segment. And that NASM defaults in 16bit segments when producing OMFs. Try one of these:

Code: Select all

SECTION .text
[bits 32]
....
..or use USE16 and USE32

Code: Select all

SECTION .text USE32
....
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:So I switch into Pmode and I call my kernel when

Post by Candy »

REV wrote: So again why is this happening when it shouldn't. All the instructions are 32-bit (at least I think so because in my NASM code they use the [bits 32] directive and all the C/C++ code is compiled using the WCC386 compiler from watcom) and all the kernel code starts at base address 0x10000 as linked by JLOC.
Either watcom or jloc is converting it to 16-bit code.
REV

Re:So I switch into Pmode and I call my kernel when

Post by REV »

NASM is compiling 32-bit instructions (I put a hlt instruction) and I would think it hang it was 16-bit.

Well it appear to be Watcom but looking at the command line options for wcc386 there is no help there. (Watcom is also throwing in useless segments in aswell that Im trying to figure out)

How can I check if Watcom is producing 16-bit code? I'm still puzzeld since it is a 32-bit compiler Im using.

I assume JLOC is producing 32-bit code for the NASM stuff.
Ryu

Re:So I switch into Pmode and I call my kernel when

Post by Ryu »

Isn't that watcom a 32bit compiler? Or can it be switched to 16bit? I actually went and downloaded NASM yesterday night and test compiled a near jump to label which was producing the 16bit version as expected.. ofcourse linked with jloc as well. Using [bits 32] after resolved the problem or USE32 directives. jloc may also have a default setting to either produce 16bit or 32bit offsets I don't really know, but its primary should be marked in the OMF objects by the compiler/assembler. Its a possibility that you have two .text segments one using 16bits and the other 32bits and jloc doesn't know how to deal with it and perhaps not warn during linkage, but not having a warning is a fat chance.

Also.. in jloc you could always disgard segments not wanted produced by watcom.
REV

Re:So I switch into Pmode and I call my kernel when

Post by REV »

There are 2 verisons of the Watcom. One for 16-bit and one for 32-bit. I am using the 32-bit compiler. I moved the 16-bit code into the bootloader and made the entire image 32-bit. At least I think it is.

Wcc386 should be making 32-bit.
Hmm there appear to be some command line perimeters for memory stuff:
[tt]
-mc compact memory model (small code/large data)
-mf flat memory model (small code/small data assuming CS=DS=SS=ES)
-ml large memory model (large code/large data)
-mm medium memory model (large code/small data)
-ms small memory model (small code/small data)
[/tt]

I'm gunna fiddle around with each of these and post the results.
REV

Re:So I switch into Pmode and I call my kernel when

Post by REV »

Ok none of them work >:( >:( >:( >:( >:( >:( >:(
This is really starting to bug me :(
Ill write up the interrupt stuff when I can just get basic C/C++ code working.
(Another note Watcom is also making a _cstart segment)

-mc, -ms and -mf produced:
[tt]
00000794800i[CPU0 ] LOCK prefix unallowed (op1=0x53, attr=0x0, mod=0x0, nnn=0)
00000794800e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00000794800e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00000794800i[CPU0 ] protected mode
00000794800i[CPU0 ] CS.d_b = 32 bit
00000794800i[CPU0 ] SS.d_b = 32 bit
00000794800i[CPU0 ] | EAX=00000010 EBX=00000000 ECX=00000002 EDX=00000000
00000794800i[CPU0 ] | ESP=00014ff0 EBP=00000000 ESI=00007343 EDI=0000ffde
00000794800i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf af pf cf
00000794800i[CPU0 ] | SEG selector base limit G D
00000794800i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00000794800i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00000794800i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00000794800i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00000794800i[CPU0 ] | ES:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000794800i[CPU0 ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000794800i[CPU0 ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000794800i[CPU0 ] | EIP=00000003 (00000003)
00000794800i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00000794800i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00000794800i[CPU0 ] >> lock push ebx : F053
[/tt]

-ml and -mm produced:
[tt]
00000794843e[CPU0 ] call_protected: CS selector null
00000794843e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00000794843e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00000794843i[CPU0 ] protected mode
00000794843i[CPU0 ] CS.d_b = 32 bit
00000794843i[CPU0 ] SS.d_b = 32 bit
00000794843i[CPU0 ] | EAX=00000010 EBX=00000000 ECX=00000002 EDX=00000000
00000794843i[CPU0 ] | ESP=00014ff8 EBP=00000000 ESI=00007343 EDI=0000ffde
00000794843i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00000794843i[CPU0 ] | SEG selector base limit G D
00000794843i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00000794843i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00000794843i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00000794843i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00000794843i[CPU0 ] | ES:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000794843i[CPU0 ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000794843i[CPU0 ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000794843i[CPU0 ] | EIP=0001074e (0001074e)
00000794843i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00000794843i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00000794843i[CPU0 ] >> call far 0000:00000000 : 9A000000000000
00000794843e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
[/tt] :(
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:So I switch into Pmode and I call my kernel when

Post by Pype.Clicker »

erhm, correct me if i'm wrong, but those "memory model" things are typical from 16 bit code... are you sure you're not encapsulating your 32bit code in a 16bit binary ?
REV

Re:So I switch into Pmode and I call my kernel when

Post by REV »

JLOC is putting everything into a binary. I belive its 32-bit. How can I check and if its not put everything into a 32-bit binary?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:So I switch into Pmode and I call my kernel when

Post by Pype.Clicker »

typically, you'll have a tool to scrutinize your binaries (except if you ask for a flat binary, of course) ... Using the gnu toolchain, this is "objdump", i don't know for JLOC.

The core idea would be to disassemble your code sections as 32 bit and see if they're valid code. if it's actually 16 bit code read as 32 bit code, you'll get some non-sense immediates (that is, two bytes of opcode appended to your 16-bit constant to form a new 32-bit constant, etc.)
REV

Re:So I switch into Pmode and I call my kernel when

Post by REV »

What kind of tool can do that and how do I look for 16/32?
Also if it is producing 16-bit code how can I fix this?
(Maybye if I make Watcom produce an EXE Dos32 file it will produce 32-bit OBJS.) Ill try that but can anyone help me with the binary stuff?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:So I switch into Pmode and I call my kernel when

Post by Candy »

Disassembling: I'd recommend "objdump -d" for formatted types and "ndisasm" for unformatted types.

Determining which it should be: You can learn to read the byte code as I did above or you can look at what the disassemblers make of it. The byte code above was pretty easy, it started with E9 which is a relative jump or call in assembly, which has either a 2-byte (16-bit) offset or a 4-byte (32-bit) offset. You can be happy it didn't compile to EB, which is a 1-byte offset in both cases.

As for practical stuff, I would very strongly recommend you (as I've done a number of times before to varying people): use the Bochs debugger, either by compiling your bochs to use debugging or by using bochsdbg.exe instead of bochs.exe. Put a breakpoint at the address you load whatever you're debugging, then step through it as it proceeds. Since your code faults at the first instruction, you don't have to step far. The bochs debugger disassembles your code for you, which it now (2.3pre2 +) does properly in long mode too. It can be wrong however, it can be useful to know a bit.


Of course, knowledge is key.
REV

Re:So I switch into Pmode and I call my kernel when

Post by REV »

Ill try that :D
Well it actually dosn't faulter at the first instruction.
It faults when I call my C/C++ code.
REV

Re:So I switch into Pmode and I call my kernel when

Post by REV »

Well when it calls the C/C++ code the debugger pointed out:
[tt]
(0) [0x00000007] 0008:0007 (unk. ctxt): lock push ebx ; f053
[/tt]
A stack operation. (I assume) Well the code in the second stage is "call main_". My stack is at address is setup properly as well. But you guys prolly know whats really going better than I do.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:So I switch into Pmode and I call my kernel when

Post by Candy »

REV wrote: Well when it calls the C/C++ code the debugger pointed out:
[tt]
(0) [0x00000007] 0008:0007 (unk. ctxt): lock push ebx ; f053
[/tt]
A stack operation. (I assume) Well the code in the second stage is "call main_". My stack is at address is setup properly as well. But you guys prolly know whats really going better than I do.
Stack operations cannot be locked (at least, afaik). I think this is an invalid instruction. The address makes me suspect you're executing the IVT, the pmode address makes me guess you created 16-bit pmode segments and forgot to adjust the base (and/or forgot that they can't contain more than 64k).

AMD manual, page 10 in a very old revision that I happen to have on hardcopy:

" The LOCK prefix can only be used with forms of the following instructions that write a memory operand: ADC, ADD, AND, BTC, BTR, BTS, CMOXCHG, CMPXCHG8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XADD, XCHG and XOr. An invalid opcode exception occurs if the LOCK prefix is used with any other instruction."

Note that CMPXCHG16B is also absent, this was an intel thing that AMD adopted after 2002 (so it isn't in my books).
REV

Re:So I switch into Pmode and I call my kernel when

Post by REV »

==This is my GDT==
[tt]
gdt:            ;This is a pointer. Its value will be help calculate its size

gdt_null:    ;Null Segment
   dw 0         ;Fill it up with 0s
   dw 0         ;More 0s
   db 0
   db 0
   db 0
   db 0

gdt_code:         ;Our code segment will be defined here
   ;First Double word
   dw 0FFFFh      ;Make this 4GB in size
   dw 0         ;The first 16-bits of the base address

   ;Second Double Word
   db 0         ;Bits 16-23 of the base address
   db 10011010b      ;Present = 1 Privilage = 0 Code = 1 CF = 0 Readable = 1 AF = 0
   db 11001111b      ;Granularity = 1 Size = 1 Reserved = 0 ASP = 0 Limit = 4GB
   db 0         ;Last 24-31 of base address
gdt_data:         ;Our data segment will be defined here
   ;First Double word
   dw 0FFFFh      ;Make this 4GB in size
   dw 0         ;The first 16-bits of the base address

   ;Second Double Word
   db 0         ;Bits 16-23 of the base address
   db 10010010b      ;Present = 1 Privilage = 0 Code = 0 CF = 0 Readable = 1 AF = 0
   db 11001111b      ;Granularity = 1 Size = 1 Reserved = 0 ASP = 0 Limit = 4GB
   db 0         ;Last 24-31 of base address
[/tt]

==This is the kernel code==
All my assembly code is:
[tt]
[extern main_]            ;NASM directive for the C function main()
SECTION .text USE32         ;NASM directive for code
[bits 32]            ;NASM directive to use 32-bit instructions
   call main_         ;Call the C/C++ code
   cli            ;Disable interrupts
   hlt            ;Halt the CPU
[/tt]

This is my C/C++ code:
[tt]
unsigned char *text = (char *)0xB80000;

void main();

void main() {
   *text++ = '!';
   *text++ = 7;
   while(1) { }
}
[/tt]
Post Reply