Annotation of Net2/arch/i386/netboot/start.s, revision 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.