CubieBoard中文论坛

 找回密码
 立即注册
搜索
热搜: unable
查看: 12752|回复: 6

对于cubieboard的sunxi kernel的研究笔记

[复制链接]
发表于 2013-10-3 10:04:51 | 显示全部楼层 |阅读模式
本帖最后由 tll 于 2013-10-3 10:45 编辑

因为看到老外做arm模拟器在avr单片机上跑linux启动bash(花6小时),感觉自己也要试试,要是能在我的Huluboard(和UNO配置一样,328p)上跑linux我该多高兴啊,但不管是否成功,能学到是最好
于是先从kernel抓起,找准一个以前编译的内核,启动ubuntu,没错,uImage,就你了。
  1. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output#
  2. hexdump -C uImage -n 64
  3. 00000000  27 05 19 56 7f 91 23 3a  51 a1 53 0b 00 3f dd 28  |'..V..#:Q.S..?.(|
  4. 00000010  40 00 80 00 40 00 80 00  83 e5 d5 e1 05 02 02 00  |@...@...........|
  5. 00000020  4c 69 6e 75 78 2d 33 2e  34 2e 34 33 00 00 00 00  |Linux-3.4.43....|
  6. 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
  7. 00000040
复制代码
uImage的前64个字节是文件头,后面是zImage
我们可以试试:
  1. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C uImage -n 70
  2. 00000000  27 05 19 56 7f 91 23 3a  51 a1 53 0b 00 3f dd 28  |'..V..#:Q.S..?.(|
  3. 00000010  40 00 80 00 40 00 80 00  83 e5 d5 e1 05 02 02 00  |@...@...........|
  4. 00000020  4c 69 6e 75 78 2d 33 2e  34 2e 34 33 00 00 00 00  |Linux-3.4.43....|
  5. 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
  6. 00000040  00 00 a0 e1 00 00                                 |......|
  7. 00000046
  8. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C zImage -n 6
  9. 00000000  00 00 a0 e1 00 00                                 |......|
  10. 00000006
  11. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output#
复制代码
大家应该看出来了吧?uImage(以下可能简称u)后面的6个字节和zImage(同理可能简称)的前6字节一致,也就是说,要从uImage里提取zImage,一个dd命令即可,dd if=uImage of=zImage bs=1 seek=64,不知道对不对……
好吧,研究kernel,看u-boot的code比较合适,因为u-boot是启动kernel的
u-boot下:
include/image.h
跳过一些code,来啦!
系统代码,CPU代码,映像格式,压缩格式
  1. /*
  2. * Operating System Codes
  3. */
  4. #define IH_OS_INVALID                0        /* Invalid OS        */
  5. #define IH_OS_OPENBSD                1        /* OpenBSD        */
  6. #define IH_OS_NETBSD                2        /* NetBSD        */
  7. #define IH_OS_FREEBSD                3        /* FreeBSD        */
  8. #define IH_OS_4_4BSD                4        /* 4.4BSD        */
  9. #define IH_OS_LINUX                5        /* Linux        */
  10. #define IH_OS_SVR4                6        /* SVR4                */
  11. #define IH_OS_ESIX                7        /* Esix                */
  12. #define IH_OS_SOLARIS                8        /* Solaris        */
  13. #define IH_OS_IRIX                9        /* Irix                */
  14. #define IH_OS_SCO                10        /* SCO                */
  15. #define IH_OS_DELL                11        /* Dell                */
  16. #define IH_OS_NCR                12        /* NCR                */
  17. #define IH_OS_LYNXOS                13        /* LynxOS        */
  18. #define IH_OS_VXWORKS                14        /* VxWorks        */
  19. #define IH_OS_PSOS                15        /* pSOS                */
  20. #define IH_OS_QNX                16        /* QNX                */
  21. #define IH_OS_U_BOOT                17        /* Firmware        */
  22. #define IH_OS_RTEMS                18        /* RTEMS        */
  23. #define IH_OS_ARTOS                19        /* ARTOS        */
  24. #define IH_OS_UNITY                20        /* Unity OS        */
  25. #define IH_OS_INTEGRITY                21        /* INTEGRITY        */
  26. #define IH_OS_OSE                22        /* OSE                */
  27. #define IH_OS_PLAN9                23        /* Plan 9        */

  28. /*
  29. * CPU Architecture Codes (supported by Linux)
  30. */
  31. #define IH_ARCH_INVALID                0        /* Invalid CPU        */
  32. #define IH_ARCH_ALPHA                1        /* Alpha        */
  33. #define IH_ARCH_ARM                2        /* ARM                */
  34. #define IH_ARCH_I386                3        /* Intel x86        */
  35. #define IH_ARCH_IA64                4        /* IA64                */
  36. #define IH_ARCH_MIPS                5        /* MIPS                */
  37. #define IH_ARCH_MIPS64                6        /* MIPS         64 Bit */
  38. #define IH_ARCH_PPC                7        /* PowerPC        */
  39. #define IH_ARCH_S390                8        /* IBM S390        */
  40. #define IH_ARCH_SH                9        /* SuperH        */
  41. #define IH_ARCH_SPARC                10        /* Sparc        */
  42. #define IH_ARCH_SPARC64                11        /* Sparc 64 Bit */
  43. #define IH_ARCH_M68K                12        /* M68K                */
  44. #define IH_ARCH_MICROBLAZE        14        /* MicroBlaze   */
  45. #define IH_ARCH_NIOS2                15        /* Nios-II        */
  46. #define IH_ARCH_BLACKFIN        16        /* Blackfin        */
  47. #define IH_ARCH_AVR32                17        /* AVR32        */
  48. #define IH_ARCH_ST200                18        /* STMicroelectronics ST200  */
  49. #define IH_ARCH_SANDBOX                19        /* Sandbox architecture (test only) */
  50. #define IH_ARCH_NDS32                20        /* ANDES Technology - NDS32  */
  51. #define IH_ARCH_OPENRISC        21        /* OpenRISC 1000  */

  52. /*
  53. * Image Types
  54. *
  55. * "Standalone Programs" are directly runnable in the environment
  56. *        provided by U-Boot; it is expected that (if they behave
  57. *        well) you can continue to work in U-Boot after return from
  58. *        the Standalone Program.
  59. * "OS Kernel Images" are usually images of some Embedded OS which
  60. *        will take over control completely. Usually these programs
  61. *        will install their own set of exception handlers, device
  62. *        drivers, set up the MMU, etc. - this means, that you cannot
  63. *        expect to re-enter U-Boot except by resetting the CPU.
  64. * "RAMDisk Images" are more or less just data blocks, and their
  65. *        parameters (address, size) are passed to an OS kernel that is
  66. *        being started.
  67. * "Multi-File Images" contain several images, typically an OS
  68. *        (Linux) kernel image and one or more data images like
  69. *        RAMDisks. This construct is useful for instance when you want
  70. *        to boot over the network using BOOTP etc., where the boot
  71. *        server provides just a single image file, but you want to get
  72. *        for instance an OS kernel and a RAMDisk image.
  73. *
  74. *        "Multi-File Images" start with a list of image sizes, each
  75. *        image size (in bytes) specified by an "uint32_t" in network
  76. *        byte order. This list is terminated by an "(uint32_t)0".
  77. *        Immediately after the terminating 0 follow the images, one by
  78. *        one, all aligned on "uint32_t" boundaries (size rounded up to
  79. *        a multiple of 4 bytes - except for the last file).
  80. *
  81. * "Firmware Images" are binary images containing firmware (like
  82. *        U-Boot or FPGA images) which usually will be programmed to
  83. *        flash memory.
  84. *
  85. * "Script files" are command sequences that will be executed by
  86. *        U-Boot's command interpreter; this feature is especially
  87. *        useful when you configure U-Boot to use a real shell (hush)
  88. *        as command interpreter (=> Shell Scripts).
  89. */

  90. #define IH_TYPE_INVALID                0        /* Invalid Image                */
  91. #define IH_TYPE_STANDALONE        1        /* Standalone Program                */
  92. #define IH_TYPE_KERNEL                2        /* OS Kernel Image                */
  93. #define IH_TYPE_RAMDISK                3        /* RAMDisk Image                */
  94. #define IH_TYPE_MULTI                4        /* Multi-File Image                */
  95. #define IH_TYPE_FIRMWARE        5        /* Firmware Image                */
  96. #define IH_TYPE_SCRIPT                6        /* Script file                        */
  97. #define IH_TYPE_FILESYSTEM        7        /* Filesystem Image (any type)        */
  98. #define IH_TYPE_FLATDT                8        /* Binary Flat Device Tree Blob        */
  99. #define IH_TYPE_KWBIMAGE        9        /* Kirkwood Boot Image                */
  100. #define IH_TYPE_IMXIMAGE        10        /* Freescale IMXBoot Image        */
  101. #define IH_TYPE_UBLIMAGE        11        /* Davinci UBL Image                */
  102. #define IH_TYPE_OMAPIMAGE        12        /* TI OMAP Config Header Image        */
  103. #define IH_TYPE_AISIMAGE        13        /* TI Davinci AIS Image                */
  104. #define IH_TYPE_KERNEL_NOLOAD        14        /* OS Kernel Image, can run from any load address */
  105. #define IH_TYPE_PBLIMAGE        15        /* Freescale PBL Boot Image        */

  106. /*
  107. * Compression Types
  108. */
  109. #define IH_COMP_NONE                0        /*  No         Compression Used        */
  110. #define IH_COMP_GZIP                1        /* gzip         Compression Used        */
  111. #define IH_COMP_BZIP2                2        /* bzip2 Compression Used        */
  112. #define IH_COMP_LZMA                3        /* lzma  Compression Used        */
  113. #define IH_COMP_LZO                4        /* lzo   Compression Used        */
复制代码
还有个define:
  1. #define IH_MAGIC        0x27051956        /* Image Magic Number                */
  2. #define IH_NMLEN                32        /* Image Name Length                */
复制代码
接下来是struct:
  1. /*
  2. * Legacy format image header,
  3. * all data in network byte order (aka natural aka bigendian).
  4. */
  5. typedef struct image_header {
  6.         __be32                ih_magic;        /* Image Header Magic Number        */
  7.         __be32                ih_hcrc;        /* Image Header CRC Checksum        */
  8.         __be32                ih_time;        /* Image Creation Timestamp        */
  9.         __be32                ih_size;        /* Image Data Size                */
  10.         __be32                ih_load;        /* Data         Load  Address                */
  11.         __be32                ih_ep;                /* Entry Point Address                */
  12.         __be32                ih_dcrc;        /* Image Data CRC Checksum        */
  13.         uint8_t                ih_os;                /* Operating System                */
  14.         uint8_t                ih_arch;        /* CPU architecture                */
  15.         uint8_t                ih_type;        /* Image Type                        */
  16.         uint8_t                ih_comp;        /* Compression Type                */
  17.         uint8_t                ih_name[IH_NMLEN];        /* Image Name                */
  18. } image_header_t;

  19. typedef struct image_info {
  20.         ulong                start, end;                /* start/end of blob */
  21.         ulong                image_start, image_len; /* start of image within blob, len of image */
  22.         ulong                load;                        /* load addr for the image */
  23.         uint8_t                comp, type, os;                /* compression, type of image, os type */
  24. } image_info_t;
复制代码
经过查询发现IH_NMLEN = 32,于是判断后32byte是内核名字,果然
  1. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C uImage -n 32
  2. 00000000  27 05 19 56 7f 91 23 3a  51 a1 53 0b 00 3f dd 28  |'..V..#:Q.S..?.(|
  3. 00000010  40 00 80 00 40 00 80 00  83 e5 d5 e1 05 02 02 00  |@...@...........|
  4. 00000020
  5. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C uImage -n 32 -s 32
  6. 00000020  4c 69 6e 75 78 2d 33 2e  34 2e 34 33 00 00 00 00  |Linux-3.4.43....|
  7. 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
  8. 00000040
  9. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output#
复制代码
前面一直没想起来,去找各个位置定义,后来突然想起struct里的定义和位置有关
大家参考这个:
  1. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C uImage -n 32
  2. 00000000  27 05 19 56 7f 91 23 3a  51 a1 53 0b 00 3f dd 28  |'..V..#:Q.S..?.(|
  3. 00000010  40 00 80 00 40 00 80 00  83 e5 d5 e1 05 02 02 00  |@...@...........|
  4. 00000020
复制代码
根据struct的定义,发现32字节的末尾有05 02 02 00,它们的定义在上面有贴,uint8_t类型,就是8个bit,一个byte:
05  Linux
02  ARM
02  KERNEL
00  无压缩
然后继续往前,__be32类型,32个bit有符号,也就是4个byte,struct里面写的是dcrc,看注释,data的crc,那么就是zImage的crc,这个嘛,用crc32程序看看(crc32是根据ubuntu提示安装的,叫libarchive-zip-perl)
  1. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# crc32 zImage
  2. 83e5d5e1
  3. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output#
复制代码
大家往上看,是不是有个83 e5 d5 e1?说明是正确的
再来,两个address
40 00 80 00 40 00 80 00
两个都是40 00 80 00
参考这个帖子,里面有内核引导数据:http://cn.cubieboard.org/forum.php?mod=viewthread&tid=601&extra=
没错,对了,就是40008000
再来,00 35 DD 28,是大小,data size,就是zImage的size
先用计算机换成10进制
0x0035dd28=4185384
然后呢:
  1. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# ls -l zImage
  2. -rwxr-xr-x 1 root root 4185384 Oct  2 17:58 zImage
  3. root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output#
复制代码
啊哈~
接下来,timestamp,时间戳。
51 a1 53 0b=1369527051
网上找个时间戳转换工具http://tool.chinaz.com/Tools/unixtime.aspx
转换得2013年5月26日格林尼治标准时间+0800上午8时10分51秒
上面的hcrc个我就觉得有点奇怪了,header里面调header的CRC?!
附上函数:
  1. int image_check_hcrc(const image_header_t *hdr)
  2. {
  3.         ulong hcrc;
  4.         ulong len = image_get_header_size();
  5.         image_header_t header;

  6.         /* Copy header so we can blank CRC field for re-calculation */
  7.         memmove(&header, (char *)hdr, image_get_header_size());
  8.         image_set_hcrc(&header, 0);

  9.         hcrc = crc32(0, (unsigned char *)&header, len);

  10.         return (hcrc == image_get_hcrc(hdr));
  11. }
复制代码
为啥用memmove,为啥不直接调用hdr?初学C,感觉有点奇怪
看了下:http://blog.csdn.net/ecbtnrt/article/details/6707113
看着一堆include的h文件发晕,大家有啥办法自动检测函数位置不?
跳过,继续,magic魔术,是判断是不是所需镜像的
内部定义:
  1. #define IH_MAGIC        0x27051956        /* Image Magic */
复制代码
正好里面是27 05 19 56,也正好了
看的文章:
http://atmel.eefocus.com/article ... tml?sort=1098_0_0_0
http://bbs.chinaunix.net/thread-1916502-1-1.html
http://os.chinaunix.net/a2009/1203/1000/000001000100.shtml
http://www.360doc.com/content/09/0727/00/26398_4475381.shtml
http://blog.csdn.net/linweig/article/details/5044978
http://blog.csdn.net/ecbtnrt/article/details/6707113
回复

使用道具 举报

发表于 2013-12-23 00:21:31 | 显示全部楼层
mark ,五个字,五个字
回复 支持 反对

使用道具 举报

发表于 2013-12-24 18:26:26 | 显示全部楼层
328P能kernel????8位的跑32位???
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-16 13:25:27 | 显示全部楼层
jiangdou 发表于 2013-12-24 18:26
328P能kernel????8位的跑32位???

唉,uARM,自己搜,把arduino作为模拟器模拟ARM,有人试过确实可以
回复 支持 反对

使用道具 举报

发表于 2014-1-17 09:27:36 | 显示全部楼层
MEMMOVE(3)                 Linux Programmer's Manual                MEMMOVE(3)

NAME
       memmove - copy memory area

SYNOPSIS
       #include <string.h>

       void *memmove(void *dest, const void *src, size_t n);

DESCRIPTION
       The  memmove()  function  copies n bytes from memory area src to memory
       area dest.  The memory areas may overlap: copying takes place as though
       the  bytes in src are first copied into a temporary array that does not
       overlap src or dest, and the bytes are then copied from  the  temporary
       array to dest.

RETURN VALUE
       The memmove() function returns a pointer to dest.
--

ps  : man memove
回复 支持 反对

使用道具 举报

发表于 2014-1-17 09:29:41 | 显示全部楼层
Hi, guy, do you try ucos ii  on A10 or A20 ?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-18 15:03:53 | 显示全部楼层
醉月 发表于 2014-1-17 09:29
Hi, guy, do you try ucos ii  on A10 or A20 ?

UCOS,没有。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|粤ICP备13051116号|cubie.cc---深刻的嵌入式技术讨论社区

GMT+8, 2024-5-3 21:13 , Processed in 0.028000 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2012 Comsenz Inc. | Style by Coxxs

返回顶部