创客学院知识巩固-06系统移植部分小结

文章目录

  • 知识框图
  • uboot与kernel启动与移植流程分析---MAKEFILE
    • Makefile
    • uboot启动流程分析
      • 启动流程
      • 启动分析
    • uboot移植
    • 内核启动流程分析
      • 内核启动流程
    • 内核移植
    • Rootfs根文件系统
      • 根文件系统制作
    • 系统启动整体流程
    • ramdisk文件系统制作
      • EXT2文件系统制作
      • EXT4文件系统制作

知识框图

创客学院知识巩固-06系统移植部分小结_第1张图片

uboot与kernel启动与移植流程分析—MAKEFILE

Makefile

uboot启动流程分析

启动流程

  1. 第一阶段:汇编阶段
    设置CPU工作模式,关中断,关MMU,关看门狗…
    初始化时钟,内存
    自搬运
    设置堆栈,清BSS段
    跳转到C环境执行
  2. 第二阶段:C阶段
    初始化GPIO
    初始化用于调试的网口或串口等必要的硬件
    执行CMD命令
    加载内核

启动分析

  1. 启动流程框架
    【uboot代码流程 version:2013】
    1、查找uboot入口函数
    1)通过链接文件(lds)文件查找启动入口函数,路径在(arch\arm\cpu\u-boot.lds),查找到入口函数是_start (ENTRY(_start))
    2)通过全局搜索(或者看链接文件里面的text断里面的start.o),找到_start在start.S下(arch\arm\cpu\armv7\start.S)
    ps:这里之所以取armv7下面的start,主要是由于目标板cpu是armv7下面的cpu。
    2、分析代码流程

     _start
           --reset
             --设置cpu模式,关中断
             --异常表基地址设置
             --cpu_init_cp15(mmu关闭)
             --cpu_init_crit
               --lowlevel_init(board\samsung\origen\lowlevel_init.S)
                 --system_clock_init 时钟初始化(这里不执行)
     --mem_ctrl_asm_init 内存初始化(这里不执行)
                 --uart_asm_init  串口初始化
     --tzpc_init  tzpc初始化
             --_main(arch\arm\lib\crt0.S)
               --为进入C做准备
               --relocated(自搬移,uboot没有在内存里面运行)
     		  --栈的初始化及 bss的清理
               --board_init_r(arch\arm\lib\board.c)
                 --目标板硬件相关初始化
                 --main_loop(for循环进入等待处理命令,待输入加载内核命令后,uboot将操作权限交给内核)
    

    【uboot代码流程version:2016】

     找_start   在 \arch\arm\lib\vectors.S:定义异常向量表
     	找reset   在arch\arm\cpu\armv7\start.S 启动代码
              ldr	r0, =_start  获取uboot加载地址
     	     mcr	p15, 0, r0, c12, c0, 0	@设置vector向量表到start地址。
    

uboot移植

		启动移植框架
			启动流程

内核启动流程分析

内核启动流程

			Kernel

/********解压*****/
1、查找解压的链接文件:arch\arm\boot\compressed\vmlinux.lds.in
2、查找入口函数:start
3、查找start实现,arch\arm\boot\compressed\head.S
   start
      --设置CPU模式 svc,关中断
      --为解压准备(内存、中断、C运行需要xx)
      --解压(decompress_kernel) 到一个指定地址。
      --跳转到指定地址执行(__enter_kernel)。  
/*******内核启动******/
1、查找启动的链接文件:arch\arm\kernel\vmlinux.lds.S
2、查找入口函数:stext
3、查找stext的实现,arch\arm\kernel\head.S
   stext
      --safe_svcmode_maskall(设置CPU模式,svc,关中断 )
--解压内核decompress_kernel  cache_clean_flush
      --cpu准备  打印cpu_info
      --内核加载地址0X40008000
      --__create_page_tables 页面的准备
      -- __enable_mmu 开启mmu
      --跳转到__mmap_switched执行(arch\arm\kernel\head-common.S)
      __mmap_switched
          --清BSS
          --start_kernel(init/main.c)
	      --初始化
          --rest_init
 		    --开启内核线程 kernel_init
			   --挂载根文件系统(rootfs) mount_rootfs()
			       --启动系统的第一个进程 /linuxrc 或/sbin/init  -run_init_process()
             				|---->init_linuxrc

内核移植

	移植流程

Rootfs根文件系统

根文件系统制作

	实验十一  文件系统的移植
【实验目的】
	熟悉Linux文件系统目录结构,创建自己的文件系统,通过NFS方式测试;用文件系统工具生成ramdisk文件系统映象文件。 
【实验环境】
1、ubuntu 12.04发行版
2、FS4412平台
3、交叉编译器 arm-none-linux-gnueabi-gcc
【实验步骤】
	一、根文件系统制作
1、	源码下载
我们选择的版本是busybox-1.22.1.tar.bz2下载路径为:
	http://busybox.net/downloads/
2、解压源码
$ tar  xvf  busybox-1.22.1.tar.bz2
3、进入源码目录
$ cd  busybox-1.22.1
4、配置源码
$ make menuconfig
Busybox Settings ---> 
		Build Options --->
			[*] Build BusyBox as a static binary (no shared libs)
			[ ] Force NOMMU build
			[ ] Build with Large File Support (for accessing files > 2 GB)
			(arm-none-linux-gnueabi-) Cross Compiler prefix
			() Additional CFLAGS
5、编译
$ make
6、安装
busybox默认安装路径为源码目录下的_install
$ make  install 
7、进入安装目录下
$ cd  _install
$ ls
bin  linuxrc  sbin  usr
8、创建其他需要的目录
$ mkdir  dev  etc  mnt  proc  var  tmp  sys  root 
9、添加库
Ø将工具链中的库拷贝到_install目录下
$ cp  /home/linux/toolchain/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/  .  -a
Ø修改文件权限并删除静态库和共享库文件中的符号表
$chmod  +w  lib
$chmod  +w  lib/*
$ rm  lib/*.a
$ arm-cortex_a8-linux-gnueabi-strip  lib/*
Ø删除不需要的库,确保所有库大小不超过8M
$ du  -mh   lib/
10、添加系统启动文件
在etc下添加文件inittab,文件内容如下:
#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
# start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# stuff to do when restarting the init process
::restart:/sbin/init
# stuff to do before rebooting
::ctrlaltdel:/sbin/reboot

在etc下添加文件fstab,文件内容如下:
#device     mount-point  	type     	options         dump     fsck order
proc      /proc       		proc     	defaults     		0     		0
tmpfs 	/tmp       		tmpfs    	defaults         	0          	0
sysfs     	/sys        		sysfs    	defaults        	0          	0
tmpfs  	/dev       		tmpfs    	defaults         	0          	0
	这里我们挂载的文件系统有三个proc、sysfs和tmpfs。在内核中proc和sysfs默认都支持,而tmpfs是没有支持的,我们需要添加tmpfs的支持
修改内核配置:
$ make menuconfig
File systems --->
		Pseudo filesystems ---> 
			[*] Virtual memory file system support (former shm fs)
			[*] Tmpfs POSIX Access Control Lists
重新编译内核
	
	在etc下创建init.d目录,并在init.d下创建rcS文件,rcS文件内容为:
#!/bin/sh
# This is the first script called by init process
/bin/mount  -a
echo  /sbin/mdev  >  /proc/sys/kernel/hotplug
/sbin/mdev  -s
	为rcS添加可执行权限:
$ chmod   +x  init.d/rcS

	在etc下添加profile文件,文件内容为:
#!/bin/sh
export HOSTNAME=farsight
export USER=root
export HOME=root
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH  LD_LIBRARY_PATH
重要:新制作的文件系统尺寸若超出8M,删除不需要的库文件
		根文件系统工作流程
			Rootfs (内核启动的最后一个阶段要挂载文件系统)
linuxrc调用inittab文件(规定操作系统行为文件),获取操作系统行为。

执行启动第一个脚本rcS,rcS中调用mount -a 挂载fstab中所有设备
当控制台登录的时候,执行bin/sh命令,进入shell命令行(在进入前,会执行profile,设置环境变量)

Bootloader --->kernel--->init  ---->挂在跟文件系统rootfs
   |---/etc/inittab  定义规则,要执行的操作
   |-----sysinit:/etc/init.d/rcS  挂载mount -a /etc/fstab     
   |						 mdev自动创建设备文件 
   |---->-/bin/sh 登陆shell (登陆之前设置profile)
   |------>profile做了三件事:
		  1定义了环境变量/bin/sbin 
			2 共享库
			3 shell命令行 ps提示
						|
                        |----->start  /sbin/init  开启第一个进程
                        |----->执行ctrlaltdel 重新启动/sbin/reboot

0x40008000  DRAM 前面是内存的基地址(根据不同的板子进行修改)
后面是指定的大小(不修改)

系统启动整体流程

   		目标板上电---->bootloader---->kernel---->rootfs---->shell

ramdisk文件系统制作

EXT2文件系统制作

通过NFS测试以后,就可以制作ramdisk文件系统了,具体如下:
1、制作一个大小为8M的镜像文件
$ cd  ~
$ dd  if=/dev/zero  of=ramdisk  bs=1k  count=8192 (ramdsik为8M)
2、格式化这个镜像文件为ext2
$ mkfs.ext2  -F  ramdisk
3、在mount下面创建initrd目录作为挂载点
$ sudo  mkdir  /mnt/initrd
4、将这个磁盘镜像文件挂载到/mnt/initrd下
注意这里的ramdisk不能存放在rootfs目录中
$ sudo  mount  -t  ext2   ramdisk  /mnt/initrd
5、将测试好的文件系统里的内容全部拷贝到 /mnt/initrd目录下面
$ sudo  cp  /source/rootfs/*   /mnt/initrd  –a
6、卸载/mnt/initrd
$ sudo  umount  /mnt/initrd
7、压缩ramdisk为ramdisk.gz
$ gzip  --best  -c  ramdisk  >  ramdisk.gz
8、格式化为uboot识别的格式并拷贝到/tftpboot下
$ mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip  -d ramdisk.gz  ramdisk.img
$ cp  ramdisk.img  /tftpboot
9、配置内核支持RAMDISK
制作完 initrd.img.gz后,需要配置内核支持RAMDISK作为启动文件系统
make menuconfig
    File systems  --->
	    <*> Second extended fs support
		    Device Drivers
			    SCSI device support  --->
			    <*> SCSI disk support
			    Block devices  --->
    <*>RAM  block  device  support   
(16)Default number of RAM disks  
(8192) Default RAM disk size (kbytes)   (修改为8M) 
General setup  --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

重新编译内核,复制到/tftpboot
10、在U-BOOT命令行重新设置启动参数:
# setenv bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-fs4412.dtb\;tftp 43000000  ramdisk.img\;bootm 41000000 43000000 42000000
# saveenv
重新启动开发板查看能否正常启动

EXT4文件系统制作

2、修改u-boot启动参数
#setenv bootargs root=/dev/nfs rw nfsroot=192.168.9.120:/source/rootfs init=/linuxrc console=ttySAC2,115200 ip=192.168.9.233
# setenv bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-fs4412.dtb\; bootm 41000000  -  42000000
#saveenv
注意:192.168.9.120 对应Ubuntu的ip
192.168.9.233 对应板子的ip 
这两个ip应该根据自己的实际情况适当修改	
3、分区
启动开发板在倒计时期间按任意键结束启动,执行如下命令
# fdisk  -c  0

4、格式化
重新启动开发板进入linux系统后执行
# mkfs.ext2  -F  /dev/mmcblk0p2 
5、修改我们/source/rootfs/etc/fstab
在最后添加如下内容
/dev/mmcblk0p2  /mnt         ext2    defaults       0             0
重新启动系统系统在启动最后会挂载mmcblk0p2 作为用户文件系统

你可能感兴趣的:(创客学院知识巩固)