网站建站推广是啥意思dede网站本地访问速度慢
网站建站推广是啥意思,dede网站本地访问速度慢,服务器部署wordpress,深圳建设工程交易以下内容源于朱有鹏嵌入式课程的学习与整理#xff0c;如有侵权请告知删除。 一、start_armboot函数简介 uboot第一阶段#xff0c;start.S文件中进行一系列的SoC内部硬件的初始化#xff0c;然后长跳转到start_armboot 函数中。 uboot第二阶段#xff0c;start_armboot函数… 以下内容源于朱有鹏嵌入式课程的学习与整理如有侵权请告知删除。 一、start_armboot函数简介 uboot第一阶段start.S文件中进行一系列的SoC内部硬件的初始化然后长跳转到start_armboot 函数中。 uboot第二阶段start_armboot函数进一步初始化SoC外部硬件比如inand网卡芯片等以及设置uboot本身内容命令行、环境变量、基本命令等。 uboot启动后自动运行打印出很多信息uboot在第一和第二阶段不断进行初始化时打印出来的信息然后uboot进入倒数bootdelay秒。如果用户没有干涉则会执行bootcmd进入自动启动内核流程此时uboot就死掉了如果用户按下回车键打断uboot的自动启动则进入uboot的命令行然后uboot就一直工作在命令行下。此时uboot的命令行就是一个死循环循环体内不断重复接收命令、解析命令、执行命令。 start_armboot函数在uboot/lib_arm/board.c文件中。 二、Start_armboot函数的解析1 start_armboot函数开头部分代码如下。 1、init_fnc_t类型 该类型由typedef int (init_fnc_t) (void)定义是函数类型。init_fnc_ptr是一个二重函数指针用来指向一个函数指针数组。2、gd变量 1在\include\asm-arm\global_data.h中定义了变量gd它是指针类型的。 用volatile修饰表示可变的用register修饰表示这个变量要尽量放到寄存器中后面的asm(r8)是gcc支持的一种语法意思是把gd放到寄存器r8中。DECLARE_GLOBAL_DATA_PTR定义了一个要放在寄存器r8中的全局变量名字叫gd类型是一个指向gd_t类型变量的指针。gd是uboot中很重要的一个全局变量在程序中经常被访问放在register中可以提升效率。2结构体gd_t见博文uboot源码——gd_t和bd_t数据结构_天糊土的博客-CSDN博客。 3将gd和gd-bd两指针指向的内存初始化为0。 3、for循环执行init_sequence init_sequence是一个函数指针数组数组中存储了很多函数指针指针指向的函数都是init_fnc_t类型特征是接收参数是void类型返回值是int。init_sequence在定义时就同时给了初始化初始化的函数指针都是一些函数名。init_sequence中的这些函数都是board级别的各种硬件初始化。 init_fnc_ptr是一个二重函数指针可以指向init_sequence这个函数指针数组。init_fnc_t的这些函数的返回值定义方式一样的函数执行正确时返回0不正确时返回-1。在遍历时去检查函数返回值如果遍历中有一个函数返回值不等于0则hang()挂起。hang函数内部只有一行代码即while(1)。可知uboot启动过程中初始化板级硬件时不能出任何错误只要有一个错误整个启动就终止除了重启开发板没有任何办法。三、Start_armboot函数的解析2 下面开始分析init_sequence这个函数指针数组里面的函数。 1、cpu_init函数 因为cpu相关的初始化已经在start.S文件完成所以这里什么也没有做。 2、board_init函数 1board_init函数在uboot/board/samsung/x210/x210.c文件中。此函数初始化了dm9000网卡并且对gd-bd中的机器码、启动参数进行赋值。 因为有“#define MEMORY_BASE_ADDRESS 0x30000000”则x210中bi_boot_params的值为0x30000100它表示内核启动参数存放的首地址。2CONFIG_DRIVER_DM9000宏在x210_sd.h中有定义这个宏用来配置开发板的网卡。 3dm9000_pre_init函数是DM9000网卡的初始化函数。如果要移植网卡主要的工作就在这里。这个函数中主要是网卡的GPIO和端口的配置而不是驱动。 4MACH_TYPE在x210_sd.h中定义。值是2456并没有特殊含义只是代表x210这个开发板的机器码将来在此开发板上面移植的linux内核中的机器码也必须是2456否则就启动不起来。 3、interrupt_init函数 1这个函数实际是用来初始化定时器Timer4。 2S5PC11X_TIMERS定义了一个结构体类型把与时钟有关的所有寄存器都存放在这个结构体内。 3S5PC11X_GetBase_TIMERS函数的作用把timer寄存器的基地址强制类型转换为S5PC11X_TIMERS * 类型然后赋值给 timers变量。 4timers-TCFG00x0f00相当于把0x0f00这个值放到 TCFG0对应的寄存器里。寄存器必须设置为连续或者一一对应的否则会造成赋值的地址错误。 5剩下的代码就和裸机的代码一致。 TCON的timer4的相应控制位清0设置为自动reload并且第一次要手动载入然后再清0设置reload开启timer4。 4、env_init函数 1此函数是与环境变量有关的初始化。 2为什么有很多env_init函数uboot支持各种不同的启动介质比如norflash、nandflash、inand、sd卡一般从哪里启动就会把环境变量env放到哪里。不同启动介质存取env的方法是不一样的。uboot支持各种不同启动介质所以有很多个env_xx开头的c文件。实际使用哪一个c文件要根据自己开发板使用的存储介质来定。这些env_xx.c同时只有1个会起作用其他是不能进去的通过x210_sd.h中配置的宏来决定谁被包含的。x210对应的函数是env_movi.c中的函数。 3此函数把common.c中初始化好的default_environment地址赋值到gd-env_addr中env_valid 赋值为1。此函数只是对uboot自带的env做了基本的初始化或者说是判定判定里面有没有能用的环境变量。因为当前还没有进行环境变量从SD卡到DDR中的重定位因此当前的环境变量不能用。 4start_armboot调用env_relocate进行环境变量从SD卡中到DDR中的重定位。重定位之后需要环境变量时才可以从DDR中去取重定位之前如果要使用环境变量只能从SD卡中去读取。uboot自带的环境变量以代码的形式存储在default_environmen[]数组中是写死的如果要修改必须修改代码。后面随着uboot被加载到DDR中运行从而在DDR中有了一份环境变量。实际上SD卡中的环境变量才是我们需要的因此需要将SD卡中的环境变量重定位到DDR中取代DDR中uboot自带的那一份环境变量。 5、init_baudrate函数 1此函数初始化波特率即从环境变量中获取波特率赋值给gd-bd-bi_baudrate、gd-baudrate。从之前的环境变量初始化函数看出实际上环境变量中的波特率就是在x210_sd.h头文件中配置的波特率即CONFIG_BAUDRATE。 2simple_strtoul函数作用是把字符串tmp中的波特率转成十进制数字。 3getenv_r函数跟踪。 上面函数作用读取环境变量name到缓存buf中读取成功返回n大于0失败返回-1。 上面函数作用判断环境变量是从内存还是从sd卡中赋值的然后返回index对应的环境变量中的字符。 上面函数的作用从内存中读取环境变量字符作为返回值返回。 上面函数的作用是判断*s1是否和i2对应的字符串相等如果相等返回i2。6、serial_init 1由于串口在start.S中已经初始化这里不再进行初始化。 2有很多个serial_init函数x210对应的是uboot/cpu/s5pc11x/serial.c中的serial_init函数。 2可以看出这函数中实际是调用了serial_setbrg函数而这个函数什么也没有做。 7、console_init_f函数 1这是控制台的第一阶段的初始化_f表示第一阶段_r表示第二阶段。 2console_init_f函数在uboot/common/console.c中仅仅将gd-have_console设置为1而已。 8、display_banner函数 1display_banner函数的作用串口输出显示uboot的logo以及打开背光。 2display_banner中使用printf函数向串口输出version_string这个字符串。根据上面的分析console_init_f并没有初始化好console为什么可以printf呢 通过追踪printf的实现发现printf-puts而puts函数中会判断当前uboot中console有没有被初始化好。如果console初始化好了则调用fputs完成串口输出这条线才是控制台如果console尚未初始化好则会调用serial_puts然后再调用serial_putc直接操作串口寄存器进行内容发送。由此可知uboot中控制台通过串口输出非控制台也是通过串口输出。究竟什么是控制台和不用控制台的区别在于哪里分析代码会发现控制台就是一个用软件虚拟出来的设备这个设备有一套专用的通信函数发送、接收……控制台的通信函数最终会映射到硬件的通信函数中来实现。uboot中控制台的通信函数直接映射到硬件串口的通信函数中即uboot中是否使用控制台其实并没有本质差别。但是在别的体系中控制台的通信函数映射到硬件通信函数时可以用软件来做一些中间优化譬如说缓冲机制。操作系统中的控制台都使用了缓冲机制所以有时候printf了内容但是屏幕上并没有看到输出信息就是因为被缓冲了。此时输出的信息到了console的buffer中buffer还没有被刷新到硬件输出设备上。这尤其体现在输出设备是LCD屏幕时。3U_BOOT_VERSION在uboot源代码中找不到定义这个变量实际上是在makefile中定义的然后在编译时生成的include/version_autogenerated.h中用一个宏定义来实现的。 9、print_cpuinfo函数 1顾名思义此函数实现打印cpu的一些信息的功能。如下 2具体代码如下包括get_ARMCLK函数、get_PLLCLK等几个函数。 3get_ARMCLK函数作用查看时钟域24MHz经过APLL倍频以后再经过分频器以后获得的cpu的频率。 4get_PLLCLK函数作用获取PLL倍频以后的时钟频率APLL、MPLL、 EPLL。 10、checkboard函数 打印“Board x210”字符而已11、init_func_i2c函数 1由于条件编译此函数实际上没有执行。X210的uboot中并没有使用I2C。 2将来开发板如果要扩展I2C来外接硬件则在x210_sd.h中配置相应的宏即可开启。有时间可以细细看一下。 12、dram_init函数 1真正的DDR初始化函数已经在汇编阶段中执行此处只是把dram的信息赋值到全局变量gd-bd中即把chip1的首地址和大小以及chip2的首地址和大小放入全局变量中。 2可以扩展chip3只要定义相应的宏。 13、display_dram_config函数 1此函数作用是计算chip1、chip2一共多少内存并输出即启动信息中的“DRAM: 512 MB”。 2uboot中有一个命令叫bdinfo此命令可以打印出gd-bd中记录的所有与硬件相关的全局变量的值因此可以得知DDR的配置信息。 四、Start_armboot函数的解析3 1、mem_malloc_init函数 1mem_malloc_init函数用来初始化uboot的堆管理器。malloc的初始化只设置了堆的start地址和end地址、以及一个malloc_brk。 2uboot中维护了一段堆内存需要有一套代码来管理这个堆内存。在uboot中也可以malloc、free这套机制来申请内存和释放内存。我们在DDR内存中给uboot堆预留了896KB的内存。 2、mmc_initialize函数 1针对不同开发板进行对应的初始化。三星用一套uboot同时满足了好多个系列型号的开发板用#if条件编译配合CONFIG_xxx宏来选定特定的开发板然后进行独有的一些初始化。 2mmc_initialize用来初始化SoC内部的SD/MMC控制器函数位于uboot/drivers/mmc/mmc.c。 3uboot中对硬件的操作比如网卡、SD卡……都是借用的linux内核中的驱动来实现的。uboot根目录底下有个drivers文件夹这里面放的全都是从linux内核中移植过来的各种驱动源文件。 4mmc_initialize是与具体硬件架构无关的一个MMC初始化函数所有的使用了这套架构的代码都可以调用此函数来完成MMC的初始化。mmc_initialize中再调用board_mmc_init和cpu_mmc_init来完成具体的硬件的MMC控制器初始化工作。cpu_mmc_init在uboot/cpu/s5pc11x/cpu.c中其中又间接的调用了drivers/mmc/s3c_mmcxxx.c中的驱动代码来初始化硬件MMC控制器。 3、env_relocate函数 1环境变量的重定位完成从SD卡中将环境变量读取到DDR中的任务。 2环境变量到底从哪里来 SD卡中有一些8个独立的扇区作为环境变量存储区域的。但是我们烧录/部署系统时我们只是烧录了uboot分区、kernel分区和rootfs分区根本不曾烧录env分区所以当我们烧录完系统第一次启动时ENV分区是空的。本次启动uboot时尝试去SD卡的ENV分区读取环境变量时失败读取回来后进行CRC校验时失败。此时uboot选择uboot内部代码中设置的一套默认的环境变量这就是默认环境变量这套默认的环境变量在本次运行时会被读取到DDR中的环境变量中。然后被写入也可能是你saveenv时写入也可能是uboot设计了第一次读取默认环境变量后就写入SD卡的ENV分区。下次再次开机时uboot就会从SD卡的ENV分区读取环境变量到DDR中这次读取就不会失败了。3将环境变量从SD卡重定位到DDR中的代码在env_relocate_spec内部的movi_read_env函数。 4、IP地址、MAC地址的确定和devices_init函数 1开发板的IP地址是在gd-bd中维护的来源于环境变量ipaddr。 2getenv函数用来获取字符串格式的IP地址然后用string_to_ip将字符串格式的IP地址转成字符串格式的点分十进制格式。 2devices_ini是设备的初始化函数。 放在这里初始化的设备都是驱动设备这个函数本来就是从驱动框架中衍生出来的。uboot中很多设备的驱动是直接移植linux内核的譬如网卡、SD卡linux内核中的驱动都有相应的设备初始化函数。linux内核在启动过程中就有一个devices_init作用就是集中执行各种硬件驱动的init函数。uboot的这个函数其实就是从linux内核中移植过来的它的作用也是去执行所有的从linux内核中继承来的那些硬件驱动的初始化函数。5、jumptable_init函数 1jumptable跳转表本身是一个函数指针数组里面记录了很多函数的函数名。实现一个函数指针到具体函数的映射关系将来通过跳转表中的函数指针就可以执行具体的函数。这个其实就是在用C语言实现面向对象编程在linux内核中有很多这种技巧。 2通过分析发现跳转表只是被赋值从未被引用因此跳转表在uboot中根本就没使用。 6、console_init_r函数 1console_init_r是console的纯软件架构方面的初始化给console相关的数据结构中填充相应的值所以属于纯软件配置类型的初始化。 2uboot的console实际上并没有做有意义的事情它直接调用的串口通信的函数。因此用不用console实际并没有什么分别但在linux内console可以提供缓冲机制等作用有不用console不能实现的东西。 7、enable_interrupts函数 1CPSR中总中断标志位的使能。 2因为uboot中没有使用中断因此没有定义CONFIG_USE_IRQ宏因此此函数无用。 8、loadaddr、bootfile两个环境变量 这两个环境变量都是内核启动有关的在启动linux内核时会参考这两个环境变量的值。 9、board_late_init函数 1顾名思义前面该初始化的都已经初始化剩下的一些初始化都在此函数中也侧面说明开发板级别的硬件软件初始化告一段落。 2对于x210来说这个函数是空的。 10、eth_initialize函数 1此函数是网卡相关的初始化是网卡芯片本身的一些初始化而非SoC与网卡芯片连接时SoC这边的初始化。 2对于X210DM9000来说此函数为空。X210的网卡初始化在board_init函数中网卡芯片的初始化在驱动中。 11、x210_preboot_init函数LCD和logo显示 x210开发板在启动起来之前的一些初始化以及LCD屏幕上的logo显示。 12、check_menukey_to_update_from_sd函数 1uboot启动的最后阶段设计了一个自动更新的功能。 我们可以将要升级的镜像放到SD卡的固定目录中然后开机时在uboot启动的最后阶段检查升级标志是一个按键按键中标志为LEFT的那个按键此按键如果按下则表示update mode如果启动时未按下则表示boot mode。如果进入update mode则uboot会自动从SD卡中读取镜像文件然后烧录到iNand中如果进入boot mode则uboot不执行update直接启动正常运行。2这种机制能够帮助我们快速烧录系统常用于量产时用SD卡进行系统烧录部署。 13、main_loop函数 1解析器 2开机倒数自动执行 3命令补全 此函数的讲解见博客uboot源码——内核启动分析_天糊土的博客-CSDN博客。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88277.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!