MACHINE_START and MACHINE_END Macro define

基于Linux与Busybox的Reboot命令流程分析 这段时间,在忙到一个项目时,需要在busybox中用到reboot命令,开始在busybox中的shell中输入reboot命令,始终如下的信息,然后就停止在那里了,无法重启...为了彻底的弄明白这个问题,我在网络上找了很久,终于有个人写的一个reboot流程分析,我就借花献佛.在这里重新分析下busybox是如何运行这个命令 阅读详情

***************************************************************************************************************************
作者:EasyWave                                                                                 时间:2012.02.11

类别:linux驱动开发                                                                           声明:转载,请保留链接

***************************************************************************************************************************

在linux-2.6.38中,/arch/arm/mach-w90x900/mach-nuc950evb.c文件的最后部分,有如下宏定义:

MACHINE_START(W90P950EVB, "W90P950EVB")
 .phys_io = W90X900_PA_UART,
 .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc, 
 .boot_params =  0x100,
 .map_io  = nuc950evb_map_io,
 .init_irq = nuc900_init_irq,
 .init_machine = nuc950evb_init,
 .timer  = &nuc900_timer,
MACHINE_END

 

而MACHINE_START和MACHINE_END宏定义在arch/arm/include/asm/mach/arch.h,如下:

struct machine_desc {
 /*
  * Note! The first four elements are used
  * by assembler code in head.S, head-common.S
  */
 unsigned int  nr;  /* architecture number */
 unsigned int  phys_io; /* start of physical io */
 unsigned int  io_pg_offst; /* byte offset for io
       * page tabe entry */

 const char  *name;  /* architecture name */
 unsigned long  boot_params; /* tagged list  */

 unsigned int  video_start; /* start of video RAM */
 unsigned int  video_end; /* end of video RAM */

 unsigned int  reserve_lp0 :1; /* never has lp0 */
 unsigned int  reserve_lp1 :1; /* never has lp1 */
 unsigned int  reserve_lp2 :1; /* never has lp2 */
 unsigned int  soft_reboot :1; /* soft reboot  */
 void   (*fixup)(struct machine_desc *,     struct tag *, char **,   struct meminfo *);
 void   (*map_io)(void);/* IO mapping function */
 void   (*init_irq)(void);
 struct sys_timer *timer;  /* system tick timer */
 void   (*init_machine)(void);
};

/*
 * Set of macros to define architecture features.  This is built into
 * a table by the linker.
 */
#define MACHINE_START(_type,_name)   \
static const struct machine_desc __mach_desc_##_type \
 __used       \
 __attribute__((__section__(".arch.info.init"))) = { \
 .nr  = MACH_TYPE_##_type,  \
 .name  = _name,

#define MACHINE_END    \
};

#endif

 

将前面定义的MACHINE_START和MACHINE_END展开后得到:
static  const struct machine_desc __mach_desc_W90P950EVB __used __attribute__((__section__(".arch.info.init"))) = {
.nr = MACH_TYPE_W90P950EVB, /* architecture number */
.name = "W90P950EVB"", /* architecture name */
.phys_io = W90X900_PA_UART, /* start of physical io */
.io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
.boot_params = 0x100, /* tagged list */
.map_io = nuc950evb_map_io, /* IO mapping function */
.init_irq = nuc900_init_irq,
.init_machine = nuc950evb_init,
.timer = &nuc900_timer,
}

MACH_TYPE_W90P950EVB定义在arch/arm/include/asm/mach-types.h内,值为1860 十六进制为:0x744.
#define MACH_TYPE_W90P950EVB             1860

这个值是机器的类型值,编译时由arch/arm/tool/mach- types里面定义的数据生成的。
/* arch/arm/tool/mach-types */
w90x900   MACH_W90X900  W90X900   1860

而在arch/arm/kernel/head-common.S文件中的__lookup_machine_type函数中有如下的定义:

/*
 *  linux/arch/arm/kernel/head-common.S
 *
 *  Copyright (C) 1994-2002 Russell King
 *  Copyright (c) 2003 ARM Limited
 *  All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#define ATAG_CORE 0x54410001
#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)

 .align 2
 .type __switch_data, %object
__switch_data:
...................中间省略

 .long processor_id                   @ r4
 .long __machine_arch_type    @ r5
 .long __atags_pointer              @ r6
 .long cr_alignment                   @ r7
 .long init_thread_union + THREAD_START_SP  @ sp

 ...................中间省略

/*
 * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for
 * more information about the __proc_info and __arch_info structures.
 */
 .align 2
3: .long __proc_info_begin
 .long __proc_info_end
4: .long .
 .long __arch_info_begin
 .long __arch_info_end

/*
 * Lookup machine architecture in the linker-build list of architectures.
 * Note that we can't use the absolute addresses for the __arch_info
 * lists since we aren't running with the MMU on (and therefore, we are
 * not in the correct address space).  We have to calculate the offset.
 *
 *  r1 = machine architecture number
 * Returns:
 *  r3, r4, r6 corrupted
 *  r5 = mach_info pointer in physical address space
 */
__lookup_machine_type:
#ifdef CONFIG_ARCH_W90X900     //这个就是前面的1860,十六进制为:0x744
       mov      r1, #0x700
       add      r1, r1, #0x40
       add      r1, r1, #0x04
#endif
 adr r3, 4b
 ldmia r3, {r4, r5, r6}
 sub r3, r3, r4   @ get offset between virt&phys
 add r5, r5, r3   @ convert virt addresses to
 add r6, r6, r3   @ physical address space
1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
 teq r3, r1    @ matches loader number?
 beq 2f    @ found
 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
 cmp r5, r6
 blo 1b
 mov r5, #0    @ unknown machine
2: mov pc, lr
ENDPROC(__lookup_machine_type)

函数说明:

adr r3,4b : 取地址指令,这里的4b 是向后symbol名称是4的位置,即4: .long .的位置,将该地址存入r3,r3中存放的是4b处物理地址.
        r5存的是__arch_info_begin 的地址
        r6存的是__arch_info_end 的地址


arm linux 从入口到start_kernel 代码分析

__arch_info_begin 和 __arch_info_end是在 arch/arm/kernel/vmlinux.lds.S中:

          __arch_info_begin = .;
          *(.arch.info.init)
          __arch_info_end = .;    

        这里是声明了两个变量:__arch_info_begin 和 __arch_info_end,其中等号后面的"."是location counter(详细内容请参考ld.info),这三行的意思是: __arch_info_begin 的位置上,放置所有文件中的 ".arch.info.init" 段的内容,然后紧接着是 __arch_info_end 的位置.

teq r3, r1    @ matches loader number?
如果R1中存储的值和mach-types.h不一致的话,会出现下面的错误:

Machine configuration botched (nr xxxx), unable to continue.不同的版本会出现的警报不一致。

在arch/arm/kernel/setup.c中:

void __init setup_arch(char **cmdline_p)
{
 struct tag *tags = (struct tag *)&init_tags;
 struct machine_desc *mdesc;
 char *from = default_command_line;

 unwind_init();

 setup_processor();
 mdesc = setup_machine(machine_arch_type);
 machine_name = mdesc->name;

 if (mdesc->soft_reboot)
  reboot_setup("s");

 if (__atags_pointer)
  tags = phys_to_virt(__atags_pointer);
 else if (mdesc->boot_params)
  tags = phys_to_virt(mdesc->boot_params);

 /*
  * If we have the old style parameters, convert them to
  * a tag list.
  */
 if (tags->hdr.tag != ATAG_CORE)
  convert_to_tag_list(tags);
 if (tags->hdr.tag != ATAG_CORE)
  tags = (struct tag *)&init_tags;

 if (mdesc->fixup)
  mdesc->fixup(mdesc, tags, &from, &meminfo);

 if (tags->hdr.tag == ATAG_CORE) {
  if (meminfo.nr_banks != 0)
   squash_mem_tags(tags);
  save_atags(tags);
  parse_tags(tags);
 }

 init_mm.start_code = (unsigned long) _text;
 init_mm.end_code   = (unsigned long) _etext;
 init_mm.end_data   = (unsigned long) _edata;
 init_mm.brk    = (unsigned long) _end;

 /* parse_early_param needs a boot_command_line */
 strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);

 /* populate cmd_line too for later use, preserving boot_command_line */
 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
 *cmdline_p = cmd_line;

 parse_early_param();

 paging_init(mdesc);
 request_standard_resources(&meminfo, mdesc);

#ifdef CONFIG_SMP
 smp_init_cpus();
#endif

 cpu_init();
 tcm_init();

 /*
  * Set up various architecture-specific pointers
  */
 init_arch_irq = mdesc->init_irq;
 system_timer = mdesc->timer;
 init_machine = mdesc->init_machine;

#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
 conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
 conswitchp = &dummy_con;
#endif
#endif
 early_trap_init();
}

而setup_machine(unsigned int nr)函数也是在arch/arm/kernel/setup.c中定义:

static struct machine_desc * __init setup_machine(unsigned int nr)
{
 struct machine_desc *list;

 /*
  * locate machine in the list of supported machines.
  */
 list = lookup_machine_type(nr); //看到了吧,这个才是重点
 if (!list) {
  printk("Machine configuration botched (nr %d), unable "
         "to continue.\n", nr);
  while (1);
 }

 printk("Machine: %s\n", list->name);

 return list;
}

因此就会出现:Machine configuration botched (nr xxxx), unable to continue.的警告信息。

 

各个成员函数在不同时期被调用:
1. .init_machine 在 arch/arm/kernel/setup.c 中被 customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用。
2. init_irq在start_kernel() --> init_IRQ() --> init_arch_irq() 被调用
3. map_io 在 setup_arch() --> paging_init() --> devicemaps_init()被调用
其他主要都在 setup_arch() 中用到。

【信息科学与工程学】计算机科学与技术——第七十七篇 系统架构设计02 编号类型模型配方企业资本运作的方法/规则/条件/依据及所有的步骤(​风险处理/异常处理/危机应对关联知识法律法规和裁决依据​​由发起人(通常是知名投资人、投行或产业资本)先设立一个只有现金、无实际业务的特殊目的收购公司(SPAC),通过IPO募集资金并在交易所上市。然后在规定时间内(通常24个月)寻找一家非上市公司进行合并(De-SPAC),使目标公司迅速实现上市,规避传统IPO的复杂流程和不确定性。1.:在开曼或特拉华注册空壳公司,注入少量种子资金。2. 阅读详情

相关推荐

W90x900 BSP中文资料

W90x900 BSP中文资料,搭建W90x900 BSP开发环境,华邦ARM9系列Linux版本的BSP包的编译器工具链

深入理解 Linux 宏定义 MACHINE_START

深入理解 Linux 宏定义 MACHINE_START

li的博客 814

STM32与SD卡SPI接口硬件设计:从原理图到调试的完整指南

SPI(串行外设接口)作为一种广泛应用的同步串行通信协议,以其接线简单、驱动成熟的特点,成为连接微控制器与各类外设的经典方案。其工作原理基于主从架构,通过时钟、数据线和片选信号实现全双工通信,在嵌入式系统中具有极高的技术价值,常用于连接传感器、存储设备和显示模块等。在数据存储场景中,SD卡凭借其大容量和便携性成为首选,而通过SPI模式驱动SD卡,则平衡了性能与设计复杂度。本文聚焦于使用Altium Designer进行硬件设计的工程实践,详细解析了STM32微控制器与SD卡通过SPI通信时,电源管理、上拉电

weixin_34101784的博客 554

linux之MACHINE_START和 MACHINE_END

一、   注:下面的内容是以linux-2.6.38和mini6410为例进行学习的。         玩过或者移植过arm-linux的都应该知道在/arch/arm目录下有许多与具体处理器相关的目录,当然对于6410的话所对应的目录就是mach-s3c64xx,在里面找到与具体板子相关的文件mach-mini6410.c,没错,就是它。无论是出于想移植到新的内核还是出于想深入学习某一款a

宇宙的起源 2084

具身智能四大技术路线:VLA、大小脑、世界模型与强化学习

具身智能是机器人实现感知-决策-执行闭环的核心范式,其本质在于物理世界中的具身化交互能力。技术演进围绕如何高效建模环境、理解指令并生成鲁棒动作展开,衍生出四大主流路径:视觉-语言-动作(VLA)端到端学习、大小脑分层控制、世界模型驱动预测,以及强化学习原生策略优化。VLA强调多模态对齐与泛化能力,适合语义理解优先场景;大小脑架构兼顾实时性与可解释性,是工业落地的高可靠选择;世界模型追求内在物理模拟,代表长期认知跃迁方向;强化学习则扎根仿真试错,在力控、抓取等连续控制任务中展现强鲁棒性。本文聚焦这四大路线的技

weixin_32181267的博客 291

react +ant desiagn pro实现按钮操作权限控制

在ant desiagn pro中提供了一个access用于对权限进行控制,需引入useAccess和Access

Sylvasylva的博客 2210

MACHINE_START-内核板级初始化实现机制(linux3.1.0)

在驱动开发时,我们都是以一块开发板为基础移植驱动程序。每一块开发板对应一个板级文件,如开发 TI AM335x系列,则对应board-am335xevm.c,这个文件完成芯片和板级的初始化工作。对于驱动开发,还有 一个很重要的文件devices.c,这个文件主要是设备接口相关资源。 今天就来说说board-am335xevm.c文件,如何全面的了解这个文件呢?先找到这个文件的入口,在文件的

亚亚图雷的专栏 4803

从混乱到清晰:用QJsonObject重构你的Qt网络API数据解析层(避坑指南)

本文详细介绍了如何使用QJsonObject重构Qt网络API数据解析层,避免常见的JSON解析陷阱。通过安全解析模式、数据绑定和性能优化技巧,帮助开发者构建高效、健壮的解析逻辑,提升代码可维护性和可读性。特别适用于处理复杂嵌套的JSON响应数据场景。

weixin_29011667的博客 229

【转】MACHINE_START分析

<br />本文转自: http://blog.sina.com.cn/s/blog_4ae5be930100nyfl.html<br /> <br />在友善mini2440提供的linux2.6.32.2内核中,有如下定义: MACHINE_START(MINI2440, "FriendlyARM Mini2440 development board").phys_io = S3C2410_PA_UART,.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0

博道的专栏 514

《Cesium 基础知识点》- 申请 Cesium Ion 密钥

一、访问 https://cesium.com/ion/signin/tokens 二、登录/注册 三、申请 四、使用 // 密钥 let defaultAccessToken = 'your token string'; // 设置 Cesium.Ion.defaultAccessToken = defaultAccessToken; // 初始化 let viewer = new Cesium.Viewer('cesiumContainer', {}); ...

前端技术 2570

SPSS与SPSS Modeler,不一样的世界

1. SPSS软件的前世今生 1.1 IBM SPSS的由来 与数据打过交道的小伙伴们,应该对SPSS软件都不陌生。SPSS是世界上最早的统计分析软件,由斯坦福大学的三个研究生大牛于1968年研发,同时还成立了SPSS公司。SPSS最初的全称是Solutions Statistical Package for the Social Sciences(社会科学统计软件包),随着SPSS产品服务领...

qq_24339451的博客 3611

linux machine start,Linux中的MACH定义之MACHINE_START / MACHINE_END

(写在转载之前)在linux中machine对应一个设备,对于开发者而言对应一个新的项目,项目开展的初始需要对应定义一个MACH,在arch/arm/mach-xxx/目录下,此文件中定义了GPIO的使用,外设,i2c总线等系统信息,所以在参加一个项目的开始,应该认真的分析machine定义文件,了解项目的情况。在arch/arm/下定义了很多mach-xxx的文件夹,一般是按照厂商或者平台命名,...

weixin_39983427的博客 550

软件工程案例教程·韩万江【课后习题】

!!!!

weixin_57858263的博客 6416

Erlang记录与宏的高级应用及性能优化

数据结构是编程语言中的基础概念,Erlang中的记录(record)提供了一种结构化数据组织方式,通过字段名而非位置索引访问数据,显著提升代码可读性。其底层实现为元组转换,保证了运行时效率。在工程实践中,记录常与宏系统配合使用,宏不仅能实现条件编译和代码生成,还能创建领域特定语言(DSL)。特别是在性能敏感场景中,合理使用宏可以消除函数调用开销,如在高并发系统中实现15%的性能提升。这些特性使Erlang特别适合构建分布式、高可用的电信级应用系统。

weixin_30268921的博客 310

2018安徽省青少年信息学奥林匹克(AHOI)初中组

12 种合法的排列分别为:1, 3, 2, 4, 2, 3, 1, 4, 3, 1, 4, 2, 3, 2, 4, 1, 1, 3, 4, 2, 2, 3,4,1,1,4,2,3, 2,4,1,3, 4,1,3,2, 4,2,3,1, 1,4,3,2, 2,4,3,1。分为 2 组,一组的队员实力值是{4, 5, 2, 3},一组是{-4, -3, -5},其中最小的组人数为 3,可以发现没有比 3 更优的分法了。[0, 1, 1, 2]同样不是合法的分组方案,因为出现了两个实力值为 1 的选手。

weixin_42358969的博客 1142

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

GOTO 语句有害论 | 反对 GOTO 语句的理由

……

u013669912的博客 1872

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

BMS基础软件通信驱动设计

本文围绕基于AUTOSAR规范的电池管理系统(BMS),重点探讨了通信驱动设计与系统集成相关内容。 文中主要涉及CAN通信驱动和SPI通信驱动。在通信驱动设计方面,阐述了Can智能收发器 TJA1145驱动的实现,该收发器通过SPI总线与MCU通信以实现CAN收发功能,借助WAKE 引脚实现CC信号唤醒功能,其INT引脚输出可作为电源芯片 8510 的唤醒信号之一,并由 TC275 进行采集;同时提及了双路 SPI 通信驱动的实现,包括硬件采用菊花链通讯及相关软件内容。

十六宿舍的博客 590

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【X86】实现x86-linux内核项目

把解压包x86安装在C盘地下,把bin目录加入到系统配置当中,加载GCC工具链。c02.02 Windows开发环境配置_哔哩哔哩_bilibili。安装cmake 软件自带加载path目录。把qemu也下载安装,作为模拟器。按照vscode并且增加扩展。暂时还没做完 做完后会上传。安装git并且按照环境变量。

qq_58358642的博客 155

C++AI编译错误自动修复神器-告别手动Debug的终极方案

在日常 C++ 开发中,编译错误是最频繁遇到的障碍之一。一个中等规模的项目在重构期间,一次 可能产生数十甚至上百条错误信息。这些错误往往具有级联效应——一个头文件的拼写错误可能导致下游十几个翻译单元同时报错,而真正需要修改的地方只有一处。传统的工作流是: 这个循环对于经验丰富的开发者来说尚可接受,但对于以下场景则效率极低:优势:局限:本项目最适合以下场景:阅读

weixin_48053866的博客 278

uboot的移植——移植uboot官方的uboot到x210开发板(2)

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

主要记录嵌入式学习与开发过程。 1537

LINUX中的MACH定义之MACHINE_START / MACHINE_END

LINUX中的MACH定义之MACHINE_START / MACHINE_END 田海立@优快云 2011/08/18 本文讲解LINUX中用MACHINE_START/MACHINE_END定义的MACH,并给出定义的各个成员函数在初始化过程中被调用的时机。 1. 定义一个MACH LINUX中MACHINE定义是用MACHINE_START()/MACHINE_END两个宏来实现的,...

wangminshe89 298

MACHINE_START与MACHINE_END

在移植Linux时,有个结构体需要填写,它以MACHINE_START开始并以MACHINE_END结束,如下mini2440开发板的移植为示例 MACHINE_START(MINI2440, "MINI2440") .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .bo

lyuncxw 1万+

关于MACHINE_START

MACHINE_START(VR1000, "Thorcom-VR1000") /* Maintainer: Ben Dooks ben@simtec.co.uk> */ .phys_ram = S3C2410_SDRAM_PA, .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 

2484

从MACHINE_START开始

注:下面的内容是以linux-2.6.38和mini6410为例进行学习的。         玩过或者移植过arm-linux的都应该知道在/arch/arm目录下有许多与具体处理器相关的目录,当然对于6410的话所对应的目录就是mach-s3c64xx,在里面找到与具体板子相关的文件mach-mini6410.c,没错,就是它。无论是出于想移植到新的内核还是出于想深入学习某一款arm等,对这个...

weixin_34192993的博客 249

MACHINE_START

玩过或者移植过arm-linux的都应该知道在/arch/arm目录下有许多与具体处理器相关的目录,当然对于s3c2440的话所对应的目录就是 arch/arm/mach-s3c2440/,在里面找到与具体板子相关的文件mach-mini2440.c,这个文件大部分内容是对平台设备(例如串口,LCD,Nand falsh等)的结构体初始化,在这个文件的最后有一个非常重要的宏: MAC

a04081122的专栏 658

MACHINE_START 怎样调用

MACHINE_START是怎样被系统调用的 MACHINE_START(AM335XEVM,"am335xevm") /*Maintainer:TexasInstruments*/ .atag_offset =0x100, .map_io =am335x_evm_map_io, .init_early =am33xx_init_early, .init...

weixin_30263073的博客 252
上一篇: USB Host/SD MP3 Decoder for AUC520B
下一篇: Linux Command Line 详细解析
wang-bob
博客等级 码龄20年 356粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值