[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

A problem about i386ex board



> > biguo at 263.net wrote:
> > 
> > > > biguo at 263.net wrote:
> > > >
> > > > > > biguo at 263.net wrote:
> > > > > >
> > > > > > > > biguo at 263.net wrote:
> > > > > > > >
> > > > > > > > > hello,everyone!Recently I met a strange problem about i386ex board.In last a few weeks I have completely burn and run the hello_world_c DEMO."hello world" have been appeared in com2.But since 26,July,there are no any reponse after hello_world_c demo is burned and run.I have made no changes about Linux and RTEMS.But I compiled a program with other cross compiler,such as MOCROTEC V> TE> X.Af> ter > the > program is burned and run in i386ex board,it's all fine.Why?Are there something wrong with cross gcc compiler or i386ex board?I'm puzzled.Can anybody tell me the possible reasons?Thanks in advance for any help.
> > > > > > > > >
> > > > > > > > > _____________________________________________
> > > > > > > > > ????????--???????????????????? http://www.263.net
> > > > > > > > > ???????? ???????? ???????? ???????? ??????????
> > > > > > > > > ???????? ???????? ???????? ???????? ????????
> > > > > > > > > ???????? ???????? ???????? ???????? ????????
> > > > > > > >
> > > > > > > >   There is a possible problem with your start.S file.  Please insert these two nop instructions into start.S:
> > > > > > > >
> > > > > > > >  .section .initial
> > > > > > > >  nop  /* required for linker -- initial jump is to "label - 2"   */
> > > > > > > >  nop  /* ie. _initInternalRegisters -2 ( which now == .initial ) */
> > > > > > > >
> > > > > > > > If you're start.S already has these two nop's then I don't know what could be wrong.  Please tell me if your start.S has or does not have these two nop instructions, and I will provide a patch to the RTEMS people.
> > > > > > > >
> > > > > > > > Thanks.
> > > > > > >
> > > > > > > > (????:??????"text/x-vcard",??????"vcard.vcf")
> > > > > > > >
> > > > > > >
> > > > > > > Mr. ivanenko:
> > > > > > >    You're right.There aren't two "nop" instructions before SYM( _initInternalRegisters) in start.s.I add two "nop" instructions there.It's all fine.But I don't understand what's the reason.Is it relative with gcc?Is it relative with INTEL X86 processor?Thank you.
> > > > > > >
> > > > > > > _____________________________________________
> > > > > > > ????????--???????????????????? http://www.263.net
> > > > > > > ???????? ???????? ???????? ???????? ??????????
> > > > > > > ???????? ???????? ???????? ???????? ????????
> > > > > > > ???????? ???????? ???????? ???????? ????????
> > > > > >
> > > > > > This is a programming problem:
> > > > > >
> > > > > > The problem is because gcc is defaulting to .code32, so the instruction jmp SYM(_initInternalRegisters) is assuming that the jmp offset is rel32.  This means that an address  4 bytes long is the offset specified by the compiler for the jump instruction.   Hence, the compiler sets the offset relative to the next instruction, which is 4 bytes away.
> > > > > >
> > > > > > But the processor is running in real mode at this time, hence the address of the jump offset can only be two bytes long.   So,  the processor assumes that the address of the next instruction is only 2 bytes away, and uses that address instead as the base for the jmp.
> > > > > >
> > > > > > Since the jump is a near jump, only the lower 16 bits of the address are significant.   The jump actually does jump two bytes too far.  Adding the 2 nops solves this problem without assuming that the compiler is capable of understanding the .code16 directive.  It also makes a dissassembled listing readable.
> > > > > >
> > > > > > If you are using a compiler that supports the .code16 directive, putting it before the .reset section SHOULD also work, but then disassembly with objdump will fail.
> > > > > >
> > > > > > I do not have a working test facility for the board available at this time. If you could try adding .code16 before the jmp SYM(_initInternalRegisters) and removing the two nops, I'd love to know if it actually works -- the final srecord in hello.i does show a change in the offset and size of instruction.
> > > > > >
> > > > > >
> > > > > >
> > > > >
> > > > > > (????:??????"text/x-vcard",??????"vcard.vcf")
> > > > > >
> > > > >
> > > > > Because SYM(_initInternalRegisters) is public symbol,I find out that it has been allocated to 4 bytes address by gcc.Though I add .code16 before .reset section,it doesn't work.If SYM(_initInternalRegisters) isn't a public symbol,it will be 2 bytes.Hence,it works well.Meanwhile,I use disassembler to find out that SYM(_initInternalRegisters) is a 2 bytes address at this time.Why SYM(_initI> nt> erna> lRegisters) is defined as public symbol?Is SYM(_initInternalRegisters) defined as a local symbole?If so,don't need to add two "nop" instruction before SYM(_initInternalRegisters).Which choice is more reasonable?
> > > > > The modified part of start.s look like as the following:
> > > > >         .
> > > > >         .
> > > > >         .
> > > > > /*PUBLIC( SYM(_initInternalRegisters) )*/
> > > > >         .
> > > > >         .
> > > > >         .
> > > > >      .section .reset
> > > > >
> > > > >
> > > > >                 PUBLIC ( SYM(reset) )
> > > > > SYM(reset):
> > > > >         .code16  /*ADD*/
> > > > >         nop
> > > > >         cli
> > > > >         cld
> > > > >         jmp     SYM(_initInternalRegisters) /* different section in this file */
> > > > >         .code32                             /* in case this section moves     */
> > > > >         nop                       /* required by CHIP LAB to pad out size */
> > > > >         nop
> > > > >         nop
> > > > >         nop
> > > > >         nop
> > > > >
> > > > >
> > > > >
> > > > >         .section .initial
> > > > >
> > > > > SYM(_initInternalRegisters):
> > > > >         .code16
> > > > >
> > > > > _____________________________________________
> > > > > ????????--???????????????????? http://www.263.net
> > > > > ???????? ???????? ???????? ???????? ??????????
> > > > > ???????? ???????? ???????? ???????? ????????
> > > > > ???????? ???????? ???????? ???????? ????????
> > > >
> > > > This looks like a bug.   It should not matter if the symbol is public or local.
> > > >
> > > > When I compile with the .code16 and local _initInternalRegisters  symbol, the SREC I get shows these codes.
> > > >
> > > > 90             nop
> > > > FA           cli
> > > > E9 97 20  jmp <offset>
> > > > 90              nop
> > > > 90              nop
> > > >
> > > >
> > > > When I compile using .code16 and the public _initInternalRegisters symbol, the jmp becomes:
> > > >
> > > > E9 9A 20 jmp <offset>
> > > >
> > > > In both cases, _initInternalRegisters is located at the same address: 3ff2092.  Clearly, using the public symbol make a difference.  I have not run this code -- I am only seeing that there is a real difference.
> > > >
> > > >
> > >
> > > > (????:??????"text/x-vcard",??????"vcard.vcf")
> > > >
> > > I think about the problem  again.Maybe that _initInternalRegisters is defined as a public symbol is meaning because in embedded RT system sometimes system need to automatically reset after collapsing.Thus,a error handlering program can jmp to _initInternalRegisters to reset.
> > 
> > This is true, you could use it that way.
> > 
> > > Another,I think it more clear that changing  "jmp SYM(_initInternalRegisters)" to "jmp SYM(_initInternalRegisters)+2" than adding two "nop" instructions before SYM(_initInternalRegisters).I remember that in DOS assemble language if adding prefix "DB 66" before "jmp SYM(_initInternalRegisters)",program can correctly handler 32 bit address in real mode.
> > 
> > The DB 66 should be unnecessary, since the .code16 directive is supposed to work.  I think I know the problem!  Either the .code16 directive should appear BEFORE the SYM(_initInternalRegisters), or the .code32 after the jmp in the reset section should be removed.....  I'd put .code16 before .reset and remove .code32.  This may invalidate the reset by  jump to  _initInternalRegisters in case th> e > system "collapeses".   It looks like the linker is having trouble linking jumps between .code16 and .code32 sections.
> > 
> > Could you check this out?  I don't have a target available.
> > 
> > > But in linux  assemble language I don't know the syntax.Hence,I can't test it.Which choice is more reasonable?
> > >
> > 
> >  I used to insert DB 66 by using the "data16" directive.  eg data16; movl $0x0, eax;  this would make the processor realize that the operand was 4 bytes long while running in real mode .  I think this no longer works since the .code16 directive has been created.
> 
> 
> > (????:??????"text/x-vcard",??????"vcard.vcf")

 
I add "data16" before "jmp  SYM(_initInternalRegisters)",not add ".code16".It works well.I use objdump to disassemble test.coff.The result is "66 e9 47 jmp 4e <Interrupt_descriptor_Table+0x48>".I think this solution is better.It is more clear in start.s while  _initInternalRegisters is kept as a public symbol.What's your idea?


_____________________________________________
????????--???????????????????? http://www.263.net
???????? ???????? ???????? ???????? ??????????
???????? ???????? ???????? ???????? ????????
???????? ???????? ???????? ???????? ????????