您的位置:首页 > 运维架构 > Linux

linux0.11 编译遇到的问题

2014-12-09 16:08 477 查看
在oldlinux网址下载了linux0.11能够编译通过的源代码,在ubuntu13.10的机子上能够编译成功(gcc版本4.8.1),但是在boshs上确无法运行,总结有如下问题:

1. 反复出现Loading system... 。一步一步调试,发现当setup完后并没有进入到head中,通过查看Image二进制文件,发现第5扇区(0xa00)开始处的指令并不是head代码。经过一步一步反复调试,发现ld程序将main.c中的main函数作为入口地址了(本来应该是head),尝试将main函数改名为kmain后成功,当然head.s中相应的一个地方也要改。

2. 显示Loading system ... 后就一直停在这里。一步一步插桩调试,发现在main函数中第一次fork然后调用copy_process出现问题,首先find_empty_process调用成功返回1,然后进入copy_process函数,get_free_page也执行成功,但是接下来将进程0的数据结构复制给进程1的操作失败了,问题出现在*p=*current赋值语句上,网上各种百度了下,原因在于这条语句汇编后其实就是串操作,串操作开始时,首先要设置方向位DF,但是这里编译器认为已经cld过了,又由于这里方向位在之前某个地方修改过,所以导致串操作方向出错,解决办法是在这条语句之前加入如下嵌入汇编代码:

__asm__ volatile ("cld");
除了fork.c文件中需要加入这条语句之外,在super.c中read_super函数里面的下面语句之前也要加上
*((struct d_super_block *) s) = *((struct d_super_block *) bh->b_data);
还有在inode.c中read_inode函数里面
*(struct d_inode *)inode =  ((struct d_inode *)bh->b_data) [(inode->i_num-1)%INODES_PER_BLOCK];


出现串操作方向错误的原因其实是linux的一个bug,首先在setup_paging函数中linux为了代码效率,倒序装入页表,导致设置了std方向位,但并未改回。因此可在该函数ret前cld一下。另外一个相同的bug在在内核代码的get_free_page函数中,同样在代码最后增加一个cld。这是第二个方法。

3. 上面3处修改过之后,发现当回车插入root软盘之后反复出现Reset floppy called的问题。 网上找到一个原因说法以及解决办法:

原因:mount_root -> read_super -> check_disk_change-> floppy_change-> floppy_on-> ticks_to_floppy_on 会启动b盘的驱动器,这会导致unexpected_floppy_interrupt被call,然后recalibrate被设为1。当do_fd_request第一次被call用于读取super block的时候,遇到recalibrate==1 就调用recalibrate_floppy。问题来了,current_drive变量还没有机会被赋值,它应该等于1却是0。于是导致recalibrate出错,recal_interrupt设reset=1
-> reset_floppy ->reset_interrupt -> recalibrate_floppy (current_drive依然并且永远是错的) ->recal_interrupt->reset_floppy->... 不断的死循环和打印Reset-floppy called。

解决办法:在recalibrate_floppy中向hardware传递正确的driver号能避免这个问题。我直接在recalibrate_floppy函数中对current_drive=1。

另外我使用的是b软盘作为root根目录,因此在bootsect.s中ROOT_DEV需修改为0x021d。到此终于能够将linux0.11跑起来了,但是又有一个问题,第一次能够运行,关闭后再运行就失败了,停在如下图所示的地方:



但是通过从新换个b软盘(拷贝新的rooimage-0.11)就可以解决,猜想原因是第一次运行对软盘某个地方进行了修改。

-------------------------------------------------------------

对于上面那个只能运行一次到问题,今天终于解决了。确实有可能第一次运行时,rootimage遭到修改。解决办法如下:

1. 首先在linux系统上挂载rootimage-0.11镜像(ubuntu 12.04):

sudo mount -t minix -o loop rootimage0.11 /mnt/minix

2. cd 进入/mnt/minix目录,再进入/etc目录,然后sudo vim rc文件,将第一行到update &删除(因为从源代码main.c可以看到,操作系统挂载根文件系统后,打开tty0终端,然后又打开rc文件输出===OK,vi这个rc文件,发现执行了一个update程序,所以猜想就是这个命令程序导致的问题)。

3. 卸载minix:sudo umount /mnt/minix。再次运行问题就解决了。

后面细想可能是update这个程序一直在后台运行,当关闭bochs后导致rootimage的minix文件系统出现问题,出现什么问题还是不得而知。。另外出现问题后无法再次在ubuntu上挂载了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: