MACHINE_START MACHINE_END macro

Source: Internet
Author: User

1. define [cpp] # define MACHINE_START (_ type, _ name) \ // board type, the Board name is static const struct machine_desc _ mach_desc _ # _ type \ _ used \ _ attribute _ (_ section _ (".arch.info. init ") = {\. nr = MACH_TYPE _ # _ type ,\. name = _ name, # define MACHINE_END \}; The MACHINE_START and MACHINE_END boxes indicate the machine_desc struct and initialize it according to the MACHINE_START macro parameters. nr and. name member and compile the struct mark to .arch.info. the init segment can initialize the machine_desc struct between the MACHINE_START and MACHINE_END macros. Definition of the remaining member machine_desc struct of [cpp] struct machine_desc {unsigned int nr;/* architecture number */const char * name;/* architecture name */unsigned long boot_params; /* tagged list */unsigned int nr_irqs;/* number of IRQs interrupt count */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 reserv E_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 (* reserve) (void ); /* reserve mem blocks */void (* map_io) (void);/* IO mapping function io ing function */void (* init_irq) (void ); /* interrupt initialization function */struct sys_timer * timer;/* system tick timer */v Oid (* init_machine) (void);/* initialization function */}; example: [cpp] MACHINE_START (SMDKC110, "SMDKC110")/* Maintainer: kukjin Kim <kgene.kim@samsung.com> */. boot_params = S5P_PA_SDRAM + 0x100 ,. init_irq = s5pv210_init_irq ,. map_io = smdkc110_map_io ,. init_machine = smdkc110_machine_init ,. timer = & s3c24xx_timer, MACHINE_END here smdkc110_machine_init is the corresponding board-Level Initialization function, s5pv210_init_irq is the board-level interrupt initialization function, smdkc110_map_io is the board-level io Initialization Function... ii. Call the MACHINE_START macro to compile the machine_desc tag to .arch.info. and/arch/arm/kernel/vmlinux. [cpp] _ arch_info_begin = .; * (.arch.info. init) _ arch_info_end = .; in the linux Startup function start_kernel, setup_arch (& command_line); [cpp] void _ init setup_arch (char ** cmdline_p) {struct tag * tags = (struct tag *) is called *) & init_tags; struct machine_desc * mdesc; // declares a machine_desc struct pointer char * from = default_command_line; init_ta Gs. mem. start = PHYS_OFFSET; unwind_init (); setup_processor (); mdesc = setup_machine (machine_arch_type); // 0 obtain machine_desc machine_name = mdesc-> name based on machine_arch_type; // set the name if (mdesc-> soft_reboot) // need soft restart? Reboot_setup ("s"); if (_ atags_pointer) tags = phys_to_virt (_ atags_pointer); else if (mdesc-> boot_params) {// process the startup parameter # ifdef CONFIG_MMU if (mdesc-> boot_params <PHYS_OFFSET | mdesc-> boot_params> = PHYS_OFFSET + SZ_1M) {printk (KERN_WARNING "Default boot params at physical 0x % 08lx out of reach \ n", mdesc-> boot_params );} else # endif {tags = phys_to_virt (mdesc-> boot_params) ;}# if defined (CONFIG_DE PRECATED_PARAM_STRUCT) if (tags-> hdr. tag! = ATAG_CORE) convert_to_tag_list (tags); # endif if (tags-> hdr. tag! = ATAG_CORE) tags = (struct tag *) & init_tags; if (mdesc-> fixup) // call the 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; vertex = (unsigned long) _ etext; vertex = (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 into _line too for later use, preserving boot_command_li Ne */strlcpy (cmd_line, boot_command_line, COMMAND_LINE_SIZE); * cmdline_p = cmd_line; parse_early_param (); arm_memblock_init (& meminfo, mdesc ); // The reserve method paging_init (mdesc) may be called here; //-> devicemaps_init (mdesc)-> map_io method request_standard_resources (& meminfo, mdesc ); // The video_start method # ifdef CONFIG_SMP if (is_smp () smp_init_cpus (); # endif reserve_crashkernel (); cpu_init (); tcm_init (); arch_nr_ir Qs = mdesc-> nr_irqs; // 1 sets the number of global variable interruptions init_arch_irq = mdesc-> init_irq; // 2 sets the global variable interrupt initialization function system_timer = mdesc-> timer; // 3 set the global variable sys_timer struct init_machine = mdesc-> init_machine; // 4 set the global variable board-Level Initialization function # ifdef CONFIG_VT # if defined (CONFIG_VGA_CONSOLE) conswitchp = & vga_con; # elif defined (CONFIG_DUMMY_CONSOLE) conswitchp = & dummy_con; # endif early_trap_init ();} 0. [cpp] static struct machine_desc *__ Init setup_machine (unsigned int nr) {extern struct machine_desc _ arch_info_begin [], _ arch_info_end []; struct machine_desc * p; for (p = _ arch_info_begin; p <_ arch_info_end; p ++) // The machine_desc structure between _ arch_info_begin and _ arch_info_end if (nr = p-> nr) {// find the corresponding board printk ("Machine: % s \ n", p-> name); // print the board-level information return p ;} early_print ("\ n" "Error: unrecognized/unsupported machine ID (r1 = 0x % 08x ). \ n" "Available machine support: \ n \ nID (hex) \ tNAME \ n", nr); for (p = _ arch_info_begin; p <_ arch_info_end; p ++) early_print ("% 08x \ t % s \ n", p-> nr, p-> name); early_print ("\ nPlease check your kernel config and/or bootloader. \ n "); while (true)/* can't use cpu_relax () here as it may require MMU setup */;} 1. number of interrupts start_kernel-> early_irq_init-> In the arch_probe_nr_irqs function, nr_irqs = arch_nr_irqs? Arch_nr_irqs: NR_IRQS; set global nr_irqs variable 2. interrupt initialization function start_kernel-> init_IRQ-> init_arch_irq () 3. sys_timer struct start_kernel-> time_init () call system_timer-> init () method both sys_timer-> init () 4. board-Level Initialization function [cpp] static void (* init_machine) (void) _ initdata; static int _ init customize_machine (void) {/* customizes platform devices, or adds new ones */if (init_machine) // The global function init_machine has init_machine (); // This is called when mdesc-> init_machin E () return 0;} arch_initcall (customize_machine); // use arch_initcall to modify the archmize_machine function arch_iniitcall function in/include/linux/init. define [cpp] # define arch_initcall (fn) _ define_initcall ("3", fn, 3) _ define_initcall in h [cpp] # define _ define_initcall (level, fn, id) \ static initcall_t _ initcall _ # fn # id _ used \ _ attribute _ (_ section __(". initcall "level ". init ") = fn expansion is static initcall_t _ initcall_cust Omize_machine3 _ used _ attribute _ (_ section __(". initcall3.init ") = customize_machine in vmlinux. [cpp] _ initcall_start = .; *(. initcallearly. init) _ early_initcall_end = .; *(. initcall0.init )*(. initcall0s. init )*(. initcall1.init )*(. initcall1s. init )*(. initcall2.init )*(. initcall2s. init )*(. initcall3.init )*(. initcall3s. init )*(. initcall4.init )*(. initcall4s. init )*(. initcall5.init )*(. initca Ll5s. init )*(. initcallrootfs. init )*(. initcall6.init )*(. initcall6s. init )*(. initcall7.init )*(. initcall7s. init) _ initcall_end = .; marked. the initcall3.init function is compiled into the section in the _ initcall_start and _ initcall_end boxes, and start_kernel-> rest_init ()-> kernel_thread (kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); the kernel thread kernel_init-> do_pre_smp static void _ init do_pre_smp_initcils (void) {initcall_t * fn; for (fn = _ Initcall_start; fn <_ early_initcall_end; fn ++) do_one_initcall (* fn);} This function traverses functions in _ initcall_start and _ early_initcall_end, call do_one_initcall [cpp] int _ init_or_module do_one_initcall (initcall_t fn) {int count = preempt_count (); int ret; if (initcall_debug) ret = fn ); else ret = fn (); // The fn function is executed, that is, customize_machine msgbuf [0] = 0; if (ret & ret! =-ENODEV & initcall_debug) sprintf (msgbuf, "error code % d", ret); if (preempt_count ()! = Count) {strlcat (msgbuf, "preemption imbalance", sizeof (msgbuf); preempt_count () = count;} if (irqs_disabled () {strlcat (msgbuf, "disabled interrupts", sizeof (msgbuf); local_irq_enable ();} if (msgbuf [0]) {printk ("initcall % pF returned with % s \ n", fn, msgbuf);} return ret ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.