结构化分析第二阶段竞品分析的目的是什么么

这是个机器人猖狂的时代,请输一下验证码,证明咱是正常人~君,已阅读到文档的结尾了呢~~
广告剩余8秒
文档加载中
高层框剪结构剪力墙抗震设计及..
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
高层框剪结构剪力墙抗震设计及实例分析(可编辑)
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口下次自动登录
现在的位置:
& 综合 & 正文
u-boot-1.1.6 源码分析(3)–第二阶段
上接第一阶段跳转语句
_start_armboot
第二阶段流程图
1。第二阶段的主线函数位于u-boot-2010.06/arch/arm/lib/board.c。
第二阶段的功能:
&1& 初始化本阶段要使用到的硬件设备。
设置时钟、初始化串口。
board_init函数设置MPLL、改变系统时钟,它是开发板相关的函数,在board/samsung/smdk2440/smdk2440.c中实现。值得注意的是board_init函数还保存了机器类型ID,这将在调用内核的时候传递给内核。如下:
gd-&bd-&bi_arch_number = MACH_TYPE_S3C2440;
串口的初始化函数主要是serial_init,它设置UART控制器,是CPU相关的函数。
&2&检测系统内存映射(memory map)。
对于smdk2440的开发板,其内存分布是明确的,一般内存起始地址为0x,大小为64M = 0x。代码如下:
int dram_init(void)
gd-&bd-&bi_dram[0] . start = PHYS_SDRAM_1;
gd-&bd-&bi_dram[0].size = PHYS_SDRAM_1_SIZE;
//这两个值都定义在include/configs/smdk2440.h中
&3&将内核映像和根文件系统映像从Flash上读到RAM空间中。
&4&为内核设置启动参数。
U-Boot 是通过标记列表向内核传递参数。
setup_memory_tags
setup_commandline_tag
这两个标记列表定义在arch/arm/lib/bootm.c中,需要在定义命令的文件include/configs/smdk2440.h中定义两个命令
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_CMDLINE_TAG
对于ARM构架的CPU来说,都是通过arch/arm/lib/bootm.c中的do_bootm_linux函数来启动内核的。这个函数中,设置标记列表,最后通过 theKernel = (void (星)(int, int, uint))images-&调用内核。其中,theKernel 指向内核存放的地址(对于ARM构架的CPU,通常这个地址是0x)。传递的3个参数如下:void (星theKernel)(int zero, int arch, uint params);
R1: 机器类型ID -- gd-&bd-&bi_arch_number = MACH_TYPE_S3C2440;
R2: 启动参数标记列表在RAM中的起始地址 0x
2。源码解析。
arch/arm/lib/board.c
void start_armboot (void){ init_fnc_t **init_fnc_
//定义二级函数指针 char *s; gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));/************************************************************************************************************
定义了全局数据指针,armboot_start的值位于0x3ff80000,且CONFIG_SYS_MALLOC_LEN在
include/configs/smdk2440.h中定义,
#define config_sys_malloc_len
(CONFIG_ENV_SIZE + 128 * 1024)
#define CONFIG_ENV_SIZE
//128K为256M的Nandflash的块大小,block。
通过以上计算得出 config_sys_malloc_len 的大小为 256k = 0x4 0000。
再来看一下结构体gd_t,位于arch/arm/include/asm/global_data.h
typedef struct global_data { bd_t
* unsigned long unsigned long unsigned long have_ /* serial_init() was called */ unsigned long env_ /* Address
of Environment struct */ unsigned long env_ /* Checksum of Environment valid? */ unsigned long fb_ /* base address of frame buffer */#ifdef CONFIG_VFD
unsigned char vfd_ /* display type */#endif#ifdef CONFIG_FSL_ESDHC
unsigned long sdhc_#endif#if 0
unsigned long cpu_ /* CPU clock in Hz!
unsigned long bus_
phys_size_t ram_ /* RAM size */
unsigned long reset_ /* reset status register at boot */#endif void
/* jump table */} gd_t;
sizeof(gd_t)=4 + 4 * 6 + 4 = 32 = 0x20。
故gd所指向地址 0x3ff80000 - 0x40000 -
0x20为 0x3FF3 FFE0
/* * Global Data Flags */#define GD_FLG_RELOC 0x00001
/* Code was relocated to RAM
*/#define GD_FLG_DEVINIT 0x00002
/* Devices have been initialized */#define GD_FLG_SILENT 0x00004
/* Silent mode
*/#define GD_FLG_POSTFAIL 0x00008
/* Critical POST test failed
*/#define GD_FLG_POSTSTOP 0x00010
/* POST seqeunce aborted
*/#define GD_FLG_LOGINIT 0x00020
/* Log Buffer has been initialized */#define GD_FLG_DISABLE_CONSOLE 0x00040
/* Disable console (in & out)
#define DECLARE_GLOBAL_DATA_PTR
register volatile gd_t *gd asm ("r8")
/***************************************************************************************
这个声明告诉编译器使用寄存器r8来存储gd_t类型的指针gd,即这个定义声明了一个指针,并且指明了它的存储位置。register表示变量放在机器的寄存器volatile用于指定变量的值可以由外部过程异步修改
这个指针在board.c中初始化。
****************************************************************************************/ __asm__ __volatile__("": : :"memory"); //分配一个存储全局数据的区域,地址给指针 gd
/****************************************************************************************************************
如同使用变量之前,需要声明定义一样,这里使用全局变量gd和bd之前,我们需要先设置它的地址,并用memset函数为它分配合适的空间。u-boot的注释告知我们,gd和bd是一个可写的指针,实际上不过是一个地址而已。代码中的这句话:__asm__ __volatile__("": : :"memory");目的就是告诉编译器内存被修改过了。更详细的关于C中内嵌汇编的文档,请参考《ARM GCC 内嵌(inline)汇编手册》。
***************************************************************************************************************/
memset ((void*)gd, 0, sizeof (gd_t));
//分配空间并清0gd-&bd = (bd_t*)((char*)gd - sizeof(bd_t));
/****************************************************************************************************************
bd_t结构体位于arch/arm/include/asm/u-boot.h中
#ifndef _U_BOOT_H_#define _U_BOOT_H_ 1
typedef struct bd_info {
bi_ /* serial console baudrate */
unsigned long bi_ip_ /* IP Address */
struct environment_s
bi_arch_ /* unique id for this board */
bi_boot_ /* where this board expects params */
/* RAM configuration */
bi_dram[CONFIG_NR_DRAM_BANKS];} bd_t;
#define bi_env_data bi_env-&data#define bi_env_crc
bi_env-&crc
#endif /* _U_BOOT_H_ */
****************************************************************************************************************/memset (gd-&bd, 0, sizeof (bd_t));
//分配空间并清0
gd-&flags |= GD_FLG_RELOC;
//设置当前uboot标志位已经重定位
monitor_flash_len = _bss_start - _armboot_
//uboot镜像文件大小
//初始化函数循环
for (init_fnc_ptr = init_ *init_fnc_ ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0)
/***************************************************************************************************************init_sequence 是一个初始化函数集的函数指针数组。
如果有任何一个函数失败就进入si循环。结构体如下:
init_fnc_t *init_sequence[] = {#if defined(CONFIG_ARCH_CPU_INIT)
arch_cpu_init,
/* basic arch cpu dependent setup */#endif
board_init,
/* basic board dependent setup */#if defined(CONFIG_USE_IRQ)
interrupt_init,
/* set up exceptions */#endif
timer_init,
/* initialize timer */#ifdef CONFIG_FSL_ESDHC
get_clocks,#endif
/* initialize environment */
init_baudrate,
/* initialze baudrate settings */
serial_init,
/* serial communications setup */
console_init_f,
/* stage 1 init of console */
display_banner,
/* say that we are here */#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo,
/* display cpu info (and speed) */#endif#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard,
/* display board info */#endif#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
init_func_i2c,#endif
dram_init,
/* configure available RAM banks */#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
arm_pci_init,#endif
display_dram_config, NULL,};
***************************************************************************************************************/
/****************************************************************************************************************
mem_malloc_init函数,这是非常关键的一步,请大家引起注意。我们必须配置好内存的起始地址和结束地址,然后把这块区域清零,以便后续来使用它。
void mem_malloc_init(ulong start, ulong size){
mem_malloc_start =
mem_malloc_end = start +
mem_malloc_brk =
memset((void *)mem_malloc_start, 0, size);}
****************************************************************************************************************/
/* armboot_start is defined in the board-specific linker script */mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,
CONFIG_SYS_MALLOC_LEN);
/****************************************************************************************************************
Norflash初始化,返回的是size是大小。定义在board/samsung/smdk2440/flash.c中
****************************************************************************************************************/
#ifndef CONFIG_SYS_NO_FLASH /* configure available FLASH banks */
display_flash_config (flash_init ());#endif /* CONFIG_SYS_NO_FLASH */
/****************************************************************************************************************
Nandflash初始化,定义在drivers/mtd/nand/nand.c中
****************************************************************************************************************/
#if defined(CONFIG_CMD_NAND)
puts ("NAND:
nand_init();
/* go init the NAND */#endif
#if defined(CONFIG_CMD_ONENAND)
onenand_init();#endif
/****************************************************************************************************************
初始化环境变量,如果认为没有找到存储其中的,就用默认值并打印:“*** Warning - bad CRC, using default environment”。这是我们常看到的。在终端输入saveenv 即可。****************************************************************************************************************/
/* initialize environment */
env_relocate ();
//多串口配置,跳过。
#ifdef CONFIG_SERIAL_MULTI
serial_initialize();#endif
//IP地址获取。
/* IP Address */
gd-&bd-&bi_ip_addr = getenv_IPaddr ("ipaddr");
//标准的输入输出
stdio_init (); /* get the devices list going. */
//初始化外设列表
jumptable_init ();
//u-boot的应用函数集,跳过
#if defined(CONFIG_API) /* Initialize API */
api_init ();#endif
//初始化控制台(console),平台无关,不一定是串口哦,如果把标准输出设为vga,字符会显示在LCD上。
console_init_r (); /* fully init console as a device */
//平台相关的其他设备初始化,这些s3c2440都没有。跳过
#if defined(CONFIG_ARCH_MISC_INIT) /* miscellaneous arch dependent initialisations */
arch_misc_init ();#endif
#if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */
misc_init_r ();#endif
//允许中断,这里还没移植USB下载,所以直接return。
/* enable exceptions */
enable_interrupts ();
//TI平台的网卡驱动,直接跳过
/* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_TI_EMAC /* XXX: this needs to be moved to board init */extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
if (getenv ("ethaddr"))
uchar enetaddr[6];
eth_getenv_enetaddr("ethaddr", enetaddr);
davinci_eth_set_mac_addr(enetaddr);
//其他网卡的设置,直接跳过。
#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96) /* XXX: this needs to be moved to board init */
if (getenv ("ethaddr"))
uchar enetaddr[6];
eth_getenv_enetaddr("ethaddr", enetaddr);
smc_set_mac_addr(enetaddr); }#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */
/* Initialize from environment */ if ((s = getenv ("loadaddr")) != NULL)
load_addr = simple_strtoul (s, NULL, 16);}
//获取bootfile参数
#if defined(CONFIG_CMD_NET)if ((s = getenv ("bootfile")) != NULL)
copy_filename (BootFile, s, sizeof (BootFile));}#endif
#ifdef BOARD_LATE_INIT
board_late_init ();#endif
//MMC卡的控制器初始化
#ifdef CONFIG_GENERIC_MMC
puts ("MMC:
mmc_initialize (gd-&bd);#endif
#ifdef CONFIG_BITBANGMII
bb_miiphy_init();#endif
#if defined(CONFIG_CMD_NET)//多网卡配置
#if defined(CONFIG_NET_MULTI)
puts ("Net:
//网卡初始化
eth_initialize(gd-&bd);
//允许网卡复位#if defined(CONFIG_RESET_PHY_R)
debug ("Reset Ethernet PHY/n");
reset_phy();#endif#endif
//进入主循环。其中会读取bootdelay和bootcmd。在bootdelay时间内按下键进入命令行,否则执行bootcmd的命令。
/* main_loop() can return to retry autoboot, if so just run it again. */ for (;;)
main_loop ();}
/* NOTREACHED - no way out of command loop except booting */}
//出错提示
void hang (void){
puts ("### ERROR ### Please RESET the board ###/n");
for (;;);}
3。初始化列表具体分析。
void jumptable_init(void){
//为是这个函数指针数组分配空间。
gd-&jt = malloc(XF_MAX * sizeof(void *));
#include &_exports.h&}
init_fnc_t *init_sequence[] = {#if defined(CONFIG_ARCH_CPU_INIT)
arch_cpu_init,
/* basic arch cpu dependent setup */#endif
board_init,
/* basic board dependent setup */
/****************************************************************************************************************
int board_init (void){ struct s3c24x0_clock_power * const clk_power =
s3c24x0_get_base_clock_power(); struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
/* to reduce PLL lock time, adjust the LOCKTIME register */ clk_power-&LOCKTIME = 0xFFFFFF;
/* configure MPLL */ clk_power-&MPLLCON = ((M_MDIV && 12) + (M_PDIV && 4) + M_SDIV);
/* some delay between MPLL and UPLL */ delay (4000);
/* configure UPLL */ clk_power-&UPLLCON = ((U_M_MDIV && 12) + (U_M_PDIV && 4) + U_M_SDIV);
/* some delay between MPLL and UPLL */ delay (8000);
/* set up the I/O ports */ gpio-&GPACON = 0x007FFFFF; gpio-&GPBCON = 0x; gpio-&GPBUP = 0x000007FF; gpio-&GPCCON = 0xAAAAAAAA; gpio-&GPCUP = 0x0000FFFF; gpio-&GPDCON = 0xAAAAAAAA; gpio-&GPDUP = 0x0000FFFF; gpio-&GPECON = 0xAAAAAAAA; gpio-&GPEUP = 0x0000FFFF; gpio-&GPFCON = 0x000055AA; gpio-&GPFUP = 0x000000FF; gpio-&GPGCON = 0xFF95FFBA; gpio-&GPGUP = 0x0000FFFF; gpio-&GPHCON = 0x002AFAAA; gpio-&GPHUP = 0x000007FF;
/* arch number of SMDK2410-Board */
gd-&bd-&bi_arch_number = MACH_TYPE_S3C2440;
/* adress of boot parameters */
gd-&bd-&bi_boot_params = 0x;
icache_enable(); //关闭指令cache dcache_enable(); //关闭数据cache
return 0;}***************************************************************************************************************/ #if defined(CONFIG_USE_IRQ)
interrupt_init,
/* set up exceptions */#endif
timer_init,
/* initialize timer */
//定时器初始化
/****************************************************************************************************************
int timer_init(void){ struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
/* use PWM Timer 4 because it has no output */ /* prescaler for Timer 4 is 16 */ writel(0x0f00, &timers-&TCFG0); if (timer_load_val == 0) {
* for 10 ms clock period @ PCLK with 4 bit divider = 1/2
* (default) and prescaler = 16. Should be 10390
* @33.25MHz and 15625 @ 50 MHz
timer_load_val = get_PCLK() / (2 * 16 * 100);
timer_clk = get_PCLK() / (2 * 16); } /* load value for 10 ms timeout */ lastdec = timer_load_ writel(timer_load_val, &timers-&TCNTB4); /* auto load, manual update of Timer 4 */ tmr = (readl(&timers-&TCON) & ~0x0700000) | 0x0600000; writel(tmr, &timers-&TCON); /* auto load, start Timer 4 */ tmr = (tmr & ~0x0700000) | 0x0500000; writel(tmr, &timers-&TCON); timestamp = 0;
return (0);}
****************************************************************************************************************/#ifdef CONFIG_FSL_ESDHC
get_clocks,#endif
/* initialize environment */
//环境变量
/***************************************************************************************************************
int env_init(void){ /* use default */ gd-&env_addr = (ulong) & default_environment[0]; gd-&env_valid = 1;
return 0;}****************************************************************************************************************/
init_baudrate,
/* initialze baudrate settings */
//波特率获取
/****************************************************************************************************************
static int init_baudrate (void){
char tmp[64]; /* long enough for environment variables */
int i = getenv_r ("baudrate", tmp, sizeof (tmp));
gd-&bd-&bi_baudrate = gd-&baudrate = (i & 0)
? (int) simple_strtoul (tmp, NULL, 10)
: CONFIG_BAUDRATE;
return (0);}
***************************************************************************************************************/
serial_init,
/* serial communications setup */
//串口设置
/****************************************************************************************************************
#if !defined(CONFIG_SERIAL_MULTI)/* Initialise the serial port. The settings are always 8 data bits, no parity, * 1 stop bit, no start bits. */int serial_init(void){
return serial_init_dev(UART_NR);
//UART_NR 就是串口号,在文件drivers/serial/serial_s3c24x0.c中有如下定义:
#ifdef CONFIG_SERIAL1#define UART_NR S3C24X0_UART0
#elif defined(CONFIG_SERIAL2)# if defined(CONFIG_TRAB)#
error "TRAB supports only CONFIG_SERIAL1"# endif#define UART_NR S3C24X0_UART1
#elif defined(CONFIG_SERIAL3)# if defined(CONFIG_TRAB)#
error "TRAB supports only CONFIG_SERIAL1"# endif#define UART_NR S3C24X0_UART2
#else#error "Bad: you didn't configure serial ..."#endif
默认的输出为串口0 即定义在include/configs/smdk2440.h中
#define CONFIG_S3C24X0_SERIAL#define CONFIG_SERIAL1
1 /* we use SERIAL 1 on SMDK2410 */}#endif
static int serial_init_dev(const int dev_index){ struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
#ifdef CONFIG_HWFLOW hwflow = 0; /* turned off by default */#endif
/* FIFO enable, Tx/Rx FIFO clear */ writel(0x07, &uart-&UFCON); writel(0x0, &uart-&UMCON);
/* Normal,No parity,1 stop,8 bit */ writel(0x3, &uart-&ULCON); /*
* tx=level,rx=edge,disable timeout int.,enable rx error int.,
* normal,interrupt or polling
*/ writel(0x245, &uart-&UCON);
#ifdef CONFIG_HWFLOW writel(0x1, &uart-&UMCON); /* RTS up */#endif
/* FIXME: This is sooooooooooooooooooo ugly */#if defined(CONFIG_ARCH_GTA02_v1) || defined(CONFIG_ARCH_GTA02_v2) /* we need auto hw flow control on the gsm and gps port */ if (dev_index == 0 || dev_index == 1)
writel(0x10, &uart-&UMCON);#endif _serial_setbrg(dev_index);
return (0);}
****************************************************************************************************************/
console_init_f,
/* stage 1 init of console */
/****************************************************************************************************************
/* Called before relocation - use serial functions */int console_init_f(void){
gd-&have_console = 1;
#ifdef CONFIG_SILENT_CONSOLE
if (getenv("silent") != NULL)
gd-&flags |= GD_FLG_SILENT;#endif
return 0;}
****************************************************************************************************************/
display_banner,
/* say that we are here */
/****************************************************************************************************************
测试串口,显示一些信息。
****************************************************************************************************************/#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo,
/* display cpu info (and speed) */#endif#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard,
/* display board info */#endif#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
init_func_i2c,#endif
dram_init,
/* configure available RAM banks */
//内存初始化
/****************************************************************************************************************
int dram_init (void){
gd-&bd-&bi_dram[0].start = PHYS_SDRAM_1;
gd-&bd-&bi_dram[0].size = PHYS_SDRAM_1_SIZE;
return 0;}
****************************************************************************************************************/#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
arm_pci_init,#endif
display_dram_config,
//显示内存信息
/****************************************************************************************************************
static int display_dram_config (void){
#ifdef DEBUG puts ("RAM Configuration:/n");
for(i=0; i&CONFIG_NR_DRAM_BANKS; i++) {
printf ("Bank #%d: %08lx ", i, gd-&bd-&bi_dram[i].start);
print_size (gd-&bd-&bi_dram[i].size, "/n"); }#else ulong size = 0;
for (i=0; i&CONFIG_NR_DRAM_BANKS; i++) {
size += gd-&bd-&bi_dram[i]. } puts("DRAM:
"); print_size(size, "/n");#endif
return (0);}
****************************************************************************************************************/ NULL,};
&&&&推荐文章:
【上篇】【下篇】}

我要回帖

更多关于 竞品分析的目的是什么 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信