Presentation is loading. Please wait.

Presentation is loading. Please wait.

内核移植基础.

Similar presentations


Presentation on theme: "内核移植基础."— Presentation transcript:

1 内核移植基础

2 内核移植基础 移植的基本工作 Linux设备树 Linux内核启动流程

3 移植的基本工作

4 移植的基本工作 板级移植通常要做以下基本工作: 移植后的工作 选择参考板 参考板Linux设备驱动工作正常,至少已经驱动基本接口。
对内核进行裁剪和添加功能 移植后的工作 $ cd linux fs4412/ $ cp .config arch/arm/configs/fs4412_defconfig $ make ARCH=arm distclean $ cd ../ $ diff -urN linux / linux fs4412/ > patch-linux fs4412 $ xz patch-linux fs4412

5 Linux设备树 Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。 Device Tree由一系列被命名的结点(node)和属性(property)组成,而 结点本身可包含子结点。所谓属性,其实就是成对出现的name和value。在 Device Tree中,可描述的信息包括(原先这些信息大多被hard code到 kernel中 CPU的数量和类别 内存基地址和大小 总线和桥 外设连接 中断控制器和中断使用情况 GPIO控制器和GPIO使用情况 Clock控制器和Clock使用情况

6 Linux设备树 DTS(device tree source)
.dts文件是一种ASCII 文本格式的Device Tree描述,此文本格式非常人性化, 适合人类的阅读习惯。基本上,在ARM Linux在,一个.dts文件对应一个ARM 的machine,一般放置在内核的arch/arm/boot/dts/目录。 如:arch/arm/boot/dts/exynos4412-origen.dts 由于一个SoC可能对应多个machine(一个SoC可以对应多个产品和电路板), 势必这些.dts文件需包含许多共同的部分,Linux内核为了简化,把SoC公用 的部分或者多个machine共同的部分一般提炼为.dtsi,类似于C语言的头文件。 如:arch/arm/boot/dts/skeleton.dtsi

7 Linux设备树 设备树语法: .dts和.dtsi文件的基本元素为结点和属性
有一个root结点”\”,,root结点下又可以有一系列子节点如: / { node1 { child-node1{ }; child-node2{ node2 {

8 Linux设备树 根节点属性 model :表示具体某一个machine
/ { model = "Insignal Origen evaluation board based on Exynos4412"; compatible = "insignal,origen4412", "samsung,exynos4412"; #address-cells = <1> #size-cells = <1> }; model :表示具体某一个machine compatible:表示支持的一系列machine,第一个是主要支持machine,后边是 兼容的machine,用来表示每个设备的子节点也有这个属性,用来将驱动和设 备绑定。

9 Linux设备树 子节点属性 compatible:同上用来绑定一个驱动和设备 reg:可寻址设备用来表示编码地址信息,是一个列表
{ compatible = "samsung,secure-firmware"; reg = <0x0203F000 0x1000>; }; compatible:同上用来绑定一个驱动和设备 reg:可寻址设备用来表示编码地址信息,是一个列表 格式:reg = <addr1 len1 [addr2 len2] [addr3 len3]> addr表示地址起始,len表示范围,这两个字段长度可变如父节点 #address-cells=<1>和 #size-cells=<1>,0x0203F0000为地址起始,0x1000 为范围,如个父节点#address-cells=<2>和 #size-cells=<0>, 0x0203F0000,0x1000都是地址,如果不希望继承父节点则可以在本结点中添加 #address-cells和 #size-cells的定义

10 Linux设备树 子节点属性 其他属性: 参考Documentation/devicetree/bindings
interrupt-parent interrupts clocks clock-name 还可以根据设备需求自定义属性 设备树与machine_desc的关系 在内核启动过程中设备树中的信息被转换为machine_desc

11 Linux内核启动流程

12 Linux内核启动流程 Bootloader -硬件上电后跳到一个固定位置执行相应的代码
第一个用户空间程序 -配置用户环境和执行服务进程 Kernel -内核自解压(zImage) -初始化静态编译进内核的驱动模块 (needed to access the root filesystem)‏ -挂载根文件系统 (needed to access and run userspace programs)‏ -直接执行第一个用户空间程序 Bootloader -硬件上电后跳到一个固定位置执行相应的代码 -初始化相应的设备 (local storage, network, removable media)‏ -加载内核的代码到内存 -跳到内核代码起始位置执行

13 Linux内核启动流程 arch/arm/boot/compressed/head.S start: ……
bl decompress_kernel # 解压内核 b __enter_kernel # 进入解压后的内核 arch/arm/boot/compressed/misc.c void decompress_kernel(……) { putstr(“Uncompressing Linux...”); # 打印解压信息 putstr(" done, booting the kernel.\n"); }

14 Linux内核启动流程 arch/arm/kernel/head.S ENTRY(stext) ……
bl __lookup_processor_type # 处理器是否支持 movs r10, r5 beq __error_p # 不支持则打印错误消息 bl __create_page_tables # 创建页表 ldr r13, =__mmap_switched # 在MMU使能后调用 b __enable_mmu # 使能MMU arch/arm/kernel/head-common.S __mmap_switched: b start_kernel # 进入内核的公共入口

15 Linux内核启动流程 init/main.c asmlinkage void __init start_kernel(void) { ……
setup_arch(&command_line); /* arch/arm/kernel/setup.c */ mdesc = setup_machine_fdt(__atags_pointer); /* 搜索 匹配的机器 */ console_init(); /* 控制台初始化 */ rest_init(); /* 余下的初始化 */ }

16 Linux内核启动流程 init/main.c rest_init(void) {
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); schedule_preempt_disabled(); /* 抢占禁止的情况下调用cpu_idle */ cpu_startup_entry(CPUHP_ONLINE); }

17 Linux内核启动流程 init/main.c kernel_init(void *unused) {
kernel_init_freeable(); do_basic_setup(); /* 驱动初始化 */ driver_init(); /* drivers/base/init.c */ do_initcalls(); /* 挂载根文件系统 */ populate_rootfs; /* init/initramfs.c, initramfs或initrd的处理 */ prepare_namespace(); /* 如果没有initramfs或initrd,则从其他设备上挂载根文件系统 */

18 Linux内核启动流程 if (execute_command) {
ret = run_init_process(execute_command); if (!ret) return 0; pr_err(“Failed to execute %s (error %d). Attempting defaults...\n”, …); } /* 否则尝试执行下面的init程序 */ if (!try_to_run_init_process("/sbin/init") || !try_to_run_init_process("/etc/init") || !try_to_run_init_process("/bin/init") || !try_to_run_init_process("/bin/sh")) return 0; /* 所有的尝试都失败,打印错误信息 */ panic("No working init found. Try passing init= option to kernel. " "See Linux Documentation/init.txt for guidance.");


Download ppt "内核移植基础."

Similar presentations


Ads by Google