这是第二次研究fdisk-0.91了,这次是把补丁该了一个数,然后重新编译内核,第一次文章里面的fdisk还是可以用的。
为什么要再次研究,是因为不能正确的显示第二块硬盘的参数。
第一次的文章
http://blog.csdn.net/oldlinux/article/details/8582379
void get_boot()
{
int i;
struct hd_geometry geometry;
if ((fd = open(disk_device, O_RDWR)) < 0)
fatal(unable_to_open);
if (SECTOR_SIZE != read(fd, buffer, SECTOR_SIZE))
fatal(unable_to_read);
if (!ioctl(fd, HDIO_REQ, &geometry)) {
heads = geometry.heads;
sectors = geometry.sectors;
cylinders = geometry.cylinders;
}
if (!heads || !sectors || !cylinders)
printf("Warning: unable to get disk geometry from system\n");
这里的open函数得到的是文件描述符,然后是读了一个扇区,里面有分区表。
然后是ioctl()函数,当然,linux-0.11里面的ioctl_table[]没有对应的函数,
static ioctl_ptr ioctl_table[]={
NULL, /* nodev */
NULL, /* /dev/mem */
NULL, /* /dev/fd */
NULL, /* /dev/hd */
tty_ioctl, /* /dev/ttyx */
tty_ioctl, /* /dev/tty */
NULL, /* /dev/lp */
NULL}; /* named pipes */
int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct file * filp;
int dev,mode;
if (fd >= NR_OPEN || !(filp = current->filp[fd]))
return -EBADF;
mode=filp->f_inode->i_mode;
if (!S_ISCHR(mode) && !S_ISBLK(mode))
return -EINVAL;
dev = filp->f_inode->i_zone[0]; //这里的dev为设备号比如/dev/hd5的设备号为0x305
if (MAJOR(dev) >= NRDEVS)
return -ENODEV;
if (!ioctl_table[MAJOR(dev)])
return -ENOTTY;
return ioctl_table[MAJOR(dev)](dev,cmd,arg);
}
所以打补丁得到hd_ioctl()函数。
+ int hd_ioctl(int dev, int cmd, int arg)
+ {
+ struct hd_geometry *loc = (void *) arg;
+
+ if (!loc)
+ return -EINVAL;
+ dev = MINOR(dev) >> 6; /*这里不适应于0.11,所以改为+ dev = MINOR(dev) >> 2; */
+ if (dev >= NR_HD)
+ return -EINVAL;
+
+ switch (cmd) {
+ case HDIO_REQ:
+ put_fs_byte(hd_info[dev].head,
+ (unsigned char *) &loc->heads);
+ put_fs_byte(hd_info[dev].sect,
+ (unsigned char *) &loc->sectors);
+ put_fs_word(hd_info[dev].cyl,
+ (unsigned short *) &loc->cylinders);
+ return 0;
+ default:
+ return -EINVAL;
+ }
#define MINOR(a) ((a)&0xff) 在fs.h文件中
dev = MINOR(dev) >> 2; 所以MINOR(0x305) >> 2 等于1,既dev等于1,既是第二块硬盘。
上面的是bochs调试的hd_info[]数组和bochs的配置文件中硬盘部分。