!************************************************************************** !* !* Network driver interface for netboot bootrom !* !* Module: undi.S !* Purpose: Initialize the UNDI driver interface !* Entries: drv_load, drv_entry !* !************************************************************************** !* !* Copyright (C) 1998-2003 Gero Kuhlmann !* !* This program is free software; you can redistribute it and/or modify !* it under the terms of the GNU General Public License as published by !* the Free Software Foundation; either version 2 of the License, or !* any later version. !* !* This program is distributed in the hope that it will be useful, !* but WITHOUT ANY WARRANTY; without even the implied warranty of !* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !* GNU General Public License for more details. !* !* You should have received a copy of the GNU General Public License !* along with this program; if not, write to the Free Software !* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. !* !* $Id: undi.S,v 1.4 2003/01/25 23:29:42 gkminix Exp $ !* ! !************************************************************************** ! ! Include assembler macros: ! #include #include #include ! !************************************************************************** ! ! Data segment: ! .data idstr: .ascii "UNDI" ! UNDI driver ID string idstrend: ! !************************************************************************** ! ! Start code segment. ! .text public drv_load ! define entry points public drv_entry ! Variables in code segment extrn txtseg ! General library external routines extrn prnstr ! !************************************************************************** ! ! The address of the UNDI entry point has to be within the text segment ! in order to allow to access it via CS. ! undi_entry: .long 0 ! !************************************************************************** ! ! Load and initialize the UNDI driver interface. When an error ! occurred, it will print an error message before returning. ! Input: ES:SI - pointer to network driver source ! DX - first usable paragraph for network driver ! Output: AX - PXE error code ! Registers changed: AX, BX, CX, DX, SI, DI, ES ! drv_load: ! Check that the UNDI driver is correct. An UNDI driver image starts with ! the following structure: ! ! 0000 - ID string "UNDI" ! 0004 - size of text segment in bytes ! 0006 - size of data segment in bytes ! 0008 - size of BSS segment in bytes ! 000A - offset to driver entry point within text segment cld mov di,si mov si,#idstr mov cx,#idstrend - idstr repe cmpsb ! check that the driver starts with jne load8 ! the proper signature seg es mov ax,[di + $0000] ! get size of text segment mov cx,ax add ax,#$000F rcr ax,#1 ! adjust to paragraph boundary shift (shr,ax,3) seg es add cx,[di + $0002] ! get size of data segment seg es mov bx,[di + $0004] ! get size of BSS segment add bx,#$000F rcr bx,#1 ! adjust to paragraph boundary shift (shr,bx,3) add ax,bx add ax,dx ! compute end segment seg cs cmp ax,txtseg ! check if space is sufficient jbe load1 load8: mov bx,#errmsg call prnstr ! print error message mov ax,#PXENV_EXIT_FAILURE jmp load9 ! Save the pointer to the UNDI driver entry point load1: seg es mov ax,[di + $0006] seg cs mov word ptr [undi_entry + 0],ax seg cs mov word ptr [undi_entry + 2],dx add di,#$0006 ! Now copy the driver into its final place push ds mov si,di ! get pointer to UNDI driver mov ax,es shift (shr,di,4) ! adjust to lowest possible offset add ax,di mov ds,ax and si,#$000F mov es,dx xor di,di ! set pointer to destination area shr cx,#1 rep ! copy words for speed movsw jnc load2 movsb load2: pop ds ! Tell the user that we found something. mov bx,#fndmsg call prnstr xor ax,ax load9: ret ! Messages: errmsg: .byte $0D,$0A .asciz "UNDI ERROR: invalid driver" fndmsg: .byte $0D,$0A .ascii "Found UNDI driver" .byte $0D,$0A,0 ! !************************************************************************** ! ! Jumps to the UNDI driver entry point. ! Input: BX - UNDI function code ! ES:DI - pointer to parameter structure ! Output: AX - error code ! Registers changed: AX, BX, CX, DX, SI, DI, BP, DS, ES ! drv_entry: pop ax push cs ! prepare return address for a far push ax ! return seg cs jmp far ptr [undi_entry] ! !************************************************************************** ! end