Apr 5, 2012

搭建内核开发调试环境

闲来无事, 总结一下内核开发调试环境的搭建过程, 希望能对和我一样的内核新手们有所帮助.

方案

我的测试系统在QEMU中运行, Host和Guest的架构都是x86_64, 用Busybox生成的initrd做为根文件系统, KGDB做为调试器.

生成内核

内核中需要打开的选项是CONFIG_EXPERIMENTAL, CONFIG_DEBUG_INFO, CONFIG_KGDBCONFIG_KGDB_SERIAL_CONSOLE, 同时需要关闭CONFIG_DEBUG_RODATA选项. 然后make bzImage编译生成内核. 具体选项的意义可以去翻内核文档, 这里就不罗嗦了.

生成根文件系统

打开Busybox的CONFIG_STATICCONFIG_INSTALL_NO_USR选项, 执行makemake install编译并生成, 然后参照下面的步骤创建initrd根文件系统:

mkdir temp && cd temp

#创建系统目录
mkdir -p dev etc/init.d mnt proc root sys tmp
chmod a+rwxt tmp

cp -rf ../busybox/_install/* ./

#挂载系统目录
cat << EOF > etc/fstab
proc  /proc  proc  defaults  0  0
sysfs  /sys  sysfs defaults  0  0
tmpfs  /tmp  tmpfs defaults  0  0
EOF

cat << EOF > etc/inittab
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
EOF

cat << EOF > etc/init.d/rcS
#!bin/sh
/bin/mount -a
#用mdev生成设备文件
/sbin/mdev -s
EOF

chmod 755 etc/init.d/rcS

find ./ | cpio -o -H newc | gzip > ../rootfs.img

启动QEMU

qemu-system-x86_64 -kernel kernel.img -append \
"root=/dev/ram rdinit=/sbin/init" -initrd rootfs.img 或
qemu-system-x86_64 -kernel kernel.img -append \
"root=/dev/ram rdinit=/sbin/init kgdboc=ttyS0,115200 kgdbwait" \
-initrd rootfs.img -serial tcp::1234,server 第二个命令开启了KGDB, 将Guest系统的串口映射到了Host系统的1234端口, 并在启动过程中等待gdb的连接.

启动gdb

内核开启KGDB的情况下, 执行gdb vmlinux, 其中vmlinux是未压缩的内核. 然后target remote localhost:1234连接kgdb.

接下来就和普通的gdb没什么大的区别了, 比如在sched_clock函数处设置断点break sched_clock, continue继续运行, 到达断点后打印jiffies_64变量print jiffies_64等等.

另外, 运行过程中可以在测试系统里执行echo g > /proc/sysrq-trigger让gdb重新得到控制权.

For 懒人

顺手在github上建了个项目, 可以自动搭建整个内核开发调试环境, 详见README.

http://github.com/adam8157/kernel-studio

git clone git://github.com/adam8157/kernel-studio.git

Feb 9, 2012

迁移到Octopress

长久以来我就对Wordpress有着诸多不满: 冗余, 速度慢, 非静态, 依赖数据库, 迁移成本高… 但是苦于没有合适的替代品, 只能忍受. 直到我最近发现了Octopress.

什么是Octopress

Octopress是一个基于Jekyll的静态博客生成系统

Octopress有什么优点

  • 纯静态: 最终发布的只有HTML, Javascript和CSS

  • Markdown: 使用Markdown作为源文件语言, 易写易读

  • 搭建方便: 简洁的Ruby框架, 操作十分简单方便

  • 迁移成本低: 因为是静态网页, 对主机要求低, 且迁移方便

  • 版本控制友好: 整个项目和文章源代码都是纯文本(图片等除外), 方便版本控制

如何搭建和迁移


Feb 2, 2012

Markdown真不错

Markdown是个轻量级的标记语言, 容易读, 容易写. 具体的介绍和语法可以去项目主页查看.

除了直接在某些网站(例如github)上使用, 还可以通过pandoc把Markdown文件转换成HTML, MediaWiki, LaTeX, 甚至Groff, Texinfo, DocBook, OpenDocument, EPUB. 更厉害的是, pandoc还可以套用LaTeX模板和CSS样式表, 真乃神器!

于是我参考这里写了个幻灯片模板, 调用pandoc和latex生成pdf, 相当舒服.


Dec 26, 2011

用Vundle管理Vim插件

一直以来, 管理Vim插件对我来说都是个困扰, 安装, 更新和卸载, 一个比一个麻烦. 我也尝试过很多插件管理工具, 但是都不如意, 直至遇到了Vundle.

Vundle利用git, 插件的git repo以及vim-scripts维护的GitHub repo, 自动安装, 更新和卸载插件. 它把这些繁杂的工作变得简单, 甚至, 成为一种享受.

Vundle的安装同样方便, 只需要执行:

git clone http://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

然后将下列代码加入vimrc中即可. (插件名字由git repo决定, 可以在http://vim-scripts.org/vim/scripts.html页面中查找)

set nocompatible    " be iMproved
filetype off        " required!

set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

" let Vundle manage Vundle
" required!
Bundle 'gmarik/vundle'

" vim-scripts repos
Bundle 'vim-plugin-foo'
Bundle 'vim-plugin-bar'

filetype plugin indent on    " required!

然后, 安装插件:

:BundleInstall

更新插件:

:BundleInstall!

卸载不在列表中的插件:

:BundleClean

就是这么简单, 方便. Enjoy it!


Dec 19, 2011

Kindle Touch一键换字体

今天忍不住把Kindle Touch的字体给换了, 效果如图:

顺手搞了个一键替换或还原字体的越狱包, 参考了别人的方案(ref 4), 感兴趣的朋友可以点此下载.

ref:
1, http://yifan.lu/
2, http://irising.me/2011/12/12591/
3, http://irising.me/2011/12/12600/
4, http://www.duokan.com/forum/thread-51409-1-1.html


Dec 13, 2011

在中科大关于Vim的演讲

上周末受朋友邀请, 去中科大讲了下Vim相关的东西. 感谢熊老师和USTC LUG的各位同学的安排和组织.

Slides改自林佑安的VIM Hacks, 遵循Creative Commons 3.0协议, 可从此处下载.

PS: roylez关于ZSH的Slides在此: http://roylez.heroku.com/2011/12/12/ustc-zsh-speech.html


Nov 27, 2011

关于子密钥

子密钥, 和主密钥绑定的密钥对. 它不麻烦, 很有用. 而且, 你已经在用了.

按照默认规则生成一个新密钥对, 在GnuPG控制台下list, 会有类似这样的输出:

pub  4096R/12345FOO  created: 2001-01-01  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  4096R/54321BAR  created: 2001-01-01  expires: never       usage: E

可以看到, 新生成的密钥包含一个主密钥, 作用是签名, 而且还包含一个子密钥, 作用是加密.

使用子密钥的好处在于能够更换签名或者加密密钥, 而不破坏主密钥的关系网络和Key ID. 除了默认生成的用来加密的子密钥外, 你还可以添加更多的子密钥, 用来签名或者用来加密. 它们的公钥会随着主密钥的公钥发布, 方便其他人验证或者加密.

ref:
1, http://www.gnupg.org/gph/en/manual.html
2, http://wiki.debian.org/subkeys


Nov 9, 2011

Upgraded my PGP key

For security reasons, upgraded my PGP/GPG key to 4096-bit RSA.

Key ID: 2F39D84D
Key fingerprint: BB13 C3CE A321 09A1 B93C BF49 2365 E976 2F39 D84D

ref: https://lkml.org/lkml/2011/9/30/421


Oct 30, 2011

Remove the www subdomain

The www subdomain is redundant and meaningless.

为了保持链接兼容, 我把使用www的链接301永久重定向到了主域名.

域名A记录指向IP, 再创建一个CNAME把www指向A记录, 然后在.htaccess中添加如下规则即可.

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

PS: 各位交换了友情链接的朋友可以顺手改下, 虽然不改也没什么影响 :)

ref: http://no-www.org/


Oct 22, 2011

让mutt提醒遗忘附件

最近也不知道是工作忙还是心不在焉, 发邮件经常漏掉附件. 尤其有时候是发给其它时区的同事和朋友, 一来一回就耽误一整天, 很影响效率.

这种事情想来也好处理, 把mutt的sendmail指向一个脚本. 先检测下正文中有没有出现Attach之类的词, 出现了而且没有附件的时候就提醒添加. 直到符合条件或者通过zenity等方式略过检查才发出去.

mutt中就下面这么一句. 但注意: 如果record, 没发送成功也会存一份, 用my_hdr Bcc:实现record就可以避免.

set sendmail="pre-sendmail"

我的配置和脚本还是放在这里, 基本上是抄的MuttWiki, 稍微做了些改进.

其实本来是想通过mutt的send2-hook, 然后exec 实现的, 但是交互性太差, 还是用脚本灵活些. 于是为了实现这个功能我顺便放弃了mutt内置的imap和smtp, 转而使用offlineimap和msmtp. 也好, 本地存储更快, 又能离线浏览. Happy accident!

PS: 另外介绍一个mutt小技巧, 标记所有邮件为已读:

macro index \cr "<tag-pattern>.\n<tag-prefix><clear-flag>N<untag-pattern>.\n"