zoukankan      html  css  js  c++  java
  • 【转载】关于Embedded Linux启动的经典问题

    转载自:http://linux.chinaunix.net/techdoc/install/2009/04/13/1107608.shtml

    发信人: armlinux (armlinux), 信区: Embedded
    标  题: 关于Embedded Linux启动的经典问题
    发信站: 哈工大紫丁香 (Sun Aug 31 20:14:46 2003)
    On Sat 06 Apr, Arts Thibaut wrote:
    > due to compiling problem, i try to understand the boot sequence. I know
    > the main points for i386 architecture.
    > > i assume that the entry point of Linux is the
    > ~/arch/armnommu/boot/compressed/head.S file written by Russel King.
    > This function call (after uncompressing the kernel) the "start_kernel"
    > function.
    > > i wish to know:
    > > * what is the real boot sequence? (if i am wrong)
    > * what exactly do the head.S file? (or where is documentation about it?)
    I've been collecting info with intent to write this up properly. I haven't
    done it yet, but I might soon.
    Here is the collected info, totally unedited, and largely from posts to this
    list. It should help you get the general idea:
    Startup
    -------
    bootloader:
    Linux needs almost nothing. Basically Linux just needs a boot loader to
    get the kernel from some storage medium into RAM by some method, set up
    a couple of registers and call it at its entry point. No MMU setup is
    required.
    After the bootloader finishes, it calls bootLinux(), which jumps to
    the kernel. However, since the kernel is compressed, the first
    entry point is in arch/arm/boot/compressed/head.s. This calls
    decompress_kernel(), which is located in /arch/arm/boot/compressed/misc.c.
    This calls setup_sa1100(), which initializes the UART and GPIO, and then
    calls gunzip() after printing "Uncompressing Linux".
    Boot code:
    > ./boot/compressed/head.S
    > ./boot/compressed/head-sa1100.S
    > ./boot/compressed/setup-sa1100.S
    This is startup code for decompressing and locating the kernel image. The
    kernel is stored in compressed form to save space and make bootstrapping
    simpler and easier. This code is discarded once the kernel begins
    executing. This code is called by the bootloader program or whatever is
    used to initialize the machine following a hard reset, after the bootloader
    has loaded the compressed kernel image to a specified location in system
    memory.
    > ./kernel/head-armo.S
    > ./kernel/head-armv.S
    This is the entry point for the kernel itself, which is entered following
    the decompression and relocation of the kernel image to its final
    destination area in system memory.It uses the machine number in R1 to find a
    table built by the linker containing vital info like where the RAM is, how
    much of it there is etc.
    ----from RMK:--
    On Tue, Jul 17, 2001 at 08:45:15PM -0700, Yang, Neil L wrote:
    > I'm interested in finding out more about the arm boot sequence. One of the
    > questions I had was where decompress_kernel() is called from.
    arch/arm/boot/compressed/head.S
    > Also, when is the MACHINE_START macro called?
    Not every macro is a piece of executable code. This particular one builds
    a data structure.
    On Wed, Jul 18, 2001 at 09:49:57AM -0700, Chivukula, Sandeep wrote:
    > >> Also, when is the MACHINE_START macro called?
    > >Not every macro is a piece of executable code. This particular one builds
    > >a data structure.
    > > So when in the boot process does this data structure get created and by
    > whom ? i.e. which function makes it initially
    No function makes it. I'll explain more clearly.
    The MACHINE_START macro expands to a statically built data structure, ie one
    that is there when the compiler builds the file. It expands to:
    const struct machine_desc __mach_desc_(type)
    __attribute__((__section__(".arch.info"))) = {
    nr: MACH_TYPE_(type),
    name: (name)
    The various other definitions set various machine_desc structure members
    using named initialisers, and finally MACHINE_END provides the closing
    brace for the structure initialiser. (see include/asm-arm/mach/arch.h)
    Note that above, (type) is the first argument passed to the MACHINE_START
    macro, and (name) is the second.
    All of these machine_desc structures are collected up by the linker into
    the .arch.info ELF section on final link, which is bounded by two symbols,
    __arch_info_begin, __arch_info_end. These symbols do not contain pointers
    into the .arch.info section, but their address are within that section.
    I hope this is enough information.
    -----------
    This code calls start_kernel
    -------From: Ray L -----on linux-arm-kernel list
    > Is there a way
    > to figure out where everything is placed in the kernel zImage, by looking
    > at the setup of the makefiles and ld?
    yes, look at the ldscripts (*.lds.* under linux/arch/arm/)
    > Where are the variables _text,
    > _etext, _edata, and _end defined.
    in one of the ldscript files, eg: linux/arch/arm/vmlinux.lds
    this script also defines a few tables, including:
    proc.info is an array of structs collected from places like the end of
    linux/arch/arm/mm/proc-arm720.S. these structs hold processor-specific info.
    arch.info is an array of 'struct machine_desc' collected from the
    MACHINE_START() macros, in places like linux/arch/arm/mach-clps711x/p720t.c.
    these structs hold machine-specific info.
    > Specifically, I would like to know the actual trace of the boot
    > sequence of the kernel on an arm processor, not an x86.
    ok, assume you're on a P720T.
    - assume the uncompressor has done its thing, and we have, in RAM, a vmlinux
    image ready to go
    - according to linux/arch/arm/vmlinux.lds, the ENTRY() is at 'stext', so go
    to linux/arch/arm/head-armv.S and find the stext symbol
    - you're not on a netwinder or L7200 so skip down to __entry
    - disable interrupts and make sure we're in supervisor mode
    - call lookup_processor_type, which will query the cpu for it's id, then
    lookup that id in .proc.info table. if it finds the struct, r10 will point
    to it. this struct comes from the end of linux/arch/arm/mm/proc-arm720.S.
    - if we didn;t find the struct, print out 'Error: p' on uart2 and die.
    - the bootloader has arranged for r1 to hold a special integer, selected from
    the list in linux/arch/arm/tools/mach-types. this will be 24 for the P720T
    - call lookup_architecture_type, which will lookup r1 in the arch.info
    table. this is a 'struct machine_desc' created in MACHINE_START() in
    linux/arch/arm/mach-clps711x/p720t.c.
    - if we didn;t find the struct, print out 'Error: a' on uart2 and die.
    - call __create_page_tables to map in ram, uarts, etc
    - set up lr with __ret. next time we return from a subroutine, we'll return
    to __ret, which is a few lines down.
    - set pc = [r10 + 12]. in other words, jump to the address in the fourth
    slot of the P720T proc.info struct, which is __arm720_setup in
    linux/arch/arm/mm/proc-arm720.S.
    - __arm720_setup sets up MMU and returns to __ret in head-armv.S
    - at __ret, set up lr with __mmap_switched (via __switch_data)
    - turn on the MMU, wait for the pipeline to clear, and return to
    __mmap_switched a few lines down
    - __mmap_switched loads up the info from __switch_data. this, among other
    things, set up stack pointer to inittask + 8192.
    - clear out BSS
    - jump to start_kernel
    hopefully i got all that correct :-) it's not the easiest thing to follow,
    but pretty straightforward once you know where the tricky jumps and linker
    tables are.
    --------endsnip
    Wookey

  • 相关阅读:
    关于silverlight打印模糊的问题
    Microsoft Office Excel 不能访问文件及COM无法访问
    IE8 下 select option 内容过长 , 展开时信息显示不全解决办法
    如何用css做一个细虚线边框表格
    DIV 垂直 垂直水平 居中
    Ul li 横排 菜单
    对原生js的一些小尝试
    Nodejs学习笔记——Assert(断言)
    Octopress创建GitHub Pages——基于代码托管的静态博客
    JS倒计时器一只,顺便复习javascript时间相关函数
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/3249000.html
Copyright © 2011-2022 走看看