免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2104 | 回复: 0
打印 上一主题 下一主题

一篇让我自惭形秽的博客-看看人家的博客做的多好-vivi开发笔记【专辑】 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-27 10:26 |只看该作者 |倒序浏览

                                文章说明:calmarrow(lqm)原创
文章引自:
http://piaoxiang.cublog.cn


2007-07-21

    今天把vivi编译了一下,顺便解决了几个问题。算是初步工作吧,下一步打算读vivi的源代码,然后改造一下,最后争取自己完成一个小的bootloader。

准备工作(这些都是基于EDUKIT-III教学平台,虽然开发工具上有些不同,但是原理和流程上是相同的。相信理解了嵌入式系统开发流程之后,对这些就会有很清晰的认识):

1)下载Nand_Prog.ide.bin到nor flash。这步工作是为烧写nand
flash做准备的。为什么不利用仿真器直接烧写nand flash呢?理解了JTAG的原理后,对这步工作不难理解。nand flash和nor
flash是不同的,nand
flash的烧写需要ECC算法等,比较复杂。现在的这个仿真器不支持,所以就不能利用JTAG来直接烧写了。当然,如果在仿真器支持软件中加入对
nand flash烧写的支持,这步工作就省去了。就我所知,国内foxICE已经可以支持直接烧写nand flash了。

2)开发环境
    还是windowsXP+VMware+redhat 9。原来学习at91rm9200的时候,开发环境都已经搭建好了,开发工具也比较齐全。

3)目标
    移植好的vivi能支持从nand
flash启动,测试内置的命令正常,利用开发板原来的内核映象和文件系统能够跑起来。vivi毕竟是一个比较小巧的bootloader,功能有限,使
用上可能有不方便的地方,所以,可以考虑在此基础上,读源代码,然后增加tftp下载功能。

开始工作

1)下载vivi

  
我使用EDUKIT-III光盘中提供的vivi-20060929.tar.gz。解压不必细说,下面就开始修改。下面的修改方案是基于网上帖子,因为
还没有仔细分析源代码,所以有些地方还不能理解清晰,这里的移植是为了获得直观的印象,如果要想得到技术水平的提升,那还是得深入分析vivi源代码,看
看这一切究竟是如何完成的。

2)修改Makefile
    因为国内大部分S3C2410的设计都是抄袭smdk2410,所以vivi的移植相对来说,工作量很小,只需要更改开发工具的几个宏就可以了。当然,如果想要增加功能,则改动可能会大一点。

只要更改如下:
LINUX_INCLUDE_DIR -- 更改为交叉编译器的include文件夹
CROSS_COMPILE     -- 交叉编译器的可执行文件的路径
ARM_GCC_LIBS      -- 交叉编译器的lib库文件的路径

################## Modified Start ####################################
# Data : 2007-07-21
# Modified by Liu Qingmin piaoxiangxinling@163.com>
#
# change this to point to the Linux include directory
#
# orginal setup
#LINUX_INCLUDE_DIR = /opt/host/armv4l/include/
# my setup
LINUX_INCLUDE_DIR = /usr/local/arm/2.95.3/include
################# Modified End ######################################
################## Modified Start ####################################
# Data : 2007-07-21
# Modified by Liu Qingmin piaoxiangxinling@163.com>
# orginal setup
#CROSS_COMPILE = /opt/host/armv4l/bin/armv4l-redhat-linux-
#CROSS_COMPILE = /opt/host/armv4l/bin/armv4l-unknown-linux-
# my setup
CROSS_COMPILE = /usr/local/arm/2.95.3/bin/arm-linux-
################# Modified End ######################################
################## Modified Start ####################################
# Data : 2007-07-21
# Modified by Liu Qingmin piaoxiangxinling@163.com>
#
# Location of the gcc arm libs.
#
# orginal setup
#ARM_GCC_LIBS = /opt/host/armv4l/lib/gcc-lib/armv4l-unknown-linux/2.95.2
#ARM_GCC_LIBS = /opt/host/armv4l/lib/gcc-lib/armv4l-redhat-linux/2.95.3
# my setup
ARM_GCC_LIBS = /usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3
################# Modified End ######################################

    这些都比较简单。

3)修改arch/s3c2410/smdk.c
    主要是修改nand flash分区信息。

#ifdef CONFIG_S3C2410_NAND_BOOT
mtd_partition_t default_mtd_partitions[] = {
        {
                name:           "vivi",         /* 128K, 1-8 sector             */
                offset:         0,
                size:           0x00020000,
                flag:           0
        }, {
                name:           "param",        /* 64K, 9-12 sector             */
                offset:         0x00020000,
                size:           0x00010000,
                flag:           0
        }, {
                name:           "kernel",       /* 2M+832K, 12-192 setctor      */
                offset:         0x00030000,
                size:           0x002d0000,
                flag:           0
        }, {
                name:           "root",         /* 29M, 193-2048 sector         */
                offset:         0x00300000,
                size:           0x01d00000,
                flag:           MF_BONFS
        }
};

    这里遇到了bon分区与mtd分区的疑惑,在分析vivi源代码时在深入分析。上面文件配置的只是mtd分区,这个可以用part show来查看。

4)编译烧写

    写个简单的批处理脚本procedure。以便后续工作的方便。【后来发现,vivi本身就提供了这样的操作,所以这个小的脚本是没有必要编写的。这一点会在Makefile分析时给出】

[root@lqm vivi]# cat procedure
#!/bin/sh
make myboard_config && make oldconfig && make vivi && cp -f vivi /mnt/hgfs/common/
   
    烧写vivi,正常。但是蜂鸣器一直在响。于是想在vivi中添加代码,关掉蜂鸣器,同时利用开发板上的四个指示灯做一个跑马灯的小程序。于是修改arch/s3c2410/head.S:

@@@@@@@@@@@@@@@@@@ Modified Start @@@@@@@@@@@@@@@@@@@@@
        mov r0, #10               @ rotate 10 times
loop:
        mov r2, #0xdf             @ D1205 led on
        str r2, [r1, #oGPIO_DAT]
        bl delay
        mov r2, #0x7f             @ D1207 led on
        str r2, [r1, #oGPIO_DAT]
        bl delay
        mov r2, #0xef             @ D1204 led on
        str r2, [r1, #oGPIO_DAT]
        bl delay
        mov r2, #0xbf             @ D1206 led on
        str r2, [r1, #oGPIO_DAT]
        bl delay
        subs r0, r0, #1
        bne loop
        mov r2, #0x0f             @ all leds on
        str r2, [r1, #oGPIO_DAT]
        @ buzzer off
        ldr r1, =0x56000010 @ GPBCON
        ldr r2, =0x155559
        str r2, [r1]
        ldr r2, =0x7ff
        str r2, [r1, #8]
        orr r2, r2, #0x01         @ buzzer off when high voltage(PWM1)
        str r2, [r1, #4]
@@@@@@@@@@@@@@@@@@ Modified End @@@@@@@@@@@@@@@@@@@@@@@@@
/*
* subroutines
*/
@@@@@@@@@@@@@@@@@@ Modified Start @@@@@@@@@@@@@@@@@@@@@
@
@ led delay
@
delay:
        ldr r3, =0x00080000
wait:
        subs r3, r3, #1
        bne wait
        mov pc, lr
@@@@@@@@@@@@@@@@@@ Modified End @@@@@@@@@@@@@@@@@@@@@

    通过source insight查看代码,可以分析出第一条打印信息的来源init/version.c。这样,just for fun,可以添加自己的启动信息。主要的参数都是有Makefile来完成的,读一下Makefile的代码,不难发现。

[root@lqm init]# cat version.c
/*
* vivi/lib/version.c
*/
#include "version.h"
#include "compile.h"
const char *vivi_banner =
                       "\n\r\t\t^_^ Well done, boy! Go on --> \n\r\n\r"
                       "VIVI version " VIVI_RELEASE " (" VIVI_COMPILE_BY "@"
                       VIVI_COMPILE_HOST ") (" VIVI_COMPILER ") " UTS_VERSION "\n\r";

【注:这里还有个小问题。就是在这里添加的时候,\n\r要合起来用,不能只用\n。原因如下:

    计算机还没有出现之前,有一种叫做电传打字机(Teletype Model
33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新
的字符传过来,那么这个字符将丢失。

    于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。

    这就是“换行”和“回车”的来历,从它们的英语名字上也可以看出一二。

   
后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分
歧。Unix
系统里,每行结尾只有“”,即“\n”;Windows系统里面,每行结尾是“”,即“\
n\r”;Mac系统里,每行结尾是“”。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变
成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。

    这几个地方我都遇到过,不过一直没有搞清楚。现在才算是找到根源了。】

    添加完成,重新执行procedure。完成烧写,测试如下:

^_^ Well done, Go on -->
VIVI version 0.1.4 (root@lqm) (gcc version 2.95.3 20010315 (release)) #0.1.4 日 7月 22 10:15:15 CST 2007
MMU table base address = 0x33DFC000
Succeed memory mapping.
NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T)
Could not found stored vivi parameters. Use default vivi parameters.
Press Return to start the LINUX now, any other key for vivi
type "help" for help.
vivi> part show
mtdpart info. (4 partitions)
name offset size flag
------------------------------------------------
vivi : 0x00000000 0x00020000 0 128k
param : 0x00020000 0x00010000 0 64k
kernel : 0x00030000 0x002d0000 0 2M+832k
root : 0x00300000 0x01d00000 4 29M
vivi>
   
    然后执行bon分区:

vivi> bon part 0 192K 3M
doing partition
offset = 0
flag = 0
offset = 196608
flag = 0
offset = 3145728
flag = 0
check bad block
part = 0 end = 196608
part = 1 end = 3145728
part = 2 end = 33554432
part0:
        offset = 0
        size = 196608
        bad_block = 0
part1:
        offset = 196608
        size = 2949120
        bad_block = 0
part2:
        offset = 3145728
        size = 30392320
        bad_block = 0
vivi>

    重新烧写vivi,注意这个时候不要断电。

vivi> load flash vivi x
Ready for downloading using xmodem...
Waiting...
正在开始 xmodem 传输。 按 Ctrl+C 取消。
正在传输 vivi...
  100% 67 KB 6 KB/s 00:00:10 0 错误
Downloaded file at 0x30000000, size = 69376 bytes
Found block size = 0x00014000
Erasing... ... done
Writing... ... done
Written 69376 bytes
vivi>

    检查分区情况:
vivi> part show
mtdpart info. (4 partitions)
name offset size flag
------------------------------------------------
vivi : 0x00000000 0x00020000 0 128k
param : 0x00020000 0x00010000 0 64k
kernel : 0x00030000 0x002d0000 0 2M+832k
root : 0x00300000 0x01d00000 4 29M
vivi> bon part show
BON info. (3 partitions)
No: offset size flags bad
---------------------------------------------
0: 0x00000000 0x00030000 00000000 0 192k
1: 0x00030000 0x002d0000 00000000 0 2M+832k
2: 0x00300000 0x01cfc000 00000000 0 28M+1008k
vivi>

    其中,part show显示的是mtd分区信息,跟smdk.c文件的配置相同。bon part show显示的bon分区信息,注意到最后一个分区少了一个扇区16K,因为bon命令把bon分区信息表存储在最后一个扇区了。

    烧写内核映象和文件系统:

vivi> load flash kernel x
Ready for downloading using xmodem...
Waiting...
正在开始 xmodem 传输。 按 Ctrl+C 取消。
正在传输 zImage...
  100% 646 KB 7 KB/s 00:01:25 0 错误
Downloaded file at 0x30000000, size = 661760 bytes
Found block size = 0x000a4000
Erasing... ... done
Writing... ... done
Written 661760 bytes
vivi>   ?
                ^_^ Well done, Go on -->
VIVI version 0.1.4 (root@lqm) (gcc version 2.95.3 20010315 (release)) #0.1.4 日 7月 22 10:15:15 CST 2007
MMU table base address = 0x33DFC000
Succeed memory mapping.
NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T)
Found saved vivi parameters.
Press Return to start the LINUX now, any other key for vivi
Copy linux kernel from 0x00030000 to 0x30008000, size = 0x002d0000 ... done
zImage magic = 0x016f2818
Setup linux parameters at 0x30000100
linux command line is: "noinitrd root=/dev/bon/2 init=/linuxrc console=ttyS0"
MACH_TYPE = 193
NOW, Booting Linux......
Uncompressing Linux............................................... done, booting the kernel.
Linux version 2.4.18-rmk7-pxa1 (root@lqm) (gcc version 2.95.3 20010315 (release)) #1 Fri Jul 20 15:12:44 CST 2007
CPU: ARM/CIRRUS Arm920Tsid(wb) revision 0
Machine: Embest EduKit II (S3C2410x)
On node 0 totalpages: 16384
zone(0): 16384 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Kernel command line: noinitrd root=/dev/bon/2 init=/linuxrc console=ttyS0
DEBUG: timer count 15626
Console: colour dummy device 80x30
Calibrating delay loop... 99.94 BogoMIPS
Memory: 64MB = 64MB total
Memory: 62880KB available (1229K code, 296K data, 60K init)
Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes)
Inode-cache hash table entries: 4096 (order: 3, 32768 bytes)
Mount-cache hash table entries: 1024 (order: 1, 8192 bytes)
Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes)
Page-cache hash table entries: 16384 (order: 4, 65536 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
CPU clock = 200.000 Mhz, HCLK = 100.000 Mhz, PCLK = 50.000 Mhz
Starting kswapd
devfs: v1.10 (20020120) Richard Gooch (rgooch@atnf.csiro.au)
devfs: boot_options: 0x1
ttyS%d0 at I/O 0x50000000 (irq = 52) is a S3C2410
ttyS%d1 at I/O 0x50004000 (irq = 55) is a S3C2410
ttyS%d2 at I/O 0x50008000 (irq = 58) is a S3C2410
Console: switching to colour frame buffer device 30x40
Installed S3C2410 frame buffer
pty: 256 Unix98 ptys configured
s3c2410-ts initialized
S3C2410 Real Time Clock Driver v0.1
block: 128 slots per queue, batch=32
eth0: cs8900 rev K(3.3 Volts) found at 0xd0000300
cs89x0 media RJ-45, IRQ 37
NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T)
bon0: 00000000-00030000 (00030000) 00000000
bon1: 00030000-00300000 (002d0000) 00000000
bon2: 00300000-01ffc000 (01cfc000) 00000000
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP, IGMP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 4096 bind 4096)
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
NetWinder Floating Point Emulator V0.95 (c) 1998-1999 Rebel.com
cramfs: wrong magic
FAT: bogus logical sector size 65535
Kernel panic: VFS: Unable to mount root fs on 61:02
vivi> load flash root x
Ready for downloading using xmodem...
Waiting...
正在开始 xmodem 传输。 按 Ctrl+C 取消。
正在传输 root.cramfs...
  100% 1104 KB 7 KB/s 00:02:22 0 错误
Downloaded file at 0x30000000, size = 1130496 bytes
Found block size = 0x00114000
Writing... size = 1130496
bad_block = 0
... done
Written 1130496 bytes
vivi>
vivi>  
                ^_^ Well done, Go on -->
VIVI version 0.1.4 (root@lqm) (gcc version 2.95.3 20010315 (release)) #0.1.4 日 7月 22 10:15:15 CST 2007
MMU table base address = 0x33DFC000
Succeed memory mapping.
NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T)
Found saved vivi parameters.
Press Return to start the LINUX now, any other key for vivi
Copy linux kernel from 0x00030000 to 0x30008000, size = 0x002d0000 ... done
zImage magic = 0x016f2818
Setup linux parameters at 0x30000100
linux command line is: "noinitrd root=/dev/bon/2 init=/linuxrc console=ttyS0"
MACH_TYPE = 193
NOW, Booting Linux......
Uncompressing Linux............................................... done, booting the kernel.
Linux version 2.4.18-rmk7-pxa1 (root@lqm) (gcc version 2.95.3 20010315 (release)) #1 Fri Jul 20 15:12:44 CST 2007
CPU: ARM/CIRRUS Arm920Tsid(wb) revision 0
Machine: Embest EduKit II (S3C2410x)
On node 0 totalpages: 16384
zone(0): 16384 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Kernel command line: noinitrd root=/dev/bon/2 init=/linuxrc console=ttyS0
DEBUG: timer count 15626
Console: colour dummy device 80x30
Calibrating delay loop... 99.94 BogoMIPS
Memory: 64MB = 64MB total
Memory: 62880KB available (1229K code, 296K data, 60K init)
Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes)
Inode-cache hash table entries: 4096 (order: 3, 32768 bytes)
Mount-cache hash table entries: 1024 (order: 1, 8192 bytes)
Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes)
Page-cache hash table entries: 16384 (order: 4, 65536 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
CPU clock = 200.000 Mhz, HCLK = 100.000 Mhz, PCLK = 50.000 Mhz
Starting kswapd
devfs: v1.10 (20020120) Richard Gooch (rgooch@atnf.csiro.au)
devfs: boot_options: 0x1
ttyS%d0 at I/O 0x50000000 (irq = 52) is a S3C2410
ttyS%d1 at I/O 0x50004000 (irq = 55) is a S3C2410
ttyS%d2 at I/O 0x50008000 (irq = 58) is a S3C2410
Console: switching to colour frame buffer device 30x40
Installed S3C2410 frame buffer
pty: 256 Unix98 ptys configured
s3c2410-ts initialized
S3C2410 Real Time Clock Driver v0.1
block: 128 slots per queue, batch=32
eth0: cs8900 rev K(3.3 Volts) found at 0xd0000300
cs89x0 media RJ-45, IRQ 37
NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T)
bon0: 00000000-00030000 (00030000) 00000000
bon1: 00030000-00300000 (002d0000) 00000000
bon2: 00300000-01ffc000 (01cfc000) 00000000
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP, IGMP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 4096 bind 4096)
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
NetWinder Floating Point Emulator V0.95 (c) 1998-1999 Rebel.com
VFS: Mounted root (cramfs filesystem).
Mounted devfs on /dev
Freeing init memory: 60K
mount /etc as ramfs
re-create the /etc/mtab entries
init started: BusyBox v1.00 (2005.06.09-02:02+0000) multi-call binary
Starting pid 17, console /dev/console: '/etc/init.d/rcS'

Embest Embedded Linux Development Paltform.

Default board ip: 192.192.192.190
To change the ip addr: ifconfig eth0 new_board_ip

Start the web server: http://(board_ip)/index.htm
To connect the NFS server, please type like:
   mkdir /etc/var/nfs
   mount -t nfs nfs_server_ip:/home/app /etc/var/nfs -o nolock
To use the USB disc(insert first), please type like:
   mount /dev/sda /mnt/udisk _OR_ mount /dev/sda1 /mnt/udisk
Please press Enter to activate this console.
Starting pid 42, console /dev/console: '/bin/sh'
~ # ls
bin etc linuxrc proc tmp var
dev lib mnt sbin usr
~ #

    一切正常。
·
vivi开发笔记(一):学习计划
·
vivi开发笔记(二):软件架构分析
·
vivi开发笔记(三):Makefile详解
·
vivi开发笔记(四):配置机制分析
·
vivi开发笔记(五):GPIO实验
·
vivi开发笔记(六):GNU Tools开发工具综述
·
vivi开发笔记(七):GNU AS基本使用方法
·
vivi开发笔记(八):GNU LD基本用法
·
vivi开发笔记(九):SDRAM实验
·
vivi开发笔记(十):nand flash与uart实验
·
vivi开发笔记(十一):中断和timer实验
·
vivi开发笔记(十二):MMU分析
·
vivi开发笔记(十三):clock
·
vivi开发笔记(十四):vivi源代码分析1
·
vivi开发笔记(十五):vivi源代码分析2
·
vivi开发笔记(十六):vivi源代码分析3
·
vivi开发笔记(十七):vivi与Linux kernel的参数传递情景分析(上)
·
vivi开发笔记(十七):vivi与Linux kernel的参数传递情景分析(下)
·
vivi开发笔记(十八):bootloader开发阶段总结
·
vivi开发笔记(二十):vivi延时函数实现不合理性的探讨
·
vivi开发笔记(十九):制作的patch集合




[color="#295200"]发表于: 2007-07-21,修改于: 2007-12-02 08:57,已浏览4981次,有评论24条
推荐
投诉







网友评论



网友:
piaoxiang
时间:2007-07-28 08:14:44    IP地址:122.4.41.★
2007-07-28
    通过后面的vivi学习才发现,为什么会需要LINUX_INCLUDE_DIR这个宏来包含内核的头文件。很简单,vivi就是Linux kernel的小“儿女”,里面有些C文件的使用仍然用了“”包含的方式。而mizi公司没有经过仔细的验证分析,认为加上这个宏就不会出现编译问题。于是,为什么网上有的人把该宏定义为编译器的include目录,有些人把它定义为kernel的include目录,编译都没有问题,就不难理解了。如果你把该宏去掉编译,仍然没有问题(也许我测试的不到位)。但是我考虑的是,vivi是bootloader,应该具有引导不同版本内核的能力,所以还是要通过测试把该宏相关的内容去除比较合适。我在后续工作中已经去掉了该宏,暂时还没有发现编译问题。
    另外,增加的蜂鸣器关闭的汇编程序也不太合适。关于它的处理应该是由[init/main.c]------[arch/s3c2410/smdk.c] board_init()-----set_gpios()来完成的。也就是说vGPBCON的值不合适。应该修改[include/platform/smdk2410.h]默认的#define vGPBCON            0x00044555。这需要查看Datasheet,了解一下GPBCON各个位的含义,然后根据自己的开发板进行修改。其他的初始状态不合适,也要考虑修改此头文件中的初始值。
    需要注意的一个小地方是,在vivi的头文件中,如果寄存器前加字母v,表示value,即取值。如果加个o,则表示offset,即偏移值。这样读程序就很容易理解了。
    vivi也就逐步清晰起来了。





网友:
spring11
时间:2007-08-31 23:40:06    IP地址:59.78.25.★
写得太好了,这是我看到的最详细的一篇!!
好想转到我的百度博客上,HOHO,不过这么好的文章还是每次都到里来吧:)
[color="#ff6600"]Blog作者的回复:
谢谢





网友:
本站网友
时间:2007-11-11 01:28:09    IP地址:210.72.218.★
佩服Super的学习态度和深度,也让我看到自己的很多不足,如果能和你成为同事,真是件辛事:)希望在以后的日子能和你多多交流,重要的是向你学习,我会给你发邮件的:)请多关照哦
[color="#ff6600"]Blog作者的回复:
^_^





网友:
bob_zhang2004
时间:2007-11-12 23:28:48    IP地址:211.103.74.★
太好了, 我们也正在讨论中,正在拜读你的文章,
也 欢迎到我们的帖子,大家一起再讨论一下:
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=driver&Number=664503&page=0&view=&sb=&o=&fpart=1&vc=1  
[color="#ff6600"]Blog作者的回复:
共同讨论。





网友:
bob_zhang2004
时间:2007-11-13 10:52:18    IP地址:58.211.114.★
>> 3、主时钟源来自外部晶振或者外部时钟。复位后,MPLL虽然默认启动,但是如果不向MPLLCON中写入value,那么外部晶振直接作为系统时钟。
>> EDUKIT-III的外部晶振有两个,一是用于系统时钟,为12MHz;一个用于RTC,为32.768KHz。
>> 以前实验没有向MPLLCON写入数值,所以系统时钟都是12MHz。
>> 从这里也可以发现一个问题,如果外部晶振开始没有焊上,那么系统是无法正常启动的。因为按照上述规则,
>> 复位后还没有写入MPLLCON,这时又没有可以使用的时钟源,所以不会启动。也就是硬件完成后,这个12MHz的晶振是一定要焊上的,
>> 才能进行后续的硬件测试工作。
您这里所说的外部时钟 , 是指什么呢? 能否举个现实中的例子。
1》不是一般情况下, 有外部晶振就够了呢?
2》  >> 但是如果不向MPLLCON中写入value,那么外部晶振直接作为系统时钟
我的疑问是: 那我要是往 MPLLCON写入value 呢? 那谁会作为系统时钟呢?      这个时候 12MHz还有意义吗?
[color="#ff6600"]Blog作者的回复:
我想,你对硬件可能不是很熟悉。
1、首先,硬件系统需要一个时钟信号。我们常用石英晶振作为这个时钟信号源。你可以看看你的板子,应该有个银白色帽子的东西,那就是晶振。再深入了解,你需要看看晶振的物理原理,了解为什么能够产生时钟信号了。
2、为了产生高频,在硬件上一般采用锁相环电路,这也是高频电路的知识。简单的说,12MHz如果作为一级时钟源,只能产生12MHz的主频,要想提到
200MHz,那就需要倍频。就是相当于12×n=200.锁相环电路完成这个n的作用,这就是MPLL的作用。等到得到了200MHz的时钟源,那么现
在的系统时钟就是1/(200MHz)了。
3、因为硬件设计的特点,具体电路就比较复杂了。简单说,要想使MPLL真正起作用,就需要一个触发事件,而这个事件就是要往MPLLCON中写入
value,确定分频比,这样电路才能接通。(主要是硬件设计部分,电路的细节我也不是太清晰,但是这种设计在51单片机等上面是很广泛的。)也就是说,
你没有理解硬件上的设计,12MHz是最初的时钟源啊,即使经过了倍频,那200MHz是二级的时钟源,这个时钟体系也是一个树状的体系结构,简称时钟
树。如果把12MHz去掉,那么200MHz的源是不可能得到的。
4、刚才说的是12MHz的晶振,另外还有一个32.768KHz的晶振,他们都是晶振,只不过频率不同,用途也不同。32.768KHz用于RTC,仅仅用作这个目的。它的这部分电路和12MHz的主频电路是不同的。
5、这里的术语可能不太严谨,所以产生了问题。外部晶振对应的是频率f,f=12MHz的话,那么对应的时钟就是1/f。二者在说法上是等同的。
简单总结一下,外部晶振和外部时钟实际是一个东西,说法不太严谨就是了,都是提供时钟树的硬件组件。关于高频的时钟设计上,要用分级的观点来考虑。一级时
钟源一般是物理的晶振,直接产生,二级时钟源则是通过锁相环电路转换产生。很显然,少了一级物理晶振,也就不可能产生二级高频时钟了。一般是二级设计,如
果是多级,就会出现时钟同步等等比较复杂的问题了。





网友:
bob_zhang2004
时间:2007-11-14 07:23:34    IP地址:211.103.74.★
非常感谢你的回答, 我对硬件懂得不多, datasheet还能看懂 , 现在就是想再深入了解一下硬件原理, 这样对kernel和driver很有好处。
听了你的阐述, 我明白了。我最后的理解是这样的: Mpll只是一个倍频输出电路, 通过它 可以 12MHz的一级时钟输入倍频输出 ,产生二级时钟,供其他的外设来使用而已。
而 MPLLCON 寄存器的作用仅仅是提供倍频参数, 用户必须写入(在我们的环境中是 u-boot初始化的时候,写入 0x5c040) ,这样MPLL 倍频电路才能生效, 产生 200MHz的输出。
如果用户不写入 MPLLCON 寄存器(即使有默认值),MPLL根本就不生效, 也就没有二级时钟了, 相当于 所有的外设都得 使用 12MHz的频率了。
所以这样看起来 , 12MHz的外部晶振必须焊接上, 按您所说 ,如果没焊上 , 板子连唯一的一级时钟都没有了, 自然无法启动了。
++++++++++++++++++++++++++++++++++++++++++++++++
[color="#ff6600"]Blog作者的回复:
对,就是这个意思。





网友:
bob_zhang2004
时间:2007-11-14 07:31:17    IP地址:211.103.74.★
对于 PLL VALUE SELECTION TABLE 表我还是有点疑惑:望指教:
图请看这里 http://blogimg.chinaunix.net/blog/upfile2/071112215834.jpg
1>  MDIV和 HDIV ,SDIV 默认值分别是 : 0x5c , 0x4 , 0x00
但是为什么表里没有0x5c 呢? 倒是有0x52 ,
PDIV 和 SDIV , 也没有对应的 0x04 和 0x0 啊?
[color="#ff6600"]Blog作者的回复:
看看公式:Mpll(Fclk)=(m×Fin)/(p×(2^s))【m=MDIV+8, p=PDIV+2,s=SDIV】
这里面有两个需要注意。一个是Fin,就是说这是一级时钟源的频率,F代表Frequency,in代表input。Mpll实际上是Main锁相环电路
的本地输出频率,实际上就是系统的Fclk。现在已知Fin为12MHz,要想获得Mpll,取决于三个参数。但是这三个参数可以是任意的,并没有死规
定,也就是我前面说的,这是一个多解方程式。
手册上也说过,表中的数据是可靠的,应用没有问题。如果我想要得到200MHz,但是表中并没有这个输出频率,而官方提供的vivi中使用了这个
200MHz,说明这个数据也是可靠的。所以在s3c2410中就普遍的使用可以生成200MHz的这三个参数了。可以说,这三个参数是源于vivi的。
之所以选择200MHz,也是为了精确定时。比如sdram的刷新频率的选择,等等。
总之,datasheet给定了公式和table。table只
是官方经过测试比较稳定的一些参数组合,并非全部。还可以有任意多的组合方式,但是呢,官方不保证你自己选择的参数在硬件上稳定可靠。而vivi也是官方
的,它提供了datasheet上没有的200MHz输出的一组参数,所以在200MHz这个时钟频率上就普遍的采用了0x5c 0x4 0x00。因为
选择200MHz在很多与时间相关的设置上的方便性,就使得200MHz成为2410上最为普遍的选择了。





网友:
bob_zhang2004
时间:2007-11-14 10:29:22    IP地址:58.211.114.★
明白了, 原来是没有写出来啊, 怪不得。
这回明白了 Fin 是什么意思, 之前只是知道肯定是 12MHz , 但就是不知道什么意思, 呵呵。
多谢了。





网友:
时间:2007-11-22 13:07:37    IP地址:202.199.138.★
科研的精神和乐于助人的精神都值得学习,非常感谢!





网友:
scanmiss
时间:2007-11-22 16:35:17    IP地址:218.5.3.★
hi, 这两个礼拜几乎每天都来,有关vivi的理解得真的不错,我现在也在写一个s3c2410的bootloader, 但是出现问题了,我用的是nor flash, sdram 64M,地址为0x30000000, 从0x30000000-0x3020000用做显示缓冲及其他功能, kernel (2.6.22)放在0x3020000+0x8000的地方, kernel参数放在0x3020000+0x100的地方,跳转到0x3020000+0x8000后就一点消息都没有,不知道是怎么回事?窜口连一点信息都不给,(提示信息到跳转到内核之前,之后的就没有了),是不是内核只能放在0x30000000,或者在什么地方有设这个值的?
[color="#ff6600"]Blog作者的回复:
内核默认是解压到mem_base+0x8000处。而这个mem_base没有通过bootloader的参数导入(参数只会导入mem的大小,默认情况下,mem_base是固定的)。所以,如果一定要在0x30200000,就需要修改内核的代码了。





网友:
scanmiss
时间:2007-11-22 17:46:35    IP地址:218.5.3.★
谢谢你的回复,
刚才我把kernel放在0x3000000的地方,但窜口也还是一点信息都没有,
我用make zImage做的内核zImage下载到nor flash, 在启动内核之前,我把mem_base+0x8000(0x30000000+0x8000)的数据打印出来如下:
e1a00000                e1a00000                e1a00000                e1a00000
e1a00000                e1a00000                e1a00000                e1a00000
ea000002                016f2818                00000000                0016b184
e1a07001                e1a08002                e10f2000                e3120003
1a000001                e3a00017                ef123456                e10f2000
e38220c0                e121f002                00000000                00000000
e28f00d0
和zImage的内容相同,窜口我用的参数传入(这用的是tag 的方式"console=ttySAC0,115200n8", 用param_struct时用的是" "noinitrd  console=ttySAC0"") 两者都不行,我用的是ADS 1.2 开发的,由于对汇编不熟,基本上是用vivi的汇编代码.
启动的代码如下:____________________________________________________
int boot_kernel(ulong from, size_t size, int media_type)
{
        int ret;
        int i;
        ulong boot_mem_base;    /* base address of bootable memory */
        ulong to;
        ulong mach_type;
        
        void (*call_linux)(int zero, int arch, unsigned long params_addr) =
          (void (*)(int, int, unsigned long))(LINUX_KERNEL_BASE + LINUX_KERNEL_OFFSET);
        boot_mem_base = LINUX_KERNEL_BASE;
    /* copy kerne image */
        to = boot_mem_base + LINUX_KERNEL_OFFSET;
        DBGMSG(DEBUG, ("Copy linux kernel from 0x%08lx to 0x%08lx, size = 0x%08lx ... ",
                from, to, size));
        ret = copy_kernel_img(to, (char *)from, size, media_type);
        if (ret)
        {
                DBGMSG(DEBUG, ("failed\n"));
                return -1;
        }
    else
        {
                DBGMSG(DEBUG, ("done\n"));
        }
        if (*(ulong *)(to + 9*4) != LINUX_ZIMAGE_MAGIC)
        {
                DBGMSG(DEBUG, ("Warning: this binary is not compressed linux kernel image\n"));
                DBGMSG(DEBUG, ("zImage magic = 0x%08lx\n", *(ulong *)(to + 9*4)));
        }
        else
        {
                DBGMSG(DEBUG, ("zImage magic = 0x%08lx\n", *(ulong *)(to + 9*4)));
        }
         /* Setup linux parameters and linux command line */
        setup_linux_param(boot_mem_base + LINUX_PARAM_OFFSET);
        /* Get machine type, see arch/arm/tools/mach-types */
        mach_type = MACH_TYPE;
        DBGMSG(DEBUG, ("MACH_TYPE = %d\n", mach_type));
        /* Go Go Go */
        DBGMSG(DEBUG, ("NOW, Booting Linux......\n"));
        clean_before_call_linux();
        
        DBGMSG(DEBUG, ("Maybe we can check some date!addr:0x%08lx \n", to));
        
        for(i = 0; i
[color="#ff6600"]Blog作者的回复:
命令行传递参数加上mem=64M。我在使用uboot的时候发现,如果不加入mem,则2.6.22的内核引导后,串口没有任何输出。





网友:
scanmiss
时间:2007-11-22 18:03:12    IP地址:218.5.3.★
晕倒,我的机器上有4个窜口,我用的窜口是"console=ttySAC1,115200n8"
刚才才恍然大悟,我没有用mem=64M
[color="#ff6600"]Blog作者的回复:
只用115200就可以了。默认就是8n1的模式。





网友:
scanmiss
时间:2007-11-22 18:52:35    IP地址:218.5.3.★
我把地址改成0x30200000后,果然内核就起不来了,
但是程序是跳转到0x30200000执行啊,机器码一个一个读进来执行,放在什么地方没什么关系吧?还是内核找不到参数表,所以就起不来了?
[color="#ff6600"]Blog作者的回复:
看看vivi开发笔记17,再读读lufuchong的bootm解析。
zImage bin文件分为三个部分,实现自解压。搬移地址是非常重要的,不能发生冲突。
这个地方与内核是相关的,并不是boot loader单方面的事情。





网友:
tianhao_1983
时间:2007-12-18 11:19:17    IP地址:221.11.46.★
这里交流的好热闹呀,看到这么多的人有如此互相学习互相帮助的积极性,真是高兴,希望向calmarrow请教学习!!





网友:
不死书生
时间:2008-01-01 21:17:19    IP地址:60.191.189.★
中国人如果多一点像你这样的人,那是中国的幸事,少一点浮华,多一点实在,中国的未来就要靠你们这样的人来支撑着。
[color="#ff6600"]Blog作者的回复:
过誉了,只是安心做自己的事情





网友:
低调
时间:2008-04-19 17:16:09    IP地址:60.22.211.★
哥们,问一下。vivi的makefile中的
init/ version.o: init/ version.c include/compile.h
    $(CC) $(CFLAGS) -DUTS_MACHINE='"$(ARCH)"' -c -o init/ version.o init/ version.c
其中的 -DUTS_MACHINE  是什么意思啊?   是给$(CC) 的参数吗?   
是arm体系的意识吧?
可是$(CC) 已经定义成arm-linux-gcc了  还要给它传递体系吗?   
为什么编译hello.c等简单的程序时,不用这个-DUTS_MACHINE  呢?
多谢!
[color="#ff6600"]Blog作者的回复:
man gcc ==> -D name=define





网友:
低调
时间:2008-04-20 11:19:33    IP地址:60.22.214.★
ifdef CONFIGURATION
..$(CONFIGURATION):
    @echo
    @echo "You have a bad or nonexistent" .$(CONFIGURATION) ": running 'make" $(CONFIGURATION)"'"
    @echo
    $(MAKE) $(CONFIGURATION)
    @echo
    @echo "Successful. Try re-making (ignore the error that follows)"
    @echo
    exit 1
dummy:
else
dummy:
endif
这是vivi的makefile中的代码
请问..$(CONFIGURATION)中的那个".."是什么意思啊?谢谢
[color="#ff6600"]Blog作者的回复:
可以把该定义规则删除,没有用处





网友:
本站网友
时间:2008-04-22 16:14:55    IP地址:218.104.217.★
vivi 请教您一个关于重定位的问题,
例如现在我有三个数据段运行顺序为
.data
.bss
.text

其中.text为重定位段,被定位到.data后面。
实际的内存存放位置为
.data
.text
.bss

我们在执行链接脚本计算.bss段起始地址大小时需要知道它前面一段的大小就是.text段的大小,但这个时候我们还不能使用SIZEOF(.text)来计算。链接的时候就会报错,请问您有没有什么好办法解决这个问题。就是在执行脚本语言的时刻可不可以在没有定义.text段时就在前面引用它, 谢谢了 。






网友:
本站网友
时间:2008-04-22 16:19:08    IP地址:218.104.217.★
CalmArrow其实我问的问题主要就是LD在执行脚本语言时只进行一次链接可不可以先计算出每个数据段的大小,然后在根据这些大小以及我们配置的运行与加载顺序生成一个二进制文件??? 谢谢了 呵呵
[color="#ff6600"]Blog作者的回复:
我认为这个问题的解决方案是按照内存的顺序编写好链接规则,这样可以通过定义的段的起始地址和终止地址得到段的位置和大小,然后增加一个搬移代码,完成搬移就可以了吧。
AT91RM9200提供的boot就是这种思路。
读一下http://blog.chinaunix.net/u/21948/showart_481779.html,会有帮助。
希望能够解决你的问题。





网友:
低调
时间:2008-04-25 23:38:13    IP地址:60.22.202.★
首先,感谢CalmArrow前面两个问题的回复。
这两天被vivi的分区弄得晕头转向,在网上找了些文章还是有点晕。
能帮我们讲讲vivi分区,part show看到的分区,bon分区,mtd分区到底都是 干什么的吗?为什么 还要通过bon命令重新设置分区呢?  不能 在vivi源代码中改写吗?   多谢了:)
[color="#ff6600"]Blog作者的回复:
采用bon分区主要是为了把分区表信息传递给内核,这样内核就不需要再次配置分区表。通信是双方的,所以内核必须有对bon分区的支持,具体的传递方式则是约定为最后一个分区的最后16KB区域作为共享区域来实现的。具体比较复杂,自己读下源代码吧。





网友:
低调
时间:2008-04-26 11:34:36    IP地址:60.23.123.★
请问斑竹:
vivi的bon分区是干什么的?
为什么我无论怎么使用bon 命令“胡乱”分区,内核也能照样运行,而且yaffs文件系统也能照样运行呢?
多谢!
[color="#ff6600"]Blog作者的回复:
你的内核应该采用了MTD分区,而不是bon分区。





网友:
低调
时间:2008-05-03 09:56:39    IP地址:60.22.213.★
感谢!





网友:
低调
时间:2008-05-03 13:49:40    IP地址:60.22.213.★
vivi都向内核传递了什么?
我先把我理解的都列出来,缺的和错的,请 CalmArrow和诸位兄弟帮补充一下,谢谢。
1,传递了param_struct。
    (1)page_size。为什么要传递这个呢?是因为vivi中设置的那个页表映射吗?这个页表映射kernel也要使用吗?kernel中不也会重新设置页表吗?
    (2)nr_pages。  
     (3)commandline 。内核启动的时候,使用哪个串口打印信息是由commandline中的“console=?”决定的吗?
2,传递了machine type通过设置r1.
3,设置了r1=0.为什么呀?
4,为什么没有传递media_type?内核怎么知道文件系统是在nand中还是在其他地方?
5,内核和vivi都有哪些约定?
    (1)内核和vivi的MTD分区要一致。
    (2)zImage一定要放在mem_base+0x8000处吗?
    (3)param_struct也要放在那个固定位置吗?
哈哈,我扔一块砖头  ,等着CalmArrow和诸位兄弟的玉哦:)
               
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/66601/showart_1013993.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP