⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bios_wini.c

📁 minix3.1.1源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		reg86.u.w.bx = bios_buf_phys % HCLICK_SIZE;		reg86.u.w.es = bios_buf_phys / HCLICK_SIZE;		reg86.u.b.ch = cylinder & 0xFF;		reg86.u.b.cl = sector | ((cylinder & 0x300) >> 2);		reg86.u.b.dh = head;		reg86.u.b.dl = wn->drive_id;	}	r= sys_int86(&reg86);	if (r != OK)		panic(ME, "BIOS call failed", r);	if (reg86.u.w.f & 0x0001) {		/* An error occurred, try again sector by sector unless */		if (++errors == 2) return(EIO);		continue;	}	if (opcode == DEV_GATHER) {		/* Copy from the DMA buffer to user space. */		count = 0;		for (iop = iov; count < nbytes; iop++) {			chunk = iov->iov_size;			if (count + chunk > nbytes) chunk = nbytes - count;			assert(chunk <= rem_buf_size);			r= sys_vircopy(SYSTEM, D, bios_buf_vir+count, 				proc_nr, D, iop->iov_addr,				chunk);			if (r != OK)				panic(ME, "sys_vircopy failed", r);			count += chunk;		}	}	/* Book the bytes successfully transferred. */	position += nbytes;	for (;;) {		if (nbytes < iov->iov_size) {			/* Not done with this one yet. */			iov->iov_addr += nbytes;			iov->iov_size -= nbytes;			break;		}		nbytes -= iov->iov_size;		iov->iov_addr += iov->iov_size;		iov->iov_size = 0;		if (nbytes == 0) {			/* The rest is optional, so we return to give FS a			 * chance to think it over.			 */			return(OK);		}		iov++;		nr_req--;	}  }  return(OK);}/*============================================================================* *				w_do_open				      * *============================================================================*/PRIVATE int w_do_open(dp, m_ptr)struct driver *dp;message *m_ptr;{/* Device open: Initialize the controller and read the partition table. */  static int init_done = FALSE;  if (!init_done) { w_init(); init_done = TRUE; }  if (w_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);  if (w_wn->open_ct++ == 0) {	/* Partition the disk. */	partition(&w_dtab, w_drive * DEV_PER_DRIVE, P_PRIMARY, 0);  }  return(OK);}/*============================================================================* *				w_do_close				      * *============================================================================*/PRIVATE int w_do_close(dp, m_ptr)struct driver *dp;message *m_ptr;{/* Device close: Release a device. */  if (w_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);  w_wn->open_ct--;  return(OK);}/*===========================================================================* *				w_init					     * *===========================================================================*/PRIVATE void w_init(){/* This routine is called at startup to initialize the drive parameters. */  int r, drive, drive_id, nr_drives;  struct wini *wn;  unsigned long capacity;  struct int13ext_params {	u16_t	len;	u16_t	flags;	u32_t	cylinders;	u32_t	heads;	u32_t	sectors;	u32_t	capacity[2];	u16_t	bts_per_sec;	u16_t	config[2];  } i13e_par;  struct reg86u reg86;  /* Ask the system task for a suitable buffer */  r= sys_getbiosbuffer(&bios_buf_vir, &bios_buf_size);  if (r != OK)  	panic(ME, "sys_getbiosbuffer failed", r);  r= sys_umap(SYSTEM, D, (vir_bytes)bios_buf_vir, (phys_bytes)bios_buf_size,  	&bios_buf_phys);  if (r != OK)  	panic(ME, "sys_umap failed", r);  if (bios_buf_phys+bios_buf_size > 0x100000)  	panic(ME, "bad BIOS buffer, phys", bios_buf_phys);#if 0  printf("bios_wini: got buffer size %d, virtual 0x%x, phys 0x%x\n",  		bios_buf_size, bios_buf_vir, bios_buf_phys);#endif  /* Get the geometry of the drives */  for (drive = 0; drive < MAX_DRIVES; drive++) {  	if (remap_first)  	{  		if (drive == 7)			drive_id= 0x80;		else			drive_id= 0x80 + drive + 1;  	}  	else		drive_id= 0x80 + drive;	(void) w_prepare(drive * DEV_PER_DRIVE);	wn = w_wn;	wn->drive_id= drive_id;	reg86.u.b.intno = 0x13;	reg86.u.b.ah = 0x08;	/* Get drive parameters. */	reg86.u.b.dl = drive_id;	r= sys_int86(&reg86);	if (r != OK)		panic(ME, "BIOS call failed", r);	nr_drives = !(reg86.u.w.f & 0x0001) ? reg86.u.b.dl : drive;	if (drive_id >= 0x80 + nr_drives) continue;	wn->present= 1;	wn->heads = reg86.u.b.dh + 1;	wn->sectors = reg86.u.b.cl & 0x3F;	wn->cylinders = (reg86.u.b.ch | ((reg86.u.b.cl & 0xC0) << 2)) + 1;	capacity = (unsigned long) wn->cylinders * wn->heads * wn->sectors;	reg86.u.b.intno = 0x13;	reg86.u.b.ah = 0x41;	/* INT 13 Extensions - Installation check */	reg86.u.w.bx = 0x55AA;	reg86.u.b.dl = drive_id;	if (pc_at) {		r= sys_int86(&reg86);		if (r != OK)			panic(ME, "BIOS call failed", r);	}	if (!(reg86.u.w.f & 0x0001) && reg86.u.w.bx == 0xAA55				&& (reg86.u.w.cx & 0x0001)) {		/* INT 13 Extensions available. */		i13e_par.len = 0x001E;	/* Input size of parameter packet */		r= sys_vircopy(SELF, D, (vir_bytes)&i13e_par,			SYSTEM, D, bios_buf_vir, 			sizeof(i13e_par));		if (r != OK)			panic(ME, "sys_vircopy failed\n", r);		reg86.u.b.intno = 0x13;		reg86.u.b.ah = 0x48;	/* Ext. Get drive parameters. */		reg86.u.b.dl = drive_id;		reg86.u.w.si = bios_buf_phys % HCLICK_SIZE;		reg86.u.w.ds = bios_buf_phys / HCLICK_SIZE;		r= sys_int86(&reg86);		if (r != OK)			panic(ME, "BIOS call failed", r);		r= sys_vircopy(SYSTEM, D, bios_buf_vir,			 SELF, D, (vir_bytes)&i13e_par,			sizeof(i13e_par));		if (r != OK)			panic(ME, "sys_vircopy failed\n", r);		if (!(reg86.u.w.f & 0x0001)) {			wn->int13ext = 1;	/* Extensions can be used. */			capacity = i13e_par.capacity[0];			if (i13e_par.capacity[1] != 0) capacity = 0xFFFFFFFF;		}	}	if (wn->int13ext) {		printf("%s: %lu sectors\n", w_name(), capacity);	} else {		printf("%s: %d cylinders, %d heads, %d sectors per track\n",			w_name(), wn->cylinders, wn->heads, wn->sectors);	}	wn->part[0].dv_size = mul64u(capacity, SECTOR_SIZE);  }}/*============================================================================* *				w_geometry				      * *============================================================================*/PRIVATE void w_geometry(entry)struct partition *entry;{  entry->cylinders = w_wn->cylinders;  entry->heads = w_wn->heads;  entry->sectors = w_wn->sectors;}/*============================================================================* *				w_other				      * *============================================================================*/PRIVATE int w_other(dr, m)struct driver *dr;message *m;{        int r, timeout, prev;        if (m->m_type != DEV_IOCTL ) {                return EINVAL;        }	if (m->REQUEST == DIOCOPENCT) {                int count;                if (w_prepare(m->DEVICE) == NIL_DEV) return ENXIO;                count = w_wn->open_ct;                if ((r=sys_datacopy(SELF, (vir_bytes)&count,                        m->PROC_NR, (vir_bytes)m->ADDRESS, sizeof(count))) != OK)                        return r;                return OK;        }        return EINVAL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -