常常有人问一台机器如何将hello经网络发送给另外一台机器,我确实是不知道,只能看代码了。
说明:本人对内核的研究学习也是刚刚起步,有不少不了解的,因此文中可能会有一些“一本正经的胡扯”。请你们辩证的阅读。注意这种方式不能调试 start_kernel等过程,我主要用来调试tcp/ip协议栈代码。若是想调试start_kernel,后面会介绍用qemu的方式。java
S1. 开发机:我是将一个老的索尼的笔记本装了Ubuntu桌面版本做为开发环境,版本号是Ubuntu 16.04.4 LTS,后面在某些步骤中也会称之为host。
S2. JDK使用的是java version "1.7.0_80"。 官网也有下载。后面CDT开发工具要用。
S3. Eclipse版本 Mars.2 Release (4.5.2),CDT(8.8.1)使用的插件的方式安装的。 相关软件在eclipse官网都可以得到。至于怎么装插件,请网上搜索。
S4. Virtualbox,版本 5.2.18 r124319 (Qt5.6.1)。 官网下载的linux版本。
S5. 开发机安装socat,模拟串口通讯用。sudo apt-get install socat
S6. 开发机安装build工具链。linux
sudo apt-get install gcc sudo apt-get install build-essential
S7. Virtualbox新建ubuntu虚拟机做为调试目标机,安装的虚拟机的系统用的镜像是:ubuntu-16.04-server-amd64.iso。至于怎么用virtualbox装虚拟机,请网上搜索。
虚拟机的CPU请根据你实际机器CPU的数量选择,我选择的是2,后面会对编译速度的提高有帮助。
虚拟机的网卡设置: 选中你的virtualbox虚拟机-->设置-->网络-->网卡1-->勾上 启用网络链接/链接方式 选择 桥接网卡/界面名称 选择 你能联网的网卡。
。
虚拟机串口设置: 选中你的virtualbox虚拟机-->设置-->串口-->端口1-->勾上 启用串口/端口模式 选择 主机管道/路径地址填写 /tmp/s
git
安装时,有个注意事项,语言选择English,不然可能会出现安装出错。另,安装server工具步骤时建议选择上openssh server。选择须要安装grub做为磁盘引导器。后面我么会称这台装好的虚拟机为guest机器,或者调试目标机,或者调试机,或者target等等。github
S8. 登陆到调试目标机,准备内核代码。
到内核官网下载你要用的内核,个人用的是[4.4.19]版本(https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.4.19.tar.gz)。能够用wget xxx内核连接地址的办法下载,个人是:shell
cd ~ mkdir 004.code cd 004.code wget https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.4.19.tar.gz tar -xzvf linux-4.4.19.tar.gz cd linux-4.4.19
S9. 在调试目标机准备编译安装内核。
修改Makefile文件(linux-4.4.19目录下),将其中的O2字样修改为O1,目前不支持O0编译。可是有个文章说能够经过修改内核代码达到使用O0编译的目的。我试了试,没成功。若是谁成功了,能够告诉我,谢谢。
安装必要的依赖:ubuntu
sudo apt-get install libncurses5-dev sudo apt-get install libssl-dev sudo apt-get install bc
调试目标机安装build工具链。网络
sudo apt-get install gcc sudo apt-get install build-essential
配置内核选项,其实只须要执行这步生成config文件,配置项不用修改,咱们要的都有。app
make menuconfig
而后选择 exit 而后选择yes 生成config文件。eclipse
make CONFIG_DEBUG_SECTION_MISMATCH=y -j2
此步骤须要很长时间,2-5小时不等,正常能够在睡觉前执行,次日早上起来看结果。ssh
S10. 在调试目标机安装新编译的内核。
工做目录在linux-4.4.19
sudo make modules_install sudo make install
S11. 在调试目标机修改启动引导选项。
在第10步完成后重启机器时,在启动菜单中选择Advance...菜单中,能够看到新安装的4.4.19内核的引导项。
进入系统(用4.4.19 或者以前的默认内核均可以),修改启动引导配置文件。
cd /boot/grub sudo su - root cp grub.cfg grub.cfg.bk.180917 chmod +w grub.cfg vi grub.cfg
找到menuentry 'Ubuntu, with Linux 4.4.19......这个地方,为了便于识别,能够讲此处单引号内的4.4.19后面加上-debug-kernel字样(可选)。 从这行开始向下查看,找到最挨着的linux /vmlinuz-4.4.19 root=...ro 这一行,在 这一行后面加上kgdb=ttyS0 kgdboc=ttyS0,115200 kgdbwait
S12. 在调试目标机将代码和编译产物拷贝给开发机。我用的scp,你能够选择ftp等方式。
scp -r linux-4.4.19 simon@192.168.2.7:/home/simon/004.code/linux-4.4.19
用户名 ip 路径 根据你本身实际状况肯定。不明白的能够搜搜scp命令怎么用,再不行就用ftp的方式搞。 也有人经过虚拟机共享目录的方式搞,这个不重要,你能拿到开发机上面就行。
S13. 在开发机,配置CDT并准备工程。
打开装了CDT插件的eclipse。
window-->preferences-->General-->Workspace 去掉勾选 Build Automatically。
window-->preferences-->C/C++-->indexer 去掉勾选 Enable indexer。
file-->new-->c project-->project name填写你本身合意的,好比linux-kernel-study / 去掉use default location,location输入框中选择你的linux-4.4.19路径。 / project type 选择 Makefile project-Empty project / Toolschains选择Linux GCC-->next-->Advanced Setting-->C/C++ Build-->去掉勾选use default build command, build command输入框内写上 make CONFIG_DEBUG_SECTION_MISMATCH=y -j2,build directory选择你的linux-4.4.19路径。 / Behavior页签 Build(Increament build) 输入框中输入一个空格便可。而后完成工程建立便可。
点击工具栏中的绿色小虫子右边的箭头,选择Debug Configurations-->C/C++ Remote Application(双击)-->proiect选择你刚建立的project / C/C++ Application选择你的linux-4.4.19路径下的vmlinux。 / 选中 Disable auto build 点击select other换一个启动器 选择 GDB(DSF)Manual Remote Debugging...
点击debugger页签 点击connection子页签,type选择Serial, speed选择115200,dev后面再来填。此处标志为待填13.1。
点击apply close便可。
S14. 启动调试目标机,在启动菜单处,选择 advance.../Ubuntu, with Linux 4.4.19-debuge-kernel这个内核引导项目。
在开发机执行命令:socat -d -d /tmp/s pty
他会有个输出 /dev/pts/.. 把这个路径填到13步待填13.1处。
cd 你的linux-4.4.19路径
gdb vmlinux
target remote /dev/pts/.. (此处对应上面的输出,不是真的写一个..)
此时就应该链接上目标机器了。按gdb的c指令即可以使得调试目标机继续启动下去。
若是须要加设断点等,能够在调试目标机执行
sudo su - root
echo g > /proc/sysrq-trigger
这样目标机就会暂停,能够在开发机中加设断点。
注意这种方式不能调试 start_kernel等过程,我主要用来调试tcp/ip协议栈代码。
S15. 在开发机用CDT调试。
退掉14步的gdb调试。
在调试目标机执行 sudo echo g > /proc/sysrq-trigger
点击CDT工具栏中的绿色小虫子右边的箭头,选择1New_configuration,若是有什么错误提示不用理会,继续proceed。 链接成功后,控制台会有输出,好比咱们能够在控制台输入 b af_inet.c:471 而后输入gdb 指令 c
而后 在目标机执行 nc -l 8080
而后你就能够发现断点停在了 snum = ntohs(addr->sin_port);, 这个时候你就能够调试server的bind动做了,其余诸如listen accept connect等相似方式调试。
F5 F6这些快捷键均可以用,只是你每次增减断点,貌似都要如今目标机执行 echo g > /proc/sysrq-trigger,使他先停下来,才好加断点等操做。