linux3.18 内核移植记录(Exynos4412)
来源:互联网 发布:长安大学网络教育 编辑:程序博客网 时间:2024/05/17 05:55
初始化
引入Device Tree之后,MACHINE_START变更为DT_MACHINE_START,其中含有一个.dt_compat成员,用于表明相关的machine与.dts中root结点的compatible属性兼容关系。如果Bootloader传递给内核的Device Tree中root结点的compatible属性出现在某machine的.dt_compat表中,相关的machine就与对应的Device Tree匹配,从而引发这一machine的一系列初始化函数被执行。
arch/arm/mach-exynos/exynos.c:
DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)") /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ .l2c_aux_val = 0x3c400001, .l2c_aux_mask = 0xc20fffff, .smp = smp_ops(exynos_smp_ops), .map_io = exynos_init_io, .init_early = exynos_firmware_init, .init_irq = exynos_init_irq, .init_machine = exynos_dt_machine_init, .init_late = exynos_init_late, .dt_compat = exynos_dt_compat, .restart = exynos_restart, .reserve = exynos_reserve, .dt_fixup = exynos_dt_fixup,MACHINE_END
若启动时出现“Starting kernel …“后挂掉,可以打开Kernel low-level debugging functions, 并在启动参数中添加earlyprintk。
emmc驱动
内核已经自带了exynos平台的mmc驱动,位于drivers/mmc/host/dw_mmc-exynos.c中,只需在dts文件中打开相应的配置即可。
mmc@12550000 { num-slots = <1>; broken-cd; non-removable; card-detect-delay = <200>; //vmmc-supply = <&vemmc_reg>; clock-frequency = <100000000>; max-frequency = <100000000>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus8>; pinctrl-names = "default"; status = "okay"; bus-width = <8>; cap-mmc-highspeed; sd-uhs-ddr50; mmc-ddr-1_8v; //slot@0{ // reg=<0>; // bus-width=<8>; //}; };
移植过程中出现了有时能启动,有时启动不了的情况,
[ 2.946761] sdhci: Secure Digital Host Controller Interface driver[ 2.952011] sdhci: Copyright(c) Pierre Ossman[ 2.956787] s3c-sdhci 12530000.sdhci: clock source 2: mmc_busclk.2 (100000000 Hz)[ 2.964198] s3c-sdhci 12530000.sdhci: No vmmc regulator found[ 2.969557] s3c-sdhci 12530000.sdhci: No vqmmc regulator found[ 3.002313] mmc0: SDHCI controller on samsung-hsmmc [12530000.sdhci] using ADMA[ 3.008362] Synopsys Designware Multimedia Card Interface Driver[ 3.015085] dwmmc_exynos 12550000.mmc: Using internal DMA controller.[ 3.020629] dwmmc_exynos 12550000.mmc: Version ID is 240a[ 3.026287] dwmmc_exynos 12550000.mmc: DW MMC controller at irq 109, 32 bit host data width, 128 deep fifo[ 3.035673] dwmmc_exynos 12550000.mmc: No vmmc regulator found[ 3.041431] dwmmc_exynos 12550000.mmc: No vqmmc regulator found[ 3.077404] dwmmc_exynos 12550000.mmc: 1 slots initialized[ 3.082601] usbcore: registered new interface driver usbhid[ 3.086971] usbhid: USB HID core driver[ 3.091464] TCP: cubic registered[ 3.094146] NET: Registered protocol family 17[ 3.098621] NET: Registered protocol family 15[ 3.103116] Registering SWP/SWPB emulation handler[ 3.109697] isp-power-domain: Power-off latency exceeded, new value 304833 ns[ 3.115427] gps-alive-power-domain: Power-off latency exceeded, new value 5793625 ns
然后就一直卡在这里,没有任何反应,而且每次卡的位置也不是完全一样。后来打开CONFIG_MMC_DEBUG后,可以输出错误信息,发现是rootfs没有挂载上;查看init/do_mounts.c后发现可以加rootdelay参数延迟挂载。在uboot的启动参数中加入rootdelay=5后,内核启动的时候在等5秒钟之后再挂载rootfs,这样改了之后虽然启动慢了点,但每次都能顺利启动了。
LCD驱动
3.18内核中自带的framebuffer驱动位于drivers/video/fbdev/s3c-fb.c,但是它不支持device tree,后来在网上找相应的补丁加入了对device tree的支持,然后在dts文件中添加相应的node:
fimd@11c00000 { pinctrl-0 = <&lcd_clk &lcd_data24 >; pinctrl-names = "default"; status = "okay"; samsung,fimd-display = <&lcd_fimd0>; samsung,fimd-vidout-rgb; samsung,fimd-frame-rate = <60>; lcd-gpios = <&gpx2 7 0>, <&gpk3 2 0 >, <&gpk3 3 0 >; gpios=<&gpf0 0 2 >, <&gpf0 1 2 >, <&gpf0 2 2 >, <&gpf0 3 2 >, <&gpf0 4 2 >, <&gpf0 5 2 >, <&gpf0 6 2 >, <&gpf0 7 2 >, <&gpf1 0 2 >, <&gpf1 1 2 >, <&gpf1 2 2 >, <&gpf1 3 2 >, <&gpf1 4 2 >, <&gpf1 5 2 >, <&gpf1 6 2 >, <&gpf1 7 2 >, <&gpf2 0 2 >, <&gpf2 1 2 >, <&gpf2 2 2 >, <&gpf2 3 2 >, <&gpf2 4 2 >, <&gpf2 5 2 >, <&gpf2 6 2 >, <&gpf2 7 2 >, <&gpf3 0 2 >, <&gpf3 1 2 >, <&gpf3 2 2 >, <&gpf3 3 2 >; window0 { samsung,fimd-win-id = <0>; samsung,fimd-win-bpp = <32 24>; samsung,fimd-win-res = <1024 600>; samsung,fimd-win-vres = <1024 600>; }; window1 { samsung,fimd-win-id = <1>; samsung,fimd-win-bpp = <32 24>; samsung,fimd-win-res = <1024 600>; samsung,fimd-win-vres = <1024 600>; }; }; lcd_fimd0: lcd_fimd0{ lcd-htiming = <120 120 80 1024>; lcd-vtiming = <22 10 3 600>; };
对于其中的gpio资源,在驱动中可以通过调用以下两个函数获取:
of_get_gpio(dev->of_node, idx);of_get_named_gpio(dev->of_node,"lcd-gpios",idx);
这样启动后出现了”failed to get bus clock”的错误,通过修改exynos4.dtsi中的clock-names解决了,对于clk这一块还没完全搞清楚,
--- a/arch/arm/boot/dts/exynos4.dtsi+++ b/arch/arm/boot/dts/exynos4.dtsi@@ -640,7 +640,7 @@ interrupt-names = "fifo", "vsync", "lcd_sys"; interrupts = <11 0>, <11 1>, <11 2>; clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;- clock-names = "sclk_fimd", "fimd";+ clock-names = "sclk_fimd", "lcd"; samsung,power-domain = <&pd_lcd0>; samsung,sysreg = <&sys_reg>; status = "disabled";
改完后重新编译发现屏幕终于亮起来了,但是会闪烁,像是扫描过慢的感觉,然后又加了如下代码修改clock频率:
@@ -1413,6 +1644,22 @@ static int s3c_fb_probe(struct platform_device *pdev) ret = PTR_ERR(sfb->lcd_clk); goto err_bus_clk; }+ printk("lcd_clk: %d\n",clk_get_rate(sfb->lcd_clk));+ ret=clk_set_rate(sfb->lcd_clk, 50000000);+ if (ret < 0) {+ dev_err(dev, "failed to clk_set_rate of sclk for fimd\n");+ }
i2c驱动
电容触摸屏用到了i2c,把触摸屏驱动改成device tree支持后,再在dts文件中加入i2c的node,
i2c@13860000 { status = "okay"; samsung,i2c-max-bus-freq = <400000>; samsung,i2c-sda-delay = <100>; gsl680@40{ compatible = "gsl680-i2c"; reg=<0x40>; gsl680-gpios = <&gpx1 5 1>, <&gpx1 6 0xf>; };};
其中gsl680驱动的地址为0x40,用到了两个gpio口,其中一个用于中断,在驱动中通过of_get_named_gpio和gpio_to_irq得到对应的irq号,
static int gsl_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct gsl_ts *ts; int rc; struct device_node* np=client->dev.of_node; gpio_ts_wake= of_get_named_gpio(np,"gsl680-gpios", 0); irq_gpio= of_get_named_gpio(np,"gsl680-gpios", 1); irq_port= gpio_to_irq(irq_gpio);
”samsung,i2c-max-bus-freq“指定i2c频率为400K,刚开始没有加“samsung,i2c-sda-delay”,导致了i2c数据读写出错,搞了很久之后才解决这个问题。
- linux3.18 内核移植记录(Exynos4412)
- linux3.0内核移植问题记录
- 在mini210下移植linux3.7.4内核记录
- ok6410最新版linux3内核移植
- Linux3.2.81内核移植(2440)
- Linux内核移植 part3:Exynos4412内核编译
- linux3.18内核移植到GT2440成功---完善串口
- 华为3GE261在Android4.0、linux3.0.8内核上的移植记录1
- 华为3GE261在Android4.0、linux3.0.8内核上的移植记录2
- linux3.6.5内核移植到S3C6410
- 移植linux3.3内核到ST2410
- 【FL2400】Linux3.0 内核移植 一
- linux3.0内核移植(S3C2440)
- 基于arm9的linux3.0内核移植
- Linux3.5.2内核移植与文件系统制作
- 移植Linux3.4.2版本内核到mini2440
- mini2440移植linux3.14.72内核笔记(1)
- 开发板X210V3S移植linux3.2内核
- myeclipse中没有new jsp了
- 李鹏、李铁映、李讷等人与一部剧的渊源
- 数据库连接池的原理
- 单机伪分布下的hadoop+spark 环境配置
- Dagger2初步使用及介绍
- linux3.18 内核移植记录(Exynos4412)
- Sublime Text 3 快捷键汇总
- UNIX网络编程
- C++11新标准总结
- [JZOJ5023]Sequence
- 织梦修改默认模板
- 程序测试技巧总结
- 51Nod 1542 羊圈偷袭
- 关于发邮件报错535 Error:authentication failed解决方法