Hi all,<br>     I am trying to make optionrom can be run in PM 32 bit mode, and my work flow is  1)load gdt 2)open A20 3) set cro bit 4) take the long jump to 32 bit PM. After step 3) optionrom has already in 16bit PM,but the long jump did not work, which should run in to 32bit PM. I paste the whole assemble file here. Is there any one who can give  a hand about this?<br>
<br><br><br>.text<br>.code16 # Real mode by default (prefix 66 or 67 to 32 bits instructions)<br><br><br>rom_size        = 0x04      # ROM size in multiple of 512 bytes<br>os_load_seg     = 0x0000    # this is working if lgdt is passed with an absolute address <br>
os_code_size    = ((rom_size - 1)*512)<br>os_code_size16  = ( os_code_size / 2 )<br>_base_address:    <br>    .word 0xAA55   # Rom signature <br>    .byte rom_size # Size of this ROM, see definition above <br>    jmp _init      # jump to PCI initialization function<br>
<br>    .org 0x18<br>    .word _pci_data_struct # Pointer to PCI HDR structure (at 18h)<br>    .word _pnp_header      # PnP Expansion Header Pointer (at 1Ah)<br><br># --------------------------------------------<br># PCI data structure<br>
#<br>_pci_data_struct:<br>    .ascii  "PCIR"   # PCI Header Sign<br>    .word   0x8086   # Vendor ID<br>    .word   0x7000   # Device ID<br>    .word   0x00     # VPD<br>    .word   0x18     # PCI data struc length (byte)<br>
    .byte   0x00     # PCI Data struct Rev<br>    .byte   0x02     # Base class code, 02h == Network Controller<br>    .byte   0x00     # Sub class code = 00h and interface = 00h -->Ethernet Controller<br>    .byte   0x00     # Interface code, see PCI Rev2.1 Spec Appendix D<br>
    .word   rom_size # Image length in mul of 512 byte, little endian format<br>    .word   0x00     # rev level<br>    .byte   0x00     # Code type = x86<br>    .byte   0x80     # last image indicator<br>    .word   0x00     # reserved<br>
<br># -----------------------------<br># PnP ROM Bios Header<br>#<br>_pnp_header:<br>    .ascii "$PnP"         # PnP Rom header sign<br>    .byte  0x01           # Structure Revision<br>    .byte  0x02           # Header structure Length in mul of 16 bytes<br>
    .word  0x00           # Offset to next header (00 if none)<br>    .byte  0x00           # reserved<br>    .byte  0x00           # 8-Bit checksum for this header, calculated and patched by build_rom <br>    .long  0x00           # PnP Device ID (0h in Realtek RPL ROM, we just follow it)<br>
    .word  0x00           # pointer to manufacturer string, we use empty string<br>    .word  0x00           # pointer to product string, we use empty string<br>    .byte  0x02,0x00,0x00 # Device Type code 3 byte<br>    .byte  0x14           # Device Indicator, 14h from Realtek RPL ROM-->See Page 18 of<br>
                          # PnP BIOS spec., Lo nibble (4) means IPL device<br><br>    .word  0x00     # Boot Connection Vector, 00h = disabled<br>    .word  0x00     # Disconnect Vector, 00h = disabled<br>    .word  _start   # Bootstrap Entry Vector (BEV)<br>
    .word  0x00     # reserved<br>    .word  0x00     # Static resource Information vector (0000h if unused)<br><br>#--------------------------------------------------------------------<br># PCI Option ROM initialization Code (init function)<br>
#<br>_init:<br>///////////////////////////////////////////////<br>1:    jmp 1b<br>    jmp _setup<br>    ret<br>////////////////////////////////////////////////////////<br>  andw $0xCF, %ax # inform system BIOS that an IPL device attached<br>
  orw  $0x20, %ax # see PnP spec 1.0A p21 for info's<br><br>  lret # return far to system BIOS<br><br>#--------------------------------------------------------------------<br># entry point/BEV implementation (invoked during bootstrap / int 19h)<br>
#<br>  .global _start # entry point<br><br>_start:<br>  movw $0x9000, %ax # setup temporary stack<br>  movw %ax, %ss     # ss = 0x9000<br><br># move ourself from "ROM" -> RAM 0x0000<br>  movw %cs, %ax          # initialize source address<br>
  movw %ax, %ds <br>  movw $os_load_seg, %ax # point to OS segment<br>  movw %ax, %es<br>  movl $os_code_size16, %ecx<br>  subw %di, %di<br>  subw %si, %si        <br>  cld<br>  rep <br>  movsw<br><br>  ljmp $os_load_seg, $_setup<br>
<br>_setup:<br>  movw %cs, %ax    # initialize segment registers (this is needed since lgdt is %ds dependent??)<br>  movw %ax, %ds    <br>xorl %eax,%eax # Compute gdt_base<br>movw %cs,%ax # (Convert %ds:gdt to a linear ptr)<br>
shll $4, %eax<br>addl $(gdt_desc), %eax<br>movl %eax, (gdt_desc+2)<br> lgdt (gdt_desc)  # load GDT to GDTR (we load both limit and base address)<br><br># ---------------------------------------------------------------------<br>
# Switch to P-Mode and jump to C-Compiled kernel<br>#<br>  cli            # disable interrupt<br>  // enable a20<br>  inb $0x0092, %al<br>  orb $0x02, %al<br>  outb %al, $0x0092<br><br> <br> <br>  movl %cr0, %eax     # switch to P-Mode<br>
  or   $1, %eax<br>  movl %eax, %cr0     # haven't yet in P-Mode, we need a FAR Jump<br><br>  .byte 0x66, 0xea   # prefix + jmpi-opcode (this force P-Mode to be reached i.e. CS updated)<br>  .long do_pm        # 32-bit linear address (jump target)<br>
  .word SEG_CODE_SEL # code segment selector<br><br>.code32<br>do_pm:<br> // xorl %esi, %esi<br> // xorl %edi, %edi<br>  movw $0x10, %ax  # Save data segment identifier (see GDT)<br>  movw %ax, %ds<br>  movw $0x18, %ax  # Save stack segment identifier<br>
  movw %ax, %ss<br>  movl $0x90000, %esp<br><br>  jmp  main # jump to main function<br><br>  .align 8, 0 # align GDT in 8 bytes boundary<br><br># -----------------------------------------------------<br>#            GDT definition<br>
#<br>gdt_marker:   # dummy Segment Descriptor (GDT)<br>  .long 0<br>  .long 0<br><br>SEG_CODE_SEL = ( . - gdt_marker)<br>SegDesc1:      # kernel CS (08h) PL0, 08h is an identifier<br>  .word 0xffff # seg_length0_15<br>  .word 0      # base_addr0_15<br>
  .byte 0      # base_addr16_23<br>  .byte 0x9A   # flags 9b?<br>  .byte 0xcf   # access<br>  .byte 0      # base_addr24_31<br><br>SEG_DATA_SEL = ( . - gdt_marker)<br>SegDesc2:      # kernel DS (10h) PL0<br>  .word    0xffff # seg_length0_15<br>
  .word    0      # base_addr0_15<br>  .byte     0      # base_addr16_23<br>  .byte     0x92   # flags <br>  .byte     0xcf   # access<br>  .byte     0      # base_addr24_31<br><br>SEG_STACK_SEL = ( . - gdt_marker)<br>SegDesc3:      # kernel SS (18h) PL0<br>
  .word 0xffff # seg_length0_15<br>  .word 0      # base_addr0_15<br>  .byte 0      # base_addr16_23<br>  .byte 0x92   # flags<br>  .byte 0xcf   # access<br>  .byte 0      # base_addr24_31<br>gdt_end:<br><br>gdt_desc:  .word (gdt_end - gdt_marker - 1) # GDT limit<br>
.long (gdt_marker - _base_address-8) # physical addr of GDT<br><br clear="all"><br>-- <br>Jason Wang <br>Peking University<br>