📄 bios_wini.c
字号:
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(®86); 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(®86); 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(®86); 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(®86); 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 + -