LiangShuang's ...

I'm not a programmer...

用crosstool-NG-1.9.3构建ARM工具链

    在成功重装了两次系统之后之前的移植工作终于还是被我弄丢了,无奈只好一切重头再来了。
    首先下载u-boot源码,下载地址为ftp://ftp.denx.de/pub/u-boot/,这次将要移植的版本为2010-12。
    制作交叉工具链(Cross-Tool),还是使用crosstool-NG来制作编译工具,下载地址:http://ymorin.is-a-geek.org/download/crosstool-ng 。版本为1.9.3,这个工具的使用方法可以在文档或是http://ymorin.is-a-geek.org/projects/crosstool中找到,由于之前在弄crosstool的时候遇到一些问题,所以这次也把它的安装过程和使用方法记录下来。
    Features of This Tool

"Uncompressing Linux......................."

    最近看了一本超级强大的书Embeded Linux Primer,里面介绍了内核调试的一种方法可以通过转储printk日志缓冲区的方法来查看内核的打印内容。开始还有些奇怪,为什么start_kernel中的printk一直不起作用呢?难道是程序没有跳转到这里,但是自己都检查几遍之前的代码了,应该没什么问题。这才知道原来printk在终端设备初始化之前是先把打印的内容暂存到自己的日志缓冲区中的,只有等终端设备初始化后才一起投放到我们面前,所以console_init()函数执行之前我们不会看到任何printk打印的信息,最多只能看到内核自解压时打印的那句"Uncompressing Linux.......................",不过这已经让我兴奋不已了<^_^>,为了定位到程序的出错位置,我首先使用串口控制台的打印函数printascii(),这个函数是.../arch/arm/kernel/debug.S中定义的,非常有趣的是在文件的注释处有这么一段英文描述:

/*
 * Some debugging routines (useful if you've got MM problems and
 * printk isn't working).  For DEBUGGING ONLY!!!  Do not leave
 * references to these in a production kernel!
 */


     看来内核的设计者早就知道我们会遇到“MM problems”了,这些函数足够我们debug用的了,printascii函数还是在内核启动早期的.../arch/arm/kernel/head-common.S中用到过,不过此时MMU已经打开了,怎么还能使用IO地址空间打印东西呢,不用担心,这个在早期的建立页表的函数head.S中的__create_page_tables()中就完成了映射工作,不过需要在内核配置时打开CONFIG_DEBUG_LL配置开关,通过这种方法我定位到了内核死在了setup_arch()->paging_init()->bootmem_init()处。接下来就是通过转储printk的日志缓冲区来显示panic()的信息了,首先我们必须知道日志缓冲区的在内存中的地址,这个可以通过查看System.map中的__log_buf得到,通过查找我得到了这样一条记录c025e018 b __log_buf,其中__log_buf是在.../kernel/printk.c中定义的,还有一个问题就是我们需要将c025e018这个地址转化一下,因为很显然这是一个虚拟地址,然后就可以利用u-boot的工具md打印内存地址上的内容了,md 3025e018,虽然显示的都是ascii码,读起来不是很方便,但是还是能够看到"bootmem alloc of 32768 bytes failed!"的错误信息。。。

    说到了这里,那内核为什么停在了bootmem_init()处了呢?