复习
1. uboot 启动流程
1. 链接脚本 三个功能
指定入口 _start
指定链接地址
指定链接顺序
.lds
2. uboot 启动流程
第一阶段: 汇编阶段
1. 设置SVC模式,
2. 关中断,关看门狗,设置中断向量表
3. 关cache, mmu
4. 初始化时钟,内存,
5. 完成自搬移
6. 初始化C语言运行环境 (栈sp,bss段)
第二阶段: C语言阶段
1. 完成大部分硬件初始化
串口,i2c, mmc, net,
等大部分硬件初始化
2. 进入 3 2 1 倒计时
3. 读取bootcmd环境变量,
进入自启动模式
2. uboot 自定义命令
3. linux 的作用
1. 多任务调度功能
2. 网络协议
3. 文件系统管理
4. 内存管理
5. 硬件驱动管理
4. 配置菜单语法
5. 将 .c 编译进入 uImage
将 .c 编译出 uImage 生成 .ko
***********************************
[1]、核模块 ko 插入,卸载 insmod rmmod
modinfo 查看模块信息
insmod 插入一个内核模块
rmmod 卸载一个内核
lsmod 列出有哪些内核模块
模块化哪些好处
1. 在linux内核运行时, 插入,或者移除
2. 减小 uImage 大小, 节省 flash 大小,
3. 随时更新驱动
[2]、总结: Kconfig .config Makefile 文件之间的关系
1. make fs6818_defconfig
arch/arm/configs/fs6818_defconfig
2. 修改 Kconfig 写配置向, 保存退出,在 .config
生成 自己的配置项
3. make menuconfig
解析 Makefile 生成 图形化界面
[3]、内核的编译流程
见 vmlinux-Image-piggy.gzip-vmlinux-zImage-uImage.txt
[4]、内核的启动流程
1. uboot 获取 uImage 打印 64字节的 头信息
得到 zImage
2. 执行 zImage 中的自解压代码
得到 Image
3. 开始运行 linux kernel
1.找到 链接脚本
通过 make uImage V=1
ld -T arch/arm/kernel/vmlinux.lds 指定链接脚本
2. 通过链接脚本 找到 入口 符号 为 stext
arch/arm/kernel/vmlinux.lds:497 ENTRY(stext)
3. grep stext System.map
找到 符号对应的 链接地址
c0008000 T stext
4. arm-none-linux-gnueabi-addr2line -e vmlinux c0008000
找到 stext 所在行号
kernel-3.4.39/arch/arm/kernel/head.S:94
内核开始启动
1. 130 bl __create_page_tables
创建 内存 页表项, 为使能 mmu 做准备
2. 139 ldr r13, =__mmap_switched
给r13 赋值一个 符号地址
3. 146 1: b __enable_mmu
405 __enable_mmu:
431 b __turn_mmu_on
4. 457 mov r3, r13
458 mov pc, r3
5. 跳转到 __mmap_switched 开始运行
arch/arm/kernel/head-common.S:81
6. mov fp, #0 @ Clear BSS (and zero fp)
初始化 bss 段
7. 103 b start_kernel
开始进入C代码
8. init/main.c:466
开始执行 各种子系统初始化
1> 495 行 打印 linux banner
2> 524 mm_init();
内存管理 子系统 初始化
3> 531 sched_init();
进程调度 子系统 初始化
4> 548 init_IRQ();
中断管理
5> 639 rest_init();
369 kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
内核启动 第一个进程 PID 1
839 static int __init kernel_init(void * unused)
886 prepare_namespace()
init/do_mounts.c:555 mount_root();
挂载根文件系统 第一个 文件系统
895 init_post(); 执行第一个程序
826 run_init_process(execute_command);
830 run_init_process("/sbin/init");
831 run_init_process("/etc/init");
832 run_init_process("/bin/init");
833 run_init_process("/bin/sh");
ctags
[5]、内核的调试
1. 点灯法
2. addr2line
3. printk
[1]、什么是根文件系统
文件系统类型 SD卡 使用 fat32 emmc ext4 norflash jiffs
nfs
mount -t 指定文件系统类型 设备 挂载点 // 挂载文件系统
unmount 挂载点 // 解除挂载
1. 存放各种命令,库文件,脚本、配置文件等
2. 安装一些软件到根文件系统
3. 内核启动挂载的第一个文件系统
[2]、根文件系统层次结构标准 (FHS 标准)
1. 文件系统中每个区域的用途
2. 所需要的最小构成的文件和目录结构
[3]、根文件系统目录结构
bin : 使用系统的必要的命令,所有用户都可以使用
etc :软件的配置文件、 内核启动文件
lib :库文件, 标准C库,数学库等
mnt : 文件系统挂载点, 用于临时挂载文件系统,SD U盘
root : 超级用户的 工作目录
sys :虚拟文件系统 sysfs 的挂载点,主要用于管理设备驱动
usr :bin sbin 用户自己安装的软件,不是系统必要的
dev :设备节点文件, 一切设备皆文件
home :普通用户的家目录
linuxrc :内核运行的第一程序
proc :虚拟文件系统, 用于管理内核进程,获取内核进程状态等
sbin :用于管理内核系统的必要的命令程序,通常需要 sudo
tmp :存放临时文件, 标准建议系统启动时,就会清空此目录
var :软件(系统)的log 日志、软件的缓存
如何引导 zImage 启动
[4]、根文件系统的获取方式
bosybox
1. 官网
https://busybox.net/downloads/
2. 开发板厂商
[5]、使用busybox制作根文件系统 第一步 生成基本命令
1. 解压 tar -xvf busybox-1.22.1.tar.bz2
2. 配置交叉编译工具 打开 顶层 vi Makefile
164 CROSS_COMPILE ?=
164 CROSS_COMPILE ?= arm-none-linux-gnueabi-
190 ARCH ?= $(SUBARCH)
190 ARCH ?= arm
3. 配置 busybox
make menuconfig
1. 添加 insmod rmmod modinfo ...
Linux Module Utilities --->
[*] modinfo
[ ] Simplified modutils
[*] insmod
[*] rmmod
[*] lsmod
[*] Pretty output
[*] modprobe
[*] Blacklist support
[*] depmod
2. 配置工具生成到 那个目录
Busybox Settings --->
Installation Options ("make install" behavior) --->
(./_install) BusyBox installation prefix
3. 编译 busybox
make / make all -j4 V=1
make install
4. 清除 busybox
make clean
make mrproper
make distclean
make menuconfig O=../output
[6]、根文件系统制作 第二步 构建基础文件和目录
1. mkdir dev etc home lib mnt proc root sys tmp var -p
2. touch etc/inittab
gedit etc/inittab
#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
::respawn:-/bin/sh
# 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
::shutdown:/sbin/swapoff -a
3. mkdir etc/init.d/ -p
touch etc/init.d/rcS
gedit etc/init.d/rcS
#!/bin/sh
#This is the first script called by init process
/bin/mount -a
echo /sbin/mdev>/proc/sys/kernel/hotplug
mdev -s
4. touch etc/fstab
gedit 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
5. touch etc/profile
gedit etc/profile
#!/bin/sh
export HOSTNAME=farsight
export USER=root
export HOME=root
export PS1="[$USER@$HOSTNAME \W]\# "
#export PS1="[\[\033[01;32m\]$USER@\[\033[00m\]\[\033[01;34m\]$HOSTNAME\[\033[00m\ \W]\$ "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
6. 添加 动态库
0. 查看 命令 依赖的 库文件
arm-none-linux-gnueabi-readelf -d /bin/ls
1. cp /opt/gcc-4.5.1/arm-none-linux-gnueabi/libc/lib ~/roofs/lib -r
为了减少体积
2. 删除静态库
rm ~/roofs/lib/*.a
3. 剥离动态库的调试信息,符号表等等 du -h 查看文件大小 瘦身
arm-none-linux-gnueabi-strip *
[7]、通过 eMMC 挂载根文件系统
1. 通过 网络挂载 根文件系统
2. fdisk /dev/mmcblk0 分区命令
Command (m for help):
m 帮助信息
n 添加一下分区
p 打印分区表
d 删除分区表
w 写分区表 吧分区表 写到 block0
1. n
2. p p primary partition (1-4)
3. Partition number (1-4): 1
4. First cylinder (1-236032, default 1): 800
5. Last cylinder or +size or +sizeM or +sizeK (800-236032, default 236032): 236032
6. Command (m for help): w
7. mkfs.ext2 /dev/mmcblk0p1 // 格式化分区为 ext2 文件系统类型
8. mount -t ext2 /dev/mmcblk0p1 /mnt/ // 挂载文件系统到 /mnt
9. 拷贝 rootfs 根文件系统的 文件, 到 /mnt
10. umount /mnt // 解除挂载
11. 设置bootargs 启动参数
FS6818# set bootargs "root=/dev/mmcblk0p1 rw rootfstype=ext2 init=/linuxrc console=ttySAC0,115200 ip=192.168.1.100"
FS6818# set bootcmd "tftp 0x41000000 uImage; bootm 0x41000000"
12. 启动开发板 挂载成功
[8]、ramdisk 制作
1. 按照给的 Makefile 文件 制作 ramdisk.img
2. 修改内核配置
make menuconfig
Device Drivers --->
[*] Block devices --->
<*> RAM block device support
(16) Default number of RAM disks
(51200) Default RAM disk size (kbytes)
make uImage
cp arch/arm/boot/uImage ~/tftpboot
3. set bootcmd "tftp 0x41000000 uImage;tftp 0x42000000 ramdisk.img; bootm 0x41000000 0x42000000"
set bootargs "root=/dev/ram rw initrd=0x42000040,0x1000000 rootfstype=ext4 init=/linuxrc console=ttySAC0,115200"
[9]、通过 fatload 挂载根文件系统
[10]、产品系统部署
FS6818# mmc dev 0
FS6818# tftp 41000000 uImage
FS6818# mmc write 0x41000000 900 3000
FS6818# tftp 41000000 ramdisk.img
FS6818# mmc write 41000000 3900 1000
FS6818# set bootcmd "mmc dev 0;mmc read 0x41000000 900 3000;mmc read 0x42000000 3900 1000; bootm 0x41000000 0x42000000"