历史上的今天
返回首页

历史上的今天

今天是:2025年11月17日(星期一)

正在发生

2022年11月17日 | S3C2440移植linux3.4.2内核之内核框架介绍及简单修改

2022-11-17 来源:zhihu

uboot启动内核分析

进入cmd_bootm.c,找到对应的bootm命令对应的do_bootm():


int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])

{

boot_os_fn *boot_fn;             //boot_fn是个数组函数

 ... ..


boot_fn(0, argc, argv, &images); //调用数组函数

 ... ...

}

boot_os_fn是个typedef型,如下图所示:

由于定义了宏CONFIG_BOOTM_LINUX,最终会跳转到do_bootm ->do_bootm_linux() 代码如下所示:

int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)

{

         /* No need for those on ARM */

         if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)

                   return -1;

         if (flag & BOOTM_STATE_OS_PREP) {

                   boot_prep_linux(images);

                   return 0;

         }

         if (flag & BOOTM_STATE_OS_GO) {

                   boot_jump_linux(images);

                   return 0;

         }



         boot_prep_linux(images);      //该函数会将各个tag参数保存在指定位置,比如:内存tag、bootargs环境变量tag、串口tag等

         boot_jump_linux(images);      //该函数会跳转到内核起始地址

         return 0;

}

最终跳转到do_bootm ->do_bootm_linux-> boot_jump_linux()


static void boot_jump_linux(bootm_headers_t *images)

{

         unsigned long machid = gd->bd->bi_arch_number;     //获取机器ID

         char *s;

         void (*kernel_entry)(int zero, int arch, uint params);

         unsigned long r2;

         kernel_entry = (void (*)(int, int, uint))images->ep;  //设置kernel_entry()的地址为0x30000000

         s = getenv("machid");                     //判断环境变量machid是否设置,若设置则使用环境变量里的值   

         if (s) {       

                   strict_strtoul(s, 16, &machid);      //重新获取机器ID

                   printf("Using machid 0x%lx from environmentn", machid);  //使用环境变量的machid

         }

     ... ...

        r2 = gd->bd->bi_boot_params;     //获取tag参数地址, gd->bd->bi_boot_params在setup_start_tag()函数里被设置 

        kernel_entry(0, machid, r2);     //跳转到0x30000000,r0=0,r1=机器ID,r2=tag参数地址

}

上面的machid默认值为MACH_TYPE_SMDK2410(也就是193),我们也可以在环境变量里设置machid变量 最终,便跳到内核执行代码,步骤如下所示: 1)根据R1(机器ID),来判断内核是否支持该机器,若支持则初始化机器相关函数 2)解析TAG参数,初始化串口,设置内存等 3)挂载根文件系统,并执行应用程序


简单配置内核

修改Makefile,修改配置


tar xjf linux-3.4.2.tar.bz2 

cd linux-3.4.2/

vi Makefile 

改为

ARCH            ?= arm

CROSS_COMPILE   ?= arm-linux-

配置编译


cd arch/arm/configs                //由于我们板子是arm板,进入该目录

ls  *2440*                            //找到有mini2440_defconfig、

ls  *2410*                            //找到有s3c2410_defconfig


cd ../../..

make s3c2410_defconfig                //配置2410, 更新.config配置文件 

make uImage                          //编译,生成uImage

cp arch/arm/boot/uImage /work/nfs_root/           //拷贝

cd /work/nfs_root/ 

mv uImage uImage_new

进入.config查看支持的CPU

vi .config

如上图所示,有我们的2440

编译内核

make uImage

报错如下


Can't use 'defined(@array)'(Maybe you should just omit the defined? )at kernel/timeconst pl line 373

/root/working/Hi3520D SDK V2.0.3.0/osdrv/kernel/linux-30y/kernel/Makefile:140

recipe for target kernel/timeconst h failed make【1】:*** 【kernel/timeconst h】 Error 255

Makefile:945:recipe for target kernel ' failed

【kernel】 Error 2

解决办法: 将 kernel/timeconst.pl中第373行的 defined0去掉只留下@val就可以了


vim kernel/timeconst.pl +373

进入uboot烧写


nfs 32000000 192.168.2.106:/work/nfs_root/uImage_new

bootm 32000000  

如下图所示,发现串口输出乱码:

设置机器ID

uboot传递进来的机器ID可以通过环境变量machid来设置 所以任意设置一个ID,这样再次启动内核时,内核识别不出来,就会打印出所有设备对应的机器ID。下面开始测试机器ID是否正确,进入uboot,输入:


set machid 33333

tftp 32000000 uImage

bootm 32000000

如下图所示,由于内核不支持这个机器ID,所以打印出内核能支持的ID表:

ID所对应的文件为arch/arm/mach-s3c24xx/Mach-smdk2440.c


MACHINE_START为一个结构体,根据不同的机器ID找到对应的MACHINE_START,调用初始化函数。 由于我们板子是2440,所以测试7cf(mini2440)以及16a(smdk2440)这两个机器ID,是否支持我们开发板。 但是依旧乱码,可能是波特率设置不正确。重新设置下环境变量的波特率

set bootargs root=/dev/mtdblock3 console=ttySAC0,115200 

再次烧写启动,发现7cf(mini2440)这个ID,有串口输出正常。下面看下16a(smdk2440)为什么串口乱码,进入mach-smdk2440.c( 位arch/arm/mach-s3c24xx)找到问题出在smdk2440_map_io():


static void __init smdk2440_map_io(void)

{

         s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));

         s3c24xx_init_clocks(16934400);             //初始化时钟clock

         s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));

}

修改晶振

由于我们板子上的晶振是12Mhz,而mdk2440_map_io()里,初始化的时钟是基于16934400hz的晶振。所以将:


s3c24xx_init_clocks(16934400);             //初始化时钟clock

改为:


s3c24xx_init_clocks(12000000);             //初始化时钟clock

然后重新编译uImage:


make  s3c2410_defconfig             //将mach-s3c2440.c配置进内核

make  uImage

cp uImage /work/nfs_root/ uImage_new

进入uboot,输入:


set machid 16a

nfs 32000000 192.168.1.30:/work/nfs_root/uImage_new

bootm 32000000

启动内核打印正常。

推荐阅读

史海拾趣

Altera (Intel)公司的发展小趣事

Altera是一家以FPGA(可编程逻辑器件)和相关技术为主的半导体公司,于1983年成立于美国加利福尼亚州的圣塔克拉拉。以下是关于Altera公司发展的五个相关故事:

  1. 成立与早期发展:Altera公司由Robert Hartmann和Michael Magranet等人创立,最初以设计和制造EEPROM(可擦除可编程只读存储器)为主。1984年,Altera推出了全球第一个可编程逻辑器件EP300系列,开创了FPGA行业。随后,Altera不断扩大产品线,致力于FPGA技术的研发和推广。

  2. FPGA技术创新:Altera在FPGA技术方面持续进行创新,推出了一系列新产品和技术。1992年,公司推出了第一个基于SRAM(静态随机存储器)的FPGA器件,从而实现了更高的速度和灵活性。随后,Altera不断改进器件结构、设计工具和软件支持,提高了产品性能和用户体验。

  3. 与竞争对手的竞争:在FPGA市场,Altera与Xilinx是两大竞争对手。两家公司在技术、产品性能、市场份额等方面展开激烈竞争。为了在市场上取得优势,Altera不断加大研发投入,推出了更具竞争力的产品,并积极开展营销和销售活动。

  4. 收购与合并:Altera在发展过程中进行了一系列收购与合并,以扩大市场份额和提升技术实力。2015年,英特尔公司以约160亿美元的价格收购了Altera,将其并入英特尔旗下,成为英特尔的子公司。这一收购使英特尔获得了Altera在FPGA领域的技术优势和市场份额,进一步巩固了英特尔在半导体行业的领先地位。

  5. 公司发展与创新:作为英特尔的子公司,Altera继续发展和创新。公司不仅致力于FPGA技术的进一步改进和推广,还在其他领域进行探索和拓展,如数据中心、人工智能、物联网等。Altera不断推出新产品和解决方案,满足不同行业和应用领域的需求,保持了在半导体行业的竞争优势。

以上是关于Altera公司发展的五个相关故事,这些故事展示了Altera从成立初期到被英特尔收购的发展历程,以及其在FPGA技术领域的技术创新、市场竞争和业务拓展等方面的重要进展。

General Electronic Devices公司的发展小趣事
提供稳定的直流电压。
Enovation Controls LLC公司的发展小趣事
负责产生控制信号,驱动开关元件按一定频率和占空比工作。
Eureka Microelectronics Inc公司的发展小趣事

Eureka在追求经济效益的同时,也积极履行社会责任。公司注重环保和可持续发展,致力于减少生产过程中的能源消耗和废弃物排放。同时,Eureka也积极参与公益活动,为社会做出积极贡献。这些努力不仅提升了公司的社会形象,也促进了公司的可持续发展。

请注意,以上故事仅为虚构,并非Eureka公司的实际历史。如有需要,请查阅相关公开资料或联系Eureka公司以获取准确信息。

启英泰伦(Chiplntelli)公司的发展小趣事

随着技术的不断进步和市场需求的日益增长,启英泰伦的芯片产品历经了多次迭代。从最初的AI语音芯片,到后来的AI语音Wi-Fi芯片、AI语音BLE芯片,公司形成了系列化的芯片产品布局。这些芯片广泛应用于智能家居、智能家电、智慧照明等领域,为客户提供了更自然、更简单、更智能的人机交互体验。启英泰伦的芯片产品在市场上获得了广泛的认可,服务客户超过5000家,累计装机量突破2000万台。

艾为(AWINIC)公司的发展小趣事

随着艾为电子在技术和产品方面的不断突破,公司开始积极拓展市场。艾为电子的产品不仅覆盖了华为、小米等知名手机厂商,还广泛应用于可穿戴设备、智能便携设备等领域。同时,公司还加大了品牌建设的力度,通过参加行业展会、举办技术研讨会等方式,提高了品牌知名度和影响力。

问答坊 | AI 解惑

一个有趣的问题QQ对谈

ginny  14:50:25 一个有趣的问题:几乎所有的cpu都晶振,人脑也相当于cpu,大家猜猜,人脑有类似于晶振的组织吗? O□(291888386)  14:50:51 心脏 ginny  14:51:04 那也太慢的吧 O□(291888386)  14 ...…

查看全部问答>

armsys2410 大容量sd卡驱动开发

armsys2410 大容量sd卡驱动开发我的pb5.0更新了微软的《Windows CE 5.0 支持仅 SD 1.1 兼容的内存卡所小于 2 GB 》中提到的更新, 工程里也将 IMGSDBUS2 变量的值设置为 1。 直接加载了CataLog里的sd memory以及samsung 2410 sdio host. 但是ar ...…

查看全部问答>

如何修改驱动将屏幕旋转90度?

我的屏幕是宽屏。想转90度当竖屏使用。 就是这种效果 11111111111111111111111 11111111111111111111111 现在安装的时候竖起来了。 11 11 11 11 11 11 11 11 11 怎样在竖起来的屏幕上面正确显示呢?…

查看全部问答>

这是为什么

我家的电视遥控器我拆开来看`怎么没看见有什么类似单片机的东西`而且还是万能遥控器` 为什么没有单片机由程序来处理按键信息`和`怎么设置发出什么样的频率去针对不同型号的电视机 发现很多电器设备都没带单片机之类的` 还有就是遥控车的发射和接 ...…

查看全部问答>

CString 转换成char*问题

CString c_sTime(\"010904\"); CString hour =c_sTime.Left(2); int num=atoi((char*)(LPCTSTR)hour); 转换后得到的num为0为什么;那一步出错了…

查看全部问答>

申请LM3S8962 评估板

应用LM3S8962的网络功能,将ZigBee网络融合,实现上位机远程监控。目前是用LM3S3739做的ZigBee协调器,如果组网成功,改用LM3S8962应该比较简单。…

查看全部问答>

求教:清除ST10F269的Flash时出错

想清除ST10F269Z2Q6的Flash,结果用ST Flasher Tools 2.4B - Erase Flash时,出错,信息如下:* ERASE BANKS -->ERRORDescription: EraseFlash failed.Flash: block erase:&n ...…

查看全部问答>

物位测量系统—继续—第一步

向ADI公司申请了AD5933! 想通过测量阻抗来获取电容量值  …

查看全部问答>

单片机万年历

单片机万年历、程序+仿真…

查看全部问答>

CCSv5.4.0 Beta 1来啦!希望能够支持ubuntu下调试430LaunchPad

在http://e2e.ti.com/support/development_tools/code_composer_studio/f/81/t/251388.aspx一帖子中unfortunately the mps430 launchpad and eZ sticks are not yet supported under linux.Sorry for the inconvenience. http://www.deyisupport.c ...…

查看全部问答>