mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
Bring in some improved bootp support for netboot submitted by Luigi:
- TFTP is not needed any longer. Add some other improvements: - swapsize is now detected if no value was specified. - resvport is used by default - merged code for setting/showing mount options for root/swap. Submitted by: Luigi Rizzo <luigi@labinfo.iet.unipi.it>
This commit is contained in:
parent
6e5f0e40e6
commit
f811abf08c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=25806
@ -36,7 +36,6 @@ CFLAGS= -O2 -DNFS -DROMSIZE=${ROMSIZE} -DRELOC=${RELOCADDR} # -DASK_BOOT
|
||||
CFLAGS += -DPCI -DPCI_VENDOR=${PCI_VENDOR} -DPCI_DEVICE=${PCI_DEVICE}
|
||||
CFLAGS += -DPCI_CLASS=${PCI_CLASS} -DASK_BOOT
|
||||
#NS8390= -DINCLUDE_WD -DWD_DEFAULT_MEM=0xD0000
|
||||
#NS8390= -DINCLUDE_WD -DWD_DEFAULT_MEM=0xD0000
|
||||
NS8390= -DINCLUDE_NE
|
||||
#NS8390+= -DINCLUDE_3COM -D_3COM_BASE=0x300
|
||||
CLEANFILES+= netboot.com
|
||||
|
@ -203,45 +203,55 @@ cmd_hostname(p)
|
||||
(char*)&nfsdiskless.my_hostnam) + 3) & ~3;
|
||||
else printf("Hostname is: %s\r\n",nfsdiskless.my_hostnam);
|
||||
}
|
||||
|
||||
static void mountopts(prefix,args,p)
|
||||
char *prefix;
|
||||
struct onfs_args *args;
|
||||
char *p;
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (*p) {
|
||||
args->flags = NFSMNT_RSIZE | NFSMNT_WSIZE | NFSMNT_RESVPORT;
|
||||
args->sotype = SOCK_DGRAM;
|
||||
if ((tmp = (char *)substr(p,"rsize=")))
|
||||
args->rsize=getdec(&tmp);
|
||||
if ((tmp = (char *)substr(p,"wsize=")))
|
||||
args->wsize=getdec(&tmp);
|
||||
if ((tmp = (char *)substr(p,"intr")))
|
||||
args->flags |= NFSMNT_INT;
|
||||
if ((tmp = (char *)substr(p,"soft")))
|
||||
args->flags |= NFSMNT_SOFT;
|
||||
if ((tmp = (char *)substr(p,"noconn")))
|
||||
args->flags |= NFSMNT_NOCONN;
|
||||
if ((tmp = (char *)substr(p, "tcp")))
|
||||
args->sotype = SOCK_STREAM;
|
||||
} else {
|
||||
printf("%s mount options: rsize=%d,wsize=%d,resvport",
|
||||
prefix,
|
||||
args->rsize,
|
||||
args->wsize);
|
||||
if (args->flags & NFSMNT_INT)
|
||||
printf (",intr");
|
||||
if (args->flags & NFSMNT_SOFT)
|
||||
printf (",soft");
|
||||
if (args->flags & NFSMNT_NOCONN)
|
||||
printf (",noconn");
|
||||
if (args->sotype == SOCK_STREAM)
|
||||
printf (",tcp");
|
||||
else
|
||||
printf (",udp");
|
||||
printf ("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
CMD_ROOTOPTS - Set root mount options
|
||||
**************************************************************************/
|
||||
cmd_rootopts(p)
|
||||
char *p;
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (*p) {
|
||||
nfsdiskless.root_args.flags = NFSMNT_RSIZE | NFSMNT_WSIZE;
|
||||
nfsdiskless.root_args.sotype = SOCK_DGRAM;
|
||||
if ((tmp = (char *)substr(p,"rsize=")))
|
||||
nfsdiskless.root_args.rsize=getdec(&tmp);
|
||||
if ((tmp = (char *)substr(p,"wsize=")))
|
||||
nfsdiskless.root_args.wsize=getdec(&tmp);
|
||||
if ((tmp = (char *)substr(p,"resvport")))
|
||||
nfsdiskless.root_args.flags |= NFSMNT_RESVPORT;
|
||||
if ((tmp = (char *)substr(p,"intr")))
|
||||
nfsdiskless.root_args.flags |= NFSMNT_INT;
|
||||
if ((tmp = (char *)substr(p,"soft")))
|
||||
nfsdiskless.root_args.flags |= NFSMNT_SOFT;
|
||||
if ((tmp = (char *)substr(p, "tcp")))
|
||||
nfsdiskless.root_args.sotype = SOCK_STREAM;
|
||||
} else {
|
||||
printf("Rootfs mount options: rsize=%d,wsize=%d",
|
||||
nfsdiskless.root_args.rsize,
|
||||
nfsdiskless.root_args.wsize);
|
||||
if (nfsdiskless.root_args.flags & NFSMNT_RESVPORT)
|
||||
printf (",resvport");
|
||||
if (nfsdiskless.root_args.flags & NFSMNT_SOFT)
|
||||
printf (",soft");
|
||||
if (nfsdiskless.root_args.flags & NFSMNT_INT)
|
||||
printf (",intr");
|
||||
if (nfsdiskless.root_args.sotype == SOCK_STREAM)
|
||||
printf (",tcp");
|
||||
else
|
||||
printf (",udp");
|
||||
printf ("\r\n");
|
||||
}
|
||||
mountopts("Rootfs",&nfsdiskless.root_args,p);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
@ -250,39 +260,7 @@ CMD_SWAPOPTS - Set swap mount options
|
||||
cmd_swapopts(p)
|
||||
char *p;
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (*p) {
|
||||
nfsdiskless.swap_args.flags = NFSMNT_RSIZE | NFSMNT_WSIZE;
|
||||
nfsdiskless.swap_args.sotype = SOCK_DGRAM;
|
||||
if ((tmp = (char *)substr(p,"rsize=")))
|
||||
nfsdiskless.swap_args.rsize=getdec(&tmp);
|
||||
if ((tmp = (char *)substr(p,"wsize=")))
|
||||
nfsdiskless.swap_args.wsize=getdec(&tmp);
|
||||
if ((tmp = (char *)substr(p,"resvport")))
|
||||
nfsdiskless.swap_args.flags |= NFSMNT_RESVPORT;
|
||||
if ((tmp = (char *)substr(p,"intr")))
|
||||
nfsdiskless.swap_args.flags |= NFSMNT_INT;
|
||||
if ((tmp = (char *)substr(p,"soft")))
|
||||
nfsdiskless.swap_args.flags |= NFSMNT_SOFT;
|
||||
if ((tmp = (char *)substr(p, "tcp")))
|
||||
nfsdiskless.swap_args.sotype = SOCK_STREAM;
|
||||
} else {
|
||||
printf("Swapfs mount options: rsize=%d,wsize=%d",
|
||||
nfsdiskless.swap_args.rsize,
|
||||
nfsdiskless.swap_args.wsize);
|
||||
if (nfsdiskless.swap_args.flags & NFSMNT_RESVPORT)
|
||||
printf (",resvport");
|
||||
if (nfsdiskless.swap_args.flags & NFSMNT_SOFT)
|
||||
printf (",soft");
|
||||
if (nfsdiskless.swap_args.flags & NFSMNT_INT)
|
||||
printf (",intr");
|
||||
if (nfsdiskless.swap_args.sotype == SOCK_STREAM)
|
||||
printf (",tcp");
|
||||
else
|
||||
printf (",udp");
|
||||
printf ("\r\n");
|
||||
}
|
||||
mountopts("Swapfs",&nfsdiskless.swap_args,p);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -37,12 +37,11 @@ MAIN - Kick off routine
|
||||
main()
|
||||
{
|
||||
int c;
|
||||
char *p;
|
||||
extern char edata[], end[];
|
||||
for (p=edata; p<end; p++) *p = 0; /* Zero BSS */
|
||||
bzero(edata,end-edata); /* Zero BSS */
|
||||
#ifdef ASK_BOOT
|
||||
while (1) {
|
||||
printf("\n\rBoot from Network (Y/N) ? ");
|
||||
printf("\nBoot from Network (Y/N) ? ");
|
||||
c = getchar();
|
||||
if ((c >= 'a') && (c <= 'z')) c &= 0x5F;
|
||||
if (c == '\r') break;
|
||||
@ -60,10 +59,10 @@ main()
|
||||
bootinfo.bi_bios_geom[c] = get_diskinfo(c + 0x80);
|
||||
|
||||
gateA20();
|
||||
printf("\r\nBOOTP/TFTP/NFS bootstrap loader ESC for menu\n\r");
|
||||
printf("\r\nSearching for adapter...");
|
||||
printf("\nBOOTP/TFTP/NFS bootstrap loader ESC for menu\n"
|
||||
"\nSearching for adapter...");
|
||||
if (!eth_probe()) {
|
||||
printf("No adapter found.\r\n");
|
||||
printf("No adapter found.\n");
|
||||
exit(0);
|
||||
}
|
||||
kernel = DEFAULT_BOOTFILE;
|
||||
@ -111,8 +110,10 @@ load()
|
||||
char cmd_line[80];
|
||||
int err, read_size, i;
|
||||
long addr, broadcast;
|
||||
int swsize;
|
||||
unsigned long pad;
|
||||
|
||||
config_buffer[0]='\0'; /* clear; bootp might fill this up */
|
||||
/* Initialize this early on */
|
||||
|
||||
nfsdiskless.root_args.rsize = 8192;
|
||||
@ -120,9 +121,11 @@ load()
|
||||
nfsdiskless.swap_args.rsize = 8192;
|
||||
nfsdiskless.swap_args.wsize = 8192;
|
||||
nfsdiskless.root_args.sotype = SOCK_DGRAM;
|
||||
nfsdiskless.root_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE);
|
||||
nfsdiskless.root_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE |
|
||||
NFSMNT_RESVPORT);
|
||||
nfsdiskless.swap_args.sotype = SOCK_DGRAM;
|
||||
nfsdiskless.swap_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE);
|
||||
nfsdiskless.swap_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE |
|
||||
NFSMNT_RESVPORT);
|
||||
|
||||
|
||||
/* Find a server to get BOOTP reply from */
|
||||
@ -142,6 +145,10 @@ load()
|
||||
printf("\n=>>"); getchar();
|
||||
#endif
|
||||
|
||||
/*** check if have got info from bootp ***/
|
||||
if (config_buffer[0])
|
||||
goto cfg_done;
|
||||
#ifndef NO_TFTP
|
||||
/* Now use TFTP to load configuration file */
|
||||
sprintf(cfg,"/tftpboot/freebsd.%I",arptable[ARP_CLIENT].ipaddr);
|
||||
if (tftp(cfg) || tftp(cfg+10))
|
||||
@ -152,6 +159,8 @@ load()
|
||||
sprintf(cfg,"/tftpboot/cfg.%I",arptable[ARP_CLIENT].ipaddr);
|
||||
if (tftp(cfg) || tftp(cfg+10))
|
||||
goto cfg_done;
|
||||
#endif
|
||||
/* not found; using default values... */
|
||||
sprintf(config_buffer,"rootfs %I:/usr/diskless_root",
|
||||
arptable[ARP_SERVER].ipaddr);
|
||||
printf("Unable to load config file, guessing:\r\n\t%s\r\n",
|
||||
@ -223,11 +232,15 @@ load()
|
||||
}
|
||||
sprintf(swapfile,"swap.%I",arptable[ARP_CLIENT].ipaddr);
|
||||
if (err = nfs_lookup(ARP_SWAPSERVER, swap_nfs_port,
|
||||
&swapfs_fh, swapfile, &nfsdiskless.swap_fh)) {
|
||||
&swapfs_fh, swapfile, &nfsdiskless.swap_fh, &swsize)) {
|
||||
printf("Unable to open %s: ",swapfile);
|
||||
nfs_err(err);
|
||||
longjmp(jmp_bootmenu,1);
|
||||
}
|
||||
if (!nfsdiskless.swap_nblks) {
|
||||
nfsdiskless.swap_nblks = swsize / 1024;
|
||||
printf("Swap size is: %d blocks\n",nfsdiskless.swap_nblks);
|
||||
}
|
||||
nfsdiskless.swap_saddr.sin_len = sizeof(struct sockaddr_in);
|
||||
nfsdiskless.swap_saddr.sin_family = AF_INET;
|
||||
nfsdiskless.swap_saddr.sin_port = htons(swap_nfs_port);
|
||||
@ -261,7 +274,7 @@ load()
|
||||
|
||||
if (err = nfs_lookup(ARP_ROOTSERVER, root_nfs_port,
|
||||
&nfsdiskless.root_fh, *kernel == '/' ? kernel+1 : kernel,
|
||||
&kernel_handle)) {
|
||||
&kernel_handle, NULL)) {
|
||||
printf("Unable to open %s: ",kernel);
|
||||
nfs_err(err);
|
||||
longjmp(jmp_bootmenu,1);
|
||||
@ -587,6 +600,17 @@ await_reply(type, ival, ptr)
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
bootp_string(char *name, char *bootp_ptr)
|
||||
{
|
||||
char tmp_buf[512]; /* oversized, but who cares ! */
|
||||
bzero(tmp_buf, sizeof(tmp_buf));
|
||||
bcopy(bootp_ptr+2, tmp_buf, TAG_LEN(bootp_ptr));
|
||||
sprintf(config_buffer+strlen(config_buffer),
|
||||
"%s %s\n", name, tmp_buf);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
DECODE_RFC1048 - Decodes RFC1048 header
|
||||
**************************************************************************/
|
||||
@ -616,6 +640,22 @@ decode_rfc1048(p)
|
||||
bcopy(p+2, &nfsdiskless.my_hostnam, TAG_LEN(p));
|
||||
hostnamelen = (TAG_LEN(p) + 3) & ~3;
|
||||
break;
|
||||
case RFC1048_ROOT_PATH: /* XXX check len */
|
||||
bootp_string("rootfs", p);
|
||||
break;
|
||||
case RFC1048_SWAP_PATH:
|
||||
bootp_string("swapfs", p);
|
||||
break;
|
||||
case RFC1048_SWAP_LEN: /* T129 */
|
||||
sprintf(config_buffer+strlen(config_buffer),
|
||||
"swapsize %d\n", ntohl(*(long *)(p+2)) );
|
||||
break;
|
||||
case 130: /* root mount options */
|
||||
bootp_string("rootopts", p);
|
||||
break;
|
||||
case 131: /* swap mount options */
|
||||
bootp_string("swapopts", p);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown RFC1048-tag ");
|
||||
for(q=p;q<p+2+TAG_LEN(p);q++)
|
||||
|
90
sys/i386/boot/netboot/netboot.8
Normal file
90
sys/i386/boot/netboot/netboot.8
Normal file
@ -0,0 +1,90 @@
|
||||
.\" $Id:$
|
||||
.Dd May 5, 1997
|
||||
.Dt NETBOOT 8
|
||||
.\".Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm netboot
|
||||
.Nd Allows remote booting of the operating system
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.It Fl b
|
||||
is used for booting the operating system over a network card. The
|
||||
program is either loaded into a ROM, or run from DOS.
|
||||
.Pp
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
loads parameters such as IP addresses, kernel name and filesystem
|
||||
names from a bootp server, tries to mount the specified root and swap
|
||||
filesystems,
|
||||
loads the specified kernel from the root filesystem using NFSv2, and
|
||||
then gives control to the kernel.
|
||||
.Pp
|
||||
The bootp server must be configured appropriately. An example
|
||||
configuration for /etc/bootptab is the following:
|
||||
.Bd -literal
|
||||
.default:\\
|
||||
:sm=255.255.255.0:\\
|
||||
:gw=your.gateway.ip:\\
|
||||
:ds=your.nameserver.ip:\\
|
||||
:hn:ht=1:vm=rfc1048:\\
|
||||
:sw=server.ip:\\
|
||||
:rp="rootfs.ip:/rootfs/path":\\
|
||||
:T128="swapfs.ip:/swapfs/path":\\
|
||||
:T129=swapsize:\\
|
||||
:T130="root,mount,options":\\
|
||||
:T131="swap,mount,options":
|
||||
.client01:bf="kernel.300":ha=00400530d6d9:tc=.default:
|
||||
.client02:bf="kernel.280":ha=00400530d6d3:tc=.default:
|
||||
.Ed
|
||||
.Pp
|
||||
For a precise description of the bootptab parameters, see
|
||||
bootptab (5) .
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
code uses options as follows.
|
||||
.Pp
|
||||
sm indicates the subnet mask.
|
||||
.Pp
|
||||
gw is the ip address of the gateway.
|
||||
.Pp
|
||||
ds is the ip address of the name server.
|
||||
.Pp
|
||||
hn instructs the bootp server to send the hostname in the reply.
|
||||
.Pp
|
||||
ht=1 indicates that the hardware is ethernet.
|
||||
.Pp
|
||||
vm=rfc1048 indicates the use of rfc1048 extensions.
|
||||
.Pp
|
||||
sw indicates the ip address of the NFS server, and is used for both
|
||||
the root filesystem and the swap filesystem server. It is optional in
|
||||
that it can be overridden from what is specified in the "rp" and "T128"
|
||||
options.
|
||||
.Pp
|
||||
rp specifies the path to the root partition. Optionally, the IP
|
||||
address of the server can be specified, followed by a :
|
||||
.Pp
|
||||
T128 specifies the path to the swap partition. Optionally, the IP
|
||||
address of the server can be specified, followed by a : . The
|
||||
actual swapfile is a file named swap.X.Y.Z.T where X.Y.Z.T is the
|
||||
IP address of the client. In both "rp" and "T128" options
|
||||
the sequence %I can be used which is replaced with the IP address of
|
||||
the client. The swap partition is optional. If specified, the swap
|
||||
file must exist and have at least the size specified with T129.
|
||||
.Pp
|
||||
T129 specifies the size of the swap file, in KB. Must be specified as
|
||||
a hexadecimal number. This argument is optional.
|
||||
.Pp
|
||||
T130 specified root mount options (e.g. soft,intr,tcp, ...).
|
||||
.Pp
|
||||
T131 specified swap mount options.
|
||||
.Pp
|
||||
bf is the name of the kernel. If not specified, it defaults to
|
||||
"kernel".
|
||||
|
||||
.Sh SEE ALSO
|
||||
.Xr bootd 8 ,
|
||||
.Xr bootptab 5
|
||||
.Sh BUGS
|
||||
The T130 and T131 options are still unsupported.
|
||||
|
@ -98,10 +98,20 @@ Author: Martin Renters
|
||||
#define RFC1048_COOKIE { 99, 130, 83, 99 }
|
||||
#define RFC1048_PAD 0
|
||||
#define RFC1048_NETMASK 1
|
||||
#define RFC1048_TIME_OFFSET 2
|
||||
#define RFC1048_GATEWAY 3
|
||||
#define RFC1048_TIME_SERVER 4
|
||||
#define RFC1048_NAME_SERVER 5
|
||||
#define RFC1048_DOMAIN_SERVER 6
|
||||
#define RFC1048_HOSTNAME 12
|
||||
#define RFC1048_BOOT_SIZE 12 /* XXX */
|
||||
#define RFC1048_SWAP_SERVER 16
|
||||
#define RFC1048_ROOT_PATH 17
|
||||
#define RFC1048_SWAP_PATH 128 /* T128 */
|
||||
#define RFC1048_SWAP_LEN 129 /* T129 */
|
||||
|
||||
#define RFC1048_END 255
|
||||
#define BOOTP_VENDOR_LEN 64
|
||||
#define BOOTP_VENDOR_LEN 256
|
||||
|
||||
#define TFTP_RRQ 1
|
||||
#define TFTP_WRQ 2
|
||||
@ -190,7 +200,7 @@ struct bootp_t {
|
||||
char bp_hwaddr[16];
|
||||
char bp_sname[64];
|
||||
char bp_file[128];
|
||||
char bp_vend[64];
|
||||
char bp_vend[BOOTP_VENDOR_LEN];
|
||||
};
|
||||
|
||||
struct tftp_t {
|
||||
|
@ -19,6 +19,11 @@ SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
DELAY(int x)
|
||||
{ volatile long a, b, l;
|
||||
for (x; x>0; x--) b=a;
|
||||
}
|
||||
|
||||
#include "netboot.h"
|
||||
#include "ns8390.h"
|
||||
|
||||
@ -284,13 +289,19 @@ eth_probe()
|
||||
ne_again:
|
||||
eth_asic_base = *tent_base + NE_ASIC_OFFSET;
|
||||
eth_nic_base = *tent_base;
|
||||
printf("Looking for NE1000/NE2000 at 0x%x\n", eth_nic_base);
|
||||
|
||||
eth_vendor = VENDOR_NOVELL;
|
||||
eth_flags = FLAG_PIO;
|
||||
eth_memsize = MEM_16384;
|
||||
eth_tx_start = 32;
|
||||
#ifdef GWETHER
|
||||
outb(eth_asic_base + NE_RESET, 0);
|
||||
DELAY(200);
|
||||
#endif
|
||||
c = inb(eth_asic_base + NE_RESET);
|
||||
outb(eth_asic_base + NE_RESET, c);
|
||||
DELAY(5000);
|
||||
inb(0x84);
|
||||
outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_STP |
|
||||
D8390_COMMAND_RD2);
|
||||
@ -317,7 +328,8 @@ eth_probe()
|
||||
return (0);
|
||||
}
|
||||
eth_pio_read(0, romdata, 16);
|
||||
printf("\r\nNE1000/NE2000 base 0x%x, addr ", eth_nic_base);
|
||||
printf("\nNE1000/NE2000 (%d bit) base 0x%x, addr ",
|
||||
eth_flags & FLAG_16BIT ? 16:8, eth_nic_base);
|
||||
for (i=0; i<6; i++) {
|
||||
printf("%b",(int)(arptable[ARP_CLIENT].node[i] = romdata[i
|
||||
+ ((eth_flags & FLAG_16BIT) ? i : 0)]));
|
||||
|
@ -86,12 +86,13 @@ nfs_mount(server, port, path, fh)
|
||||
NFS_LOOKUP: Lookup Pathname
|
||||
|
||||
***************************************************************************/
|
||||
nfs_lookup(server, port, fh, path, file_fh)
|
||||
nfs_lookup(server, port, fh, path, file_fh, sizep)
|
||||
int server;
|
||||
int port;
|
||||
char *fh;
|
||||
char *path;
|
||||
char *file_fh;
|
||||
int *sizep;
|
||||
{
|
||||
struct rpc_t buf, *rpc;
|
||||
char *rpcptr;
|
||||
@ -111,6 +112,8 @@ nfs_lookup(server, port, fh, path, file_fh)
|
||||
return(-(ntohl(rpc->u.reply.data[0])));
|
||||
} else {
|
||||
bcopy(&rpc->u.reply.data[1],file_fh, 32);
|
||||
if (sizep)
|
||||
*sizep = ntohl(rpc->u.reply.data[14]);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
@ -360,12 +360,9 @@ GET DISK GEOMETRY INFO
|
||||
_get_diskinfo:
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
push %es
|
||||
push %ebx
|
||||
push %esi
|
||||
push %edi
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
movb 0x8(%ebp), %dl /* diskinfo(drive #) */
|
||||
call _prot_to_real /* enter real mode */
|
||||
@ -414,12 +411,9 @@ ok:
|
||||
andb $0x3f, %cl /* mask of cylinder gunk */
|
||||
movb %cl, %al /* max sector (and # sectors) */
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %es
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user