第二十八篇: 学习笔记

近期一直在学一些零零碎碎的东西,


首先,将《鸟哥的 Linux 私房菜 -- 基础学习篇》过了一遍。

由于有了Windows驱动。PCI/PCIe, USB, xHCI, Windows内核编程的基础。

加上自己曾经也动手写过Linux设备驱动, 研究过Makefile, KConfig, make menuconfig, GIT的部分内容

鸟哥的这本书确实写得很通俗易懂,帮我解开了一些曾经知道怎么操作, 但不知道为什么要这样操作的疑惑。


另外,基本完毕了USB Audio/Video Class设备端的:裸金属代码与Linux驱动代码。

USB xHCI主机端的Windows WDDM驱动。与Linux的DRM/KMS 驱动还在有条不紊地行进中与优化中。

通过这个项目,

技术上:

USB Audio/Video Class

HDMI

DDR memory controller

LCD controller

VESA/CEA-861-D

I2S, I2C

SoC: Cache(D/I cache, L2 cache & Internal SRAM), CP15, MMU

Linux driver/module

等有了更进一步的深入理解

比起曾经负责的项目(avstream/bda driver, cypress fx2 firmware, usb audio class, usb video class)。 usb audio/video class项目不仅从技术上得到了加强与锻炼,同一时候也在一线技术管理。项目安排。规划方面,外部交流中得到了一定的锻炼。


另外,近期也研究了一下:

arm的vector.s, init.s, scatter loading(xxx_ld.script, 在Eclipse的项目。属性,ARM RealView Linker, Output, Scatter Description File --scatter= 设置).


arm从0地址開始执行,首先执行的是:

Reset_handler(init.s) (LDR     PC, Reset_addr),在当中做了一些硬件初始化后(比方,MMU开关。 I/D CACHE开关。 异常向量在高/低端的设置, SoC内部的SRAM是用作L2 CACHE还是SRAM的设置)

各个模式(比如SVC, IRQ, FIQ, ABT, UND, SYS/USER)的准备(主要是STACK的基地址设置)

以上设置部分须要涉及到CP15的读写。

之后。PC就跳转到__main (不是main).


然后,PC跳到__scatterload (包含 __scatterload_r, __scatterload_n(__scatterload_n就是__scatterload_null))

之后,执行__decompress (__scatterload_null 调用了__decompress)

之后,执行__scatterload_z (zero init)

之后,执行__rt_entry


{

__rt_stackheap_init

__user_setup_stackheap


__rt_stackheap_storage

__platform_post_stackheap_init

__fp_init

__rt_fp_status_addr

__ARM_argv_veneer

__heap_extend

__rt_heap_extend


__rt_heap_descriptor

__heap_guard


__heap_provide_memory

__init_alloc

srand


__rand_init

__aeabi_memclr4

__memset_w


__mutex_initialize


__sys_open


似乎并没有所有列出来

}


最后。才開始运行main (c代码中的main)


总结一下:

_main()引导库函数完毕C运行环境的初始化,详细步骤例如以下:
◇将非启动代码的RO和RW运行域代码从载入域地址拷贝到运行域地址;
◇将ZI域清零。
◇跳转到_rt_entry。


_main()并没有建立C库执行必须的环境,这项工作由_rt_entry()完毕,主要调用过程为:
◇调用_rt_stackheap_init()建立堆和栈;
◇调用_rt_lib_init()初始化引用的库函数;假如须要,建立main()函数的參数argc和argv等。(似乎我没跟踪到_rt_lib_init(), 可是看到了strlen,难道这就是在调用?
◇调用main()函数,运行应用程式,可以应用库函数。
◇用main()函数的返回值作參数调用exit()。

 


在ADS1.2的环境中,假设在C入口没有调用编译器的链接库(__main)。那么在C程序一開始要调用该函数以初始化执行时的函数库,以保证对ADS提供的某些库函数可以正常调用。从这个函数開始,我们已经在C语言环境下了。



原文地址:https://www.cnblogs.com/mengfanrong/p/5274654.html