uClinux在S3C4510上的启动分析(ZT)

uClinux的执行过程

 

 uCinux的启动主要经历三个阶段。首先,必须完成CPU和存储器的硬件初始化,在系统RAM中建立程序堆栈和数据段,建立程序的运行时的环境。初始化完成之后,uClinux内核就取得了CPU的控制权,开始操作系统自身的初始化,这包括建立RAM中断矢量表、加载设备驱动程序、内存管理模块等等。这一切完成后,uClinux启动一个最初的init线程,进入到第三阶段,这时内核已经正常运行,外围模块也都就绪,开始执行一些脚本文件(如/etc/rc脚本文件)。

 

                       一.kernel代码段之前的系统初始化 

 

1. uClinux-dist/linux-2.4.x/arch/armnommu/boot/compressed/head.S

 

    开发板从上电开始,最开始执行的程序放在uClinux-dist/linux-2.4.x/arch/armnommu/boot/compressed/head.S中.

 

   (1) 切换模式,关闭中断. (line 96 )

 

   (2) 首先程序要先给SYSCFG,EXTDBWTH,ROMCON0等一系列系统控制寄存器赋值,此时flash地址在   0X0,DRAM地址在0X1000000.(line 141 )

 

   (3) 点亮I/O口的指示灯. (line 152 )

 

   (4) 把在flash上的image复制到DRAM上.(line 161 )

 

   (5) 执行remap,把flash地址映射为0X1000000,DRAM地址映射为0.(line 172 )

 

   (6) 打开cache和write buffer.(line 196 )

 

   (7) 设置好64K堆栈.(line 204 )

 

   (8) 跳转到decompress_kernel函数(line 217 ),此处的跳转为带返回的跳转,以便于执行完此函数跳转回来.

 

2. uClinux-dist/linux-2.4.x/arch/armnommu/boot/compressed/misc.c

 

     此时的函数decompress_kernel是用C语言写的,line 297 .

 

   (1) makecrc();进行crc校验.

 

   (2) puts("Uncompressing Linux..."); 输出linux起动后的第一句话.

 

   (3) gunzip();解压缩kernel.

 

   (4) puts(" done, booting the kernel./n");

 

3. uClinux-dist/linux-2.4.x/arch/armnommu/boot/compressed/head.S

 

   执行完decompress_kernel函数后,kernel又跳转回head.S中,因为此时我们还要检验解压缩之后的kernel起始地址是否紧接着kernel image,如果是,beq call_kernel(line 220),执行解压后的kernel.

 

   如果解压缩之后的kernel起始地址不是紧接着kernel image,执行relocate(line 236),将其拷贝到紧接着kernel image的地方,然后跳转,执行解压后的kernel.

 

 

 

                          二.kernel执行

 

1.uClinux-dist/linux-2.4.x/init/main.c中的start_kernel()  (line 352)   

 

   系统启动过程到此,转入体系结构无关的通用C代码中,start_kernel() 中调用了一系列初始化函数,以完成kernel本身的设置。这些动作有的是公共的,有的则是需要配置的才会执行的。

 

    (1) 输出Linux版本信息(printk(linux_banner))

  (2) 设置与体系结构相关的环境(setup_arch())

 

 

    (3) parse_options(command_line);解析command_line,将其转化为环境变量.

 

    (4) 初始化系统IRQ(init_IRQ())

 

    (5) 核心进程调度器初始化(sched_init())

 

    (6) 软中段初始化softirq_init();

 

    (7) 时间、定时器初始化(包括估测主频、初始化定时器中断等,time_init())

 

    (8) 控制台初始化console_init();

 

    (9) 核心CACHE初始化kmem_cache_init(); 

 

    (10)延迟校准calibrate_delay();

 

    (11)内存初始化(设置内存上下界和页表项初始值,mem_init()) 

 

    (12)文件,目录,块设备读写缓冲区初始化

 

    (13)检查体系结构漏洞(check_bugs())

 

    (14)启动init过程(创建第一个核心线程,调用init()函数,原执行序列调用cpu_idle() 等待调度,init())

 

   至此start_kernel()结束,基本的核心环境已经建立起来了。

 

 

 

2.uClinux-dist/linux-2.4.x/init/main.c中的init() (line 548)

 

现在我们进入内核引导第二部分,init()函数作为核心线程,首先锁定内核(仅对SMP机器有效,我们为空函数),然后调用 do_basic_setup() (line 551)完成外设及其驱动程序的加载初始化。

 

过程如下:

 

    * 网络初始化(初始化网络数据结构,包括sk_init()、skb_init()和proto_init()三部分,在proto_init()中,将调用protocols结构中包含的所有协议的初始化过程,sock_init())

 

    * 创建事件管理核心线程(start_context_thread()函数,这是系统创建的第二个内核线程,名叫“keventd”。其代码context_thread()也在kernel/context.c中,)

 

启动任何使用__initcall标识的函数(方便核心开发者添加启动函数,此时由do_initcalls()函数启动)。

 

    此时系统开始加载外部设备的初始化程序,如:在linux-2.4.x/driver/block/genhd.c中的device_init()函数,在genhd.c中由__initcall(device_init)标识在此时调用,device_init()函数是所有外部设备初始化的总入口,包括了块设备的初始化blk_dev_init,网络设备的初始化net_dev_init()和atmdev_init()等。

 

   至此do_basic_setup()函数返回init(),在释放启动内存段(free_initmem())并给内核解锁以后,init()打开/dev/console设备,重定向stdin、stdout和stderr到控制台,最后,搜索文件系统中的init程序(或者由init=命令行参数指定的程序),并使用 execve()系统调用加载执行init程序。(line 576) .

 

   init()函数到此结束,内核的引导部分也到此结束了,

 

 

 

3. uClinux-dist/linux-2.4.x/init/main.c中的execve("/etc/init",argv_init,envp_init); (line 579)

 

       init进程是系统所有进程的起点,内核在完成核内引导以后,即在本线程(进程)空间内加载init程序,它的进程号是1。

 

   init程序需要读取/vendors/SAMSUNG/4510B/inittab文件作为其行为指针,然后执行.

 

 

 

4.系统执行rc脚本.

 

hostname Samsung

 

/bin/expand /etc/ramfs.img /dev/ram0

 

/bin/expand /etc/ramfs2048.img /dev/ram1

 

mount -t proc proc /proc

 

mount -t ext2 /dev/ram0 /var

 mount -t ext2 /dev/ram1 /ramdisk

 

 

chmod 777 /ramdisk

 

mkdir /var/config

 

mkdir /var/tmp

 

mkdir /var/log

 

mkdir /var/run

 

mkdir /var/lock

 

ifconfig lo 127.0.0.1

 

route add -net 127.0.0.0 netmask 255.255.255.0 lo

 

dhcpcd &

 

 

 

cat /etc/motd

 

 

 

rc程序执行完毕后,系统环境已经设置好了,下面就该用户登录系统了。

 

 

 

5.运行Sash command shell

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值