Annotation of Net2/arch/i386/netboot/start.s, revision 1.1.1.1

1.1       root        1: /* netboot
                      2:  *
                      3:  * start.s,v
                      4: # Revision 1.1  1993/07/08  16:04:11  brezak
                      5: # Diskless boot prom code from Jim McKim ([email protected])
                      6: #
                      7:  * Revision 1.3  1993/06/30  20:19:14  mckim
                      8:  * Exit to BIOS support added.
                      9:  *
                     10:  * Revision 1.2  1993/05/28  20:01:30  mckim
                     11:  * Fixed various StartProg() problems.
                     12:  *
                     13:  * Revision 1.1.1.1  1993/05/28  11:41:08  mckim
                     14:  * Initial version.
                     15:  *
                     16:  */
                     17: 
                     18: #include "asm.h"
                     19: 
                     20: /* At entry, the processor is in 16 bit real mode and the code is being
                     21:  * executed from an address it was not linked to. Code must be pic and
                     22:  * 32 bit sensitive until things are fixed up.
                     23:  */
                     24: 
                     25:        .word   0xaa55                  /* bios extension signature */
                     26:        .byte   0                       /* no. of 512B blocks */
                     27:        jmp     1f                      /* enter from bios here */
                     28:        .byte   0                       /* checksum */
                     29: 1:
                     30:        cli
                     31:        # save the bios return address in these registers until protected
                     32:        # mode %ds is set up
                     33:        #       mov     (%esp), %edx
                     34:        #       mov     2(%esp), %ebp
                     35:        pop     %dx                     /* return offset */
                     36:        pop     %ebp                    /* return segment */
                     37: 
                     38:        /*  save stack [, data] context in case we are under dos */
                     39:        mov     %esp, %ecx
                     40:        mov     %ss, %ax
                     41:        mov     %eax, %ebx
                     42: 
                     43:        /* set up a usable stack */
                     44:        .byte   0xb8                    /* (mov $0xa000, %ax) */
                     45:        .word   0xa000
                     46:        mov     %ax, %ss
                     47:        xor     %esp, %esp
                     48: 
                     49:        push    %ebp                    /* return segment */
                     50:        push    %dx                     /* return offset */
                     51:        push    %ds
                     52: 
                     53: #if 0
                     54:        jmp     ret16
                     55: #endif
                     56: 
                     57: 
                     58: #ifdef CHECK_386
                     59:        # check if 386 or later
                     60:        # from Intel i486 programmer\'s reference manual, section 22.10
                     61:        # Care must be taken with the first few instructions to ensure
                     62:        # operations are compatible with 386 progenitors - no operand
                     63:        # or address size overrides, all operations must be 16 bit.
                     64:        # Real mode not well supported by gas so it looks a bit crufty
                     65: 
                     66:        # TBD - there is little stack space, although the routine below
                     67:        # uses only two bytes; might set up new stack first thing, then
                     68:        # check processor type - would mean carrying sp, ss in two gp
                     69:        # registers for a while. also make alternate provisions for saving
                     70:        # ds: below.
                     71: 
                     72:        pushf
                     73:        pop     %ebx
                     74:        .byte   0x81, 0xe3              /* (and 0x0fff, %ebx) */
                     75:        .word   0x0fff
                     76:        push    %ebx
                     77:        popf
                     78:        pushf
                     79:        pop     %eax
                     80:        .byte   0x25                    /* (and 0xf000, %eax) */
                     81:        .word   0xf000
                     82:        .byte   0x3d                    /* (cmp 0xf000, %eax) */
                     83:        .word   0xf000
                     84:        jz      Lwrong_cpu              /* \'86 */
                     85:        .byte   0x81, 0xcb              /* (or 0xf000, %ebx) */
                     86:        .word   0xf000
                     87:        push    %ebx
                     88:        popf
                     89:        pushf
                     90:        pop     %eax
                     91:        .byte   0x25                    /* (and 0xf000, %eax) */
                     92:        .word   0xf000
                     93:        jnz     Lcpu_ok                 /* else is \'286 */
                     94: 
                     95: Lwrong_cpu:
                     96:        .byte   0xbb                    /* (mov bad_cpu_msg, %ebx) */
                     97:        .word   bad_cpu_msg
                     98:        .byte   0xe8                    /* (call xputs) */
                     99:        .word   xputs-.-2
                    100:        lret
                    101: 
                    102: xputc: /* print byte in %al */
                    103:        data32
                    104:        pusha
                    105:        .byte   0xbb                    /* (mov $0x1, %ebx) %bh=0, %bl=1 (blue) */
                    106:        .word   0x0001
                    107:        movb    $0xe, %ah
                    108:        # sti
                    109:        int     $0x10                   /* display a byte */
                    110:        # cli
                    111:        data32
                    112:        popa
                    113:        ret
                    114: 
                    115: xputs: /* print string pointed to by cs:bx */
                    116:        data32
                    117:        pusha
                    118: 1:
                    119:        cs
                    120:        .byte   0x8a, 0x07              /* (mov (%ebx), %al) */
                    121:        cmpb    $0, %al
                    122:        jz      1f
                    123:        push    %ebx
                    124:        .byte   0xe8                    /* (call xputc) */
                    125:        .word   xputc-.-2
                    126:        pop     %ebx
                    127:        inc     %ebx
                    128:        jmp     1b
                    129: 1:
                    130:        data32
                    131:        popa
                    132:        ret
                    133: 
                    134: bad_cpu_msg:   .asciz  "netboot: cpu cannot execute '386 instructions, net boot not done.\n\r"
                    135: 
                    136: Lcpu_ok:
                    137:        # at this point it is known this can execute 386 instructions
                    138:        # so operand and address size prefixes are ok
                    139: #endif /* CHECK_386 */
                    140: 
                    141:        /* copy rom to link addr, prepare for relocation */
                    142:         xor     %esi, %esi             /* source */
                    143:         opsize
                    144:         mov     $0, %edi               /* destination */
                    145:         opsize
                    146:         mov     $(RELOC)>>4, %eax
                    147:         mov     %ax, %es
                    148:         opsize
                    149:        mov     $(ROM_SIZE), %ecx               /* count */
                    150:         cs
                    151:         rep
                    152:         movsb
                    153: 
                    154:        addrsize
                    155:        cs
                    156:        lgdt    gdtarg-RELOC
                    157: 
                    158:        /* turn on protected mode */
                    159:        cli
                    160:        mov     %cr0, %eax
                    161:        opsize
                    162:        or      $CR0_PE, %eax
                    163:        mov     %eax, %cr0
                    164: 
                    165:        /* jump to relocation, flush prefetch queue, and reload %cs */
                    166:        opsize
                    167:        ljmp    $KERN_CODE_SEG, $1f
                    168: 1:
                    169:        /* reload other segment registers */
                    170:        movl    $KERN_DATA_SEG, %eax
                    171:        movl    %ax, %ds
                    172:        movl    %ax, %es
                    173:        movl    %ax, %ss
                    174:        movl    $0xa0000, %esp
                    175:        call    _main
                    176:        call    _exit
                    177: 
                    178: _ExitToBios:
                    179:        .globl _ExitToBios
                    180:        /* set up a dummy stack frame for the second seg change. */
                    181:        mov     $(RELOC)>>4, %eax
                    182:        pushw   %ax                     /* real cs */
                    183:        pushw   $2f                     /* real pc */
                    184: 
                    185:        /* Change to use16 mode. */
                    186:        ljmp    $BOOT_16_SEG, $1f       /* jump to a 16 bit segment */
                    187: 1:
                    188:        /* clear the PE bit of CR0 */
                    189:        mov     %cr0, %eax
                    190:        opsize
                    191:        and     $0!CR0_PE, %eax
                    192:        mov     %eax, %cr0
                    193: 
                    194:        /* make intersegment jmp to flush the processor pipeline
                    195:         * using the fake stack frame set up earlier
                    196:         * and reload CS register
                    197:         */
                    198:        lret
                    199: 2:
                    200:        /* we are in real mode now
                    201:         * set up the real mode segment registers : DS, SS, ES
                    202:         */
                    203:        movw    %cs, %ax
                    204:        movw    %ax, %ds
                    205:        movw    %ax, %ss
                    206:        movw    %ax, %es
                    207: 
                    208: ret16: /* temporary label - remove (TBD) */
                    209:        /* now in dumbed down mode, caveats */
                    210:        /* restore old context and return to whatever called us */
                    211:        pop     %ds
                    212:        pop     %dx
                    213:        pop     %ebp
                    214: 
                    215:        mov     %ebx, %eax
                    216:        mov     %ax, %ss
                    217:        mov     %ecx, %esp
                    218: 
                    219:        push    %ebp
                    220:        push    %dx     
                    221:        sti
                    222:        lret
                    223: 
                    224: #ifdef USE_BIOS
                    225: _real_to_prot:
                    226:        .global _real_to_prot
                    227: 
                    228:        addrsize
                    229:        cs
                    230:        lgdt    gdtarg-RELOC
                    231:        cli
                    232:        mov     %cr0, %eax
                    233:        opsize
                    234:        or      $CR0_PE, %eax
                    235:        mov     %eax, %cr0
                    236: 
                    237:        /* jump to relocation, flush prefetch queue, and reload %cs */
                    238:        opsize
                    239:        ljmp    $KERN_CODE_SEG, $1f
                    240: 1:
                    241:        movl    $KERN_DATA_SEG, %eax
                    242:        movl    %ax, %ds
                    243:        movl    %ax, %es
                    244:        movl    %ax, %ss
                    245: 
                    246:        ret
                    247: #endif
                    248: 
                    249: #ifdef USE_BIOS
                    250: _prot_to_real:
                    251:        .global _prot_to_real
                    252: 
                    253:        /* set up a dummy stack frame for the second seg change. */
                    254:        movl    $(RELOC), %eax
                    255:        sarl    $4, %eax
                    256:        pushw   %ax                     /* real cs */
                    257:        pushw   $2f                     /* real pc */
                    258: 
                    259:        /* Change to use16 mode. */
                    260:        ljmp    $BOOT_16_SEG, $1f       /* jump to a 16 bit segment */
                    261: 1:
                    262:        /* clear the PE bit of CR0 */
                    263:        mov     %cr0, %eax
                    264:        opsize
                    265:        and     $0!CR0_PE, %eax
                    266:        mov     %eax, %cr0
                    267: 
                    268:        /* make intersegment jmp to flush the processor pipeline
                    269:         * using the fake stack frame set up earlier
                    270:         * and reload CS register
                    271:         */
                    272:        lret
                    273: 2:
                    274:        /* we are in real mode now
                    275:         * set up the real mode segment registers : DS, SS, ES
                    276:         */
                    277:        movw    %cs, %ax
                    278:        movw    %ax, %ds
                    279:        movw    %ax, %ss
                    280:        movw    %ax, %es
                    281: 
                    282:        opsize
                    283:        ret
                    284: #endif
                    285: 
                    286:        .align  4
                    287: gdt:
                    288:        .word   0, 0
                    289:        .byte   0, 0x00, 0x00, 0
                    290: 
                    291:        /* code segment */
                    292:        .word   0xffff, 0
                    293:        .byte   0, 0x9f, 0xcf, 0
                    294: 
                    295:        /* data segment */
                    296:        .word   0xffff, 0
                    297:        .byte   0, 0x93, 0xcf, 0
                    298: 
                    299:        /* 16 bit real mode */
                    300:        .word   0xffff, 0
                    301:        .byte   0, 0x9e, 0x00, 0
                    302: 
                    303:        .align  4
                    304: gdtarg:
                    305:        .word   0x1f                    /* limit */
                    306:        .long   gdt                     /* addr */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.