tll 发表于 2013-10-3 10:04:51

对于cubieboard的sunxi kernel的研究笔记

本帖最后由 tll 于 2013-10-3 10:45 编辑

因为看到老外做arm模拟器在avr单片机上跑linux启动bash(花6小时),感觉自己也要试试,要是能在我的Huluboard(和UNO配置一样,328p)上跑linux我该多高兴啊,但不管是否成功,能学到是最好
于是先从kernel抓起,找准一个以前编译的内核,启动ubuntu,没错,uImage,就你了。root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output#
hexdump -C uImage -n 64
0000000027 05 19 56 7f 91 23 3a51 a1 53 0b 00 3f dd 28|'..V..#:Q.S..?.(|
0000001040 00 80 00 40 00 80 0083 e5 d5 e1 05 02 02 00|@...@...........|
000000204c 69 6e 75 78 2d 33 2e34 2e 34 33 00 00 00 00|Linux-3.4.43....|
0000003000 00 00 00 00 00 00 0000 00 00 00 00 00 00 00|................|
00000040uImage的前64个字节是文件头,后面是zImage
我们可以试试:root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C uImage -n 70
0000000027 05 19 56 7f 91 23 3a51 a1 53 0b 00 3f dd 28|'..V..#:Q.S..?.(|
0000001040 00 80 00 40 00 80 0083 e5 d5 e1 05 02 02 00|@...@...........|
000000204c 69 6e 75 78 2d 33 2e34 2e 34 33 00 00 00 00|Linux-3.4.43....|
0000003000 00 00 00 00 00 00 0000 00 00 00 00 00 00 00|................|
0000004000 00 a0 e1 00 00                                 |......|
00000046
root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C zImage -n 6
0000000000 00 a0 e1 00 00                                 |......|
00000006
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代码,映像格式,压缩格式/*
* Operating System Codes
*/
#define IH_OS_INVALID                0      /* Invalid OS      */
#define IH_OS_OPENBSD                1      /* OpenBSD      */
#define IH_OS_NETBSD                2      /* NetBSD      */
#define IH_OS_FREEBSD                3      /* FreeBSD      */
#define IH_OS_4_4BSD                4      /* 4.4BSD      */
#define IH_OS_LINUX                5      /* Linux      */
#define IH_OS_SVR4                6      /* SVR4                */
#define IH_OS_ESIX                7      /* Esix                */
#define IH_OS_SOLARIS                8      /* Solaris      */
#define IH_OS_IRIX                9      /* Irix                */
#define IH_OS_SCO                10      /* SCO                */
#define IH_OS_DELL                11      /* Dell                */
#define IH_OS_NCR                12      /* NCR                */
#define IH_OS_LYNXOS                13      /* LynxOS      */
#define IH_OS_VXWORKS                14      /* VxWorks      */
#define IH_OS_PSOS                15      /* pSOS                */
#define IH_OS_QNX                16      /* QNX                */
#define IH_OS_U_BOOT                17      /* Firmware      */
#define IH_OS_RTEMS                18      /* RTEMS      */
#define IH_OS_ARTOS                19      /* ARTOS      */
#define IH_OS_UNITY                20      /* Unity OS      */
#define IH_OS_INTEGRITY                21      /* INTEGRITY      */
#define IH_OS_OSE                22      /* OSE                */
#define IH_OS_PLAN9                23      /* Plan 9      */

/*
* CPU Architecture Codes (supported by Linux)
*/
#define IH_ARCH_INVALID                0      /* Invalid CPU      */
#define IH_ARCH_ALPHA                1      /* Alpha      */
#define IH_ARCH_ARM                2      /* ARM                */
#define IH_ARCH_I386                3      /* Intel x86      */
#define IH_ARCH_IA64                4      /* IA64                */
#define IH_ARCH_MIPS                5      /* MIPS                */
#define IH_ARCH_MIPS64                6      /* MIPS         64 Bit */
#define IH_ARCH_PPC                7      /* PowerPC      */
#define IH_ARCH_S390                8      /* IBM S390      */
#define IH_ARCH_SH                9      /* SuperH      */
#define IH_ARCH_SPARC                10      /* Sparc      */
#define IH_ARCH_SPARC64                11      /* Sparc 64 Bit */
#define IH_ARCH_M68K                12      /* M68K                */
#define IH_ARCH_MICROBLAZE      14      /* MicroBlaze   */
#define IH_ARCH_NIOS2                15      /* Nios-II      */
#define IH_ARCH_BLACKFIN      16      /* Blackfin      */
#define IH_ARCH_AVR32                17      /* AVR32      */
#define IH_ARCH_ST200                18      /* STMicroelectronics ST200*/
#define IH_ARCH_SANDBOX                19      /* Sandbox architecture (test only) */
#define IH_ARCH_NDS32                20      /* ANDES Technology - NDS32*/
#define IH_ARCH_OPENRISC      21      /* OpenRISC 1000*/

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

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

/*
* Compression Types
*/
#define IH_COMP_NONE                0      /*No         Compression Used      */
#define IH_COMP_GZIP                1      /* gzip         Compression Used      */
#define IH_COMP_BZIP2                2      /* bzip2 Compression Used      */
#define IH_COMP_LZMA                3      /* lzmaCompression Used      */
#define IH_COMP_LZO                4      /* lzo   Compression Used      */
还有个define:#define IH_MAGIC      0x27051956      /* Image Magic Number                */
#define IH_NMLEN                32      /* Image Name Length                */接下来是struct:/*
* Legacy format image header,
* all data in network byte order (aka natural aka bigendian).
*/
typedef struct image_header {
      __be32                ih_magic;      /* Image Header Magic Number      */
      __be32                ih_hcrc;      /* Image Header CRC Checksum      */
      __be32                ih_time;      /* Image Creation Timestamp      */
      __be32                ih_size;      /* Image Data Size                */
      __be32                ih_load;      /* Data         LoadAddress                */
      __be32                ih_ep;                /* Entry Point Address                */
      __be32                ih_dcrc;      /* Image Data CRC Checksum      */
      uint8_t                ih_os;                /* Operating System                */
      uint8_t                ih_arch;      /* CPU architecture                */
      uint8_t                ih_type;      /* Image Type                        */
      uint8_t                ih_comp;      /* Compression Type                */
      uint8_t                ih_name;      /* Image Name                */
} image_header_t;

typedef struct image_info {
      ulong                start, end;                /* start/end of blob */
      ulong                image_start, image_len; /* start of image within blob, len of image */
      ulong                load;                        /* load addr for the image */
      uint8_t                comp, type, os;                /* compression, type of image, os type */
} image_info_t;经过查询发现IH_NMLEN = 32,于是判断后32byte是内核名字,果然root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C uImage -n 32
0000000027 05 19 56 7f 91 23 3a51 a1 53 0b 00 3f dd 28|'..V..#:Q.S..?.(|
0000001040 00 80 00 40 00 80 0083 e5 d5 e1 05 02 02 00|@...@...........|
00000020
root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C uImage -n 32 -s 32
000000204c 69 6e 75 78 2d 33 2e34 2e 34 33 00 00 00 00|Linux-3.4.43....|
0000003000 00 00 00 00 00 00 0000 00 00 00 00 00 00 00|................|
00000040
root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output#
前面一直没想起来,去找各个位置定义,后来突然想起struct里的定义和位置有关
大家参考这个:root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# hexdump -C uImage -n 32
0000000027 05 19 56 7f 91 23 3a51 a1 53 0b 00 3f dd 28|'..V..#:Q.S..?.(|
0000001040 00 80 00 40 00 80 0083 e5 d5 e1 05 02 02 00|@...@...........|
00000020根据struct的定义,发现32字节的末尾有05 02 02 00,它们的定义在上面有贴,uint8_t类型,就是8个bit,一个byte:
05Linux
02ARM
02KERNEL
00无压缩
然后继续往前,__be32类型,32个bit有符号,也就是4个byte,struct里面写的是dcrc,看注释,data的crc,那么就是zImage的crc,这个嘛,用crc32程序看看(crc32是根据ubuntu提示安装的,叫libarchive-zip-perl)root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# crc32 zImage
83e5d5e1
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
然后呢:root@ubuntu:~/kernel/linux-sunxi-sunxi-3.4/output# ls -l zImage
-rwxr-xr-x 1 root root 4185384 Oct2 17:58 zImage
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?!
附上函数:int image_check_hcrc(const image_header_t *hdr)
{
        ulong hcrc;
        ulong len = image_get_header_size();
        image_header_t header;

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

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

        return (hcrc == image_get_hcrc(hdr));
}为啥用memmove,为啥不直接调用hdr?初学C,感觉有点奇怪
看了下:http://blog.csdn.net/ecbtnrt/article/details/6707113
看着一堆include的h文件发晕,大家有啥办法自动检测函数位置不?
跳过,继续,magic魔术,是判断是不是所需镜像的
内部定义:#define IH_MAGIC        0x27051956        /* Image Magic */正好里面是27 05 19 56,也正好了
看的文章:
http://atmel.eefocus.com/article/12-04/833141334025647.html?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

Darwin 发表于 2013-12-23 00:21:31

mark ,五个字,五个字

jiangdou 发表于 2013-12-24 18:26:26

328P能kernel????8位的跑32位???

tll 发表于 2014-1-16 13:25:27

jiangdou 发表于 2013-12-24 18:26 static/image/common/back.gif
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
       Thememmove()functioncopies n bytes from memory area src to memory
       area dest.The memory areas may overlap: copying takes place as though
       thebytes in src are first copied into a temporary array that does not
       overlap src or dest, and the bytes are then copied fromthetemporary
       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 iion A10 or A20 ?

tll 发表于 2014-1-18 15:03:53

醉月 发表于 2014-1-17 09:29 static/image/common/back.gif
Hi, guy, do you try ucos iion A10 or A20 ?

UCOS,没有。
页: [1]
查看完整版本: 对于cubieboard的sunxi kernel的研究笔记