内核调试 · 2014-06-02 0

Bochs调试linux内核环境搭建笔记(2)

此文主要是记录了一下,基于grub 0.97等老版本做Bochs镜像的操作流程,以备后用。该文与前一篇博文总体上面就细节上稍微有些许差异,制作镜像的整体步骤相同。原本有前一篇博文就已经够了,但是个人在研究Linux内核启动的过程中,有部分细节不太清晰,后来发现是GRUB发生了变化的缘故。grub 0.97及之前的版本可以称之为GRUB Legacy,大约2002年左右,Yoshinori K. Okuji在PUPA重写了GRUB,使它更清晰,安全,健壮,更强大,PUPA最后把它重命名为GRUB2,2005年发行了grub legacy(0.97),而2007 GNU/Linux 开始在小范围内使用GRUB2,到2009年底大多数主要的发行版都开始默认安装GRUB2。

   GRUB2是全新的一个引导工具,差异不小,研究linux启动的时候,首先就可以发现GRUB2为linux启动做了很多准备性的工作,由arch/x86/boot/header.s的start_of_setup到arch/x86/boot/main.c的main的所有工作好像都已经被GRUB接管去完成了,而后面所需要的数据也是有GRUB去做的。这也就是为什么在GRUB2引导启动linux的过程中bochs没办法断到0x90200位置的缘故了。至于GRUB2的其他特性,请自行谷歌百度了,这里就不赘述了。

实验环境:
Vmware + Redhat 5.5
grub 0.97

以下是实验操作记录:
1、创建磁盘镜像
[root@localhost ~]# dd if=/dev/zero of=disk.img count=$((63*16*20))
20160+0 records in
20160+0 records out
10321920 bytes (10 MB) copied, 0.161663 seconds, 63.8 MB/s
注:count是cylinders、heads和每个track的sector数的乘积;
2、磁盘上建立分区表信息
[root@localhost ~]# fdisk disk.img 
last_lba(): I don’t know how to handle files with mode 81a4
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won’t be recoverable.

You must set cylinders.
You can do this from the extra functions menu.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): x
——进入专家功能模式

Expert command (m for help): c
Number of cylinders (1-1048576): 20
——设置cylinders柱面,其中参数20

Expert command (m for help): h
Number of heads (1-256, default 255): 16
——设置heads,其中参数16

Expert command (m for help): s
Number of sectors (1-63, default 63): 63
——设置每个track的sector数,其中参数63
Warning: setting sector offset for DOS compatiblity

Expert command (m for help): r
——返回至普通模式

Command (m for help): n
——创建新分区
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
——创建基础分区,分区数为1
First cylinder (1-20, default 1): 1
Last cylinder or +size or +sizeM or +sizeK (1-20, default 20): 20
——设置起始和结束的cylinder柱面号

Command (m for help): a
Partition number (1-4): 1
——设置可引导的分区

Command (m for help): w
——将分区表写入磁盘并退出
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 25: Inappropriate ioctl for device.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.
注:每道扇区数63,磁头数16是基本固定的,据说bochs只识别这个,改天有空了再研究一下,至于扩大容量可以修改柱面数;
3、检查刚才的操作结果
[root@localhost ~]# hexdump -s 0x1BE -x -n 16 disk.img 
00001be    0180    0001    0f83    133f    003f    0000    4e81    0000
00001ce
[root@localhost ~]# fdisk -l -u disk.img 
last_lba(): I don’t know how to handle files with mode 81a4
You must set cylinders.
You can do this from the extra functions menu.

Disk disk.img: 0 MB, 0 bytes
16 heads, 63 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes

   Device Boot      Start         End      Blocks   Id  System
disk.img1   *          63       20159       10048+  83  Linux
4、安装磁盘设备
[root@localhost ~]# losetup -o $((63*512)) /dev/loop0 disk.img 
[root@localhost ~]# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                      18156292   3269400  13949728  19% /
/dev/sda1               101086     12200     83667  13% /boot
tmpfs                   517504         0    517504   0% /dev/shm
.host:/              157014868  96851708  60163160  62% /mnt/hgfs
/dev/scd0              2884990   2884990         0 100% /media/RHEL_5.5 Source
5、把磁盘格式化为fat格式
[root@localhost ~]# mkdosfs /dev/loop0
mkdosfs 2.11 (12 Mar 2005)
Loop device does not match a floppy size, using default hd params
[root@localhost ~]# hexdump -s 0x1BE -x -n 16 disk.img 
00001be    0180    0001    0f83    133f    003f    0000    4e81    0000
00001ce
注:mkdosfs好像没法改变格式,所以还需要fdisk来进行格式化(好像前一篇博文没注意这点,迟些再专门研究一下);
[root@localhost ~]# fdisk disk.img 
last_lba(): I don’t know how to handle files with mode 81a4
You must set cylinders.
You can do this from the extra functions menu.

Command (m for help): t
——切换分区的系统ID
Selected partition 1
Hex code (type L to list codes): L
——查看各个类型的编码

 0  Empty           1e  Hidden W95 FAT1 80  Old Minix       bf  Solaris        
 1  FAT12           24  NEC DOS         81  Minix / old Lin c1  DRDOS/sec (FAT-
 2  XENIX root      39  Plan 9          82  Linux swap / So c4  DRDOS/sec (FAT-
 3  XENIX usr       3c  PartitionMagic  83  Linux           c6  DRDOS/sec (FAT-
 4  FAT16 <32M      40  Venix 80286     84  OS/2 hidden C:  c7  Syrinx         
 5  Extended        41  PPC PReP Boot   85  Linux extended  da  Non-FS data    
 6  FAT16           42  SFS             86  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS       4d  QNX4.x          87  NTFS volume set de  Dell Utility   
 8  AIX             4e  QNX4.x 2nd part 88  Linux plaintext df  BootIt         
 9  AIX bootable    4f  QNX4.x 3rd part 8e  Linux LVM       e1  DOS access     
 a  OS/2 Boot Manag 50  OnTrack DM      93  Amoeba          e3  DOS R/O        
 b  W95 FAT32       51  OnTrack DM6 Aux 94  Amoeba BBT      e4  SpeedStor      
 c  W95 FAT32 (LBA) 52  CP/M            9f  BSD/OS          eb  BeOS fs        
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a0  IBM Thinkpad hi ee  EFI GPT        
 f  W95 Ext’d (LBA) 54  OnTrackDM6      a5  FreeBSD         ef  EFI (FAT-12/16/
10  OPUS            55  EZ-Drive        a6  OpenBSD         f0  Linux/PA-RISC b
11  Hidden FAT12    56  Golden Bow      a7  NeXTSTEP        f1  SpeedStor      
12  Compaq diagnost 5c  Priam Edisk     a8  Darwin UFS      f4  SpeedStor      
14  Hidden FAT16 <3 61  SpeedStor       a9  NetBSD          f2  DOS secondary  
16  Hidden FAT16    63  GNU HURD or Sys ab  Darwin boot     fb  VMware VMFS    
17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE 
18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fd  Linux raid auto
1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid fe  LANstep        
1c  Hidden W95 FAT3 75  PC/IX           be  Solaris boot    ff  BBT            
Hex code (type L to list codes): 4
——由于需要格式化为fat,所以选择“4  FAT16 <32M”
Changed system type of partition 1 to 4 (FAT16 <32M)

Command (m for help): w
——将操作写入的磁盘中
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 25: Inappropriate ioctl for device.
The kernel still uses the old table.
The new table will be used at the next reboot.

WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.
注:再次检查刚才的操作;
[root@localhost ~]# hexdump -s 0x1BE -x -n 16 disk.img 
00001be    0180    0001    0f04    133f    003f    0000    4e81    0000
00001ce
6、挂载磁盘
[root@localhost ~]# mount -o loop /dev/loop0 /mnt
7、安装grub
[root@localhost ~]# mkdir -p /mnt/boot/grub
[root@localhost ~]# pwd
/root
[root@localhost ~]# find / -name stage*
/usr/share/grub/i386-redhat/stage2_eltorito
/usr/share/grub/i386-redhat/stage2
/usr/share/grub/i386-redhat/stage1
/boot/grub/stage2
/boot/grub/stage1
[root@localhost ~]# find / -name fat_stage*
/usr/share/grub/i386-redhat/fat_stage1_5
/boot/grub/fat_stage1_5
[root@localhost ~]# cd /usr/share/grub/i386-redhat/
[root@localhost i386-redhat]# ls
e2fs_stage1_5  iso9660_stage1_5  reiserfs_stage1_5  stage2_eltorito  xfs_stage1_5
fat_stage1_5   jfs_stage1_5      stage1             ufs2_stage1_5
ffs_stage1_5   minix_stage1_5    stage2             vstafs_stage1_5
[root@localhost i386-redhat]# cp ./stage1 ./stage
stage1           stage2           stage2_eltorito  
[root@localhost i386-redhat]# cp ./stage1 ./stage2
stage2           stage2_eltorito  
[root@localhost i386-redhat]# cp ./stage1 ./fat_stage1_5 ./stage2 /mnt/boot/grub/
[root@localhost i386-redhat]# vi /mnt/boot/grub/
fat_stage1_5  stage1        stage2        
8、编辑grub引导信息:
[root@localhost i386-redhat]# vi /mnt/boot/grub/grub.conf
[root@localhost i386-redhat]# cp /mnt/boot/grub/grub.conf /mnt/boot/grub/menu.lst
内容:
default=0
timeout=500
title=OS2Bochs
root (hd0,0)
kernel /kernel.bin

[root@localhost i386-redhat]# umount /mnt
[root@localhost i386-redhat]# losetup -d /dev/loop0
[root@localhost i386-redhat]# pwd
/usr/share/grub/i386-redhat
9、初始化光盘映像的grub
[root@localhost i386-redhat]# grub –device-map=/dev/null
[root@localhost i386-redhat]# cd
[root@localhost ~]# ls
anaconda-ks.cfg  grub-0.97-13.5.src.rpm  scsrun.log
Desktop          install.log             VMwareTools-9.6.1-1378637.tar.gz
disk.img         install.log.syslog      vmware-tools-distrib
[root@localhost ~]# grub –device-map=/dev/null
grub的操作记录:
 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.]
grub> device (hd0) disk.img
grub> geometry (hd0)
drive 0x80: C/H/S = 620/128/63, The number of sectors = 20160, disk.img
   Partition num: 0,  Filesystem type is fat, partition type 0x4
grub> geometry (hd0) 20 16 63
drive 0x80: C/H/S = 20/16/63, The number of sectors = 20160, disk.img
   Partition num: 0,  Filesystem type is fat, partition type 0x4
grub> root (hd0,0)
 Filesystem type is fat, partition type 0x4
grub> setup (hd0)
 Checking if “/boot/grub/stage1” exists… yes
 Checking if “/boot/grub/stage2” exists… yes
 Checking if “/boot/grub/fat_stage1_5” exists… yes
 Running “embed /boot/grub/fat_stage1_5 (hd0)”…  15 sectors are embedded.
succeeded
 Running “install /boot/grub/stage1 (hd0) (hd0)1+15 p (hd0,0)/boot/grub/stage2 /boot/grub/gru
b.conf”… succeeded
Done.
grub> quit
——退出
10、将分区挂载到loop0上面,并将Linux内核安装进去
[root@localhost ~]# losetup -o 32256 /dev/loop0 disk.img 
[root@localhost ~]# mount -o loop /dev/loop0 /mnt
[root@localhost ~]# find / -name vmlinuz*
/boot/vmlinuz-2.6.18-194.el5
[root@localhost ~]# cp /boot/vmlinuz-2.6.18-194.el5 /mnt/kernel.bin
[root@localhost ~]# ls /mnt/
boot  kernel.bin
11、将设备卸载
[root@localhost ~]# umount /mnt
[root@localhost ~]# losetup -d /dev/loop0
由此,磁盘镜像做完。
12、此外Bochs的配置修改为
megs: 32
romimage: file=$BXSHARE/BIOS-bochs-latest
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
ata0-master: type=disk, path=”disk0.img”, cylinders=20, heads=16, spt=63
boot: c
log: bochsout.txt
mouse: enabled=0
cpu: ips=15000000
clock: sync=both

本文操作参考:
http://blog.chinaunix.net/uid-23345370-id-2427590.html
http://www.cnblogs.com/yuboyue/archive/2011/09/15/2178128.html