链接脚本:arch/arm/kernel/vmlinux.lds
1.内核运行的一个文件(汇编)
/arch/arm/kernel/head.S:ENTRY(stext)
bl __lookup_processor_type 检查配置编译好的内核是否支持此处理器
bl __lookup_machine_type 检查配置编译好的内核是否支持此硬件平台
bl __create_page_tables 内核在开启mmu(用虚拟地址)之前,
需要先创建页表(虚拟地址和物理地址之前的转化关系)
ldr r13, __switch_data @ address to jump to after (保存要跳转的地址)
@ mmu has been enabled
adr lr, BSYM(__enable_mmu) @ return (PIC) address (开mmu)
ARM( add pc, r10, #PROCINFO_INITFUNC ) (初始化处理器核心)
__switch_data:.word __mmap_switched:
__mmap_switched: 保存地址信息, 初始化8k 栈空间, 清bss段 跳转到C
b start_kernel
2. 内核启动(C语言) init/main.c
start_kernel()
|- setup_arch(&command_line); 初始化硬件平台
|- 内核各种机制的初始化
|- rest_init(); 开启kernel_init()线程
|- kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
|- 初始化设备 挂载根文件系统 开启用户空间第一个进程 init_post();
3. 内核启动的最后阶段,开启用户第一个进程(init进程)
init_post();
if (execute_command) {
853 run_init_process(execute_command);
854 printk(KERN_WARNING "Failed to execute %s. Attempting "
855 "defaults...\n", execute_command);
856 }
857 run_init_process("/sbin/init");
858 run_init_process("/etc/init");
859 run_init_process("/bin/init");
860 run_init_process("/bin/sh");
这一段代码最后都会指向 busybox的应用,busybox里集成了包括init进程
sh等系统级应用。
源码可在http://busybox.net/downloads/ 获取
vim arch/arm/mach-s5pc100/mach-smdkc100.c
2、添加需要的头文件#if defined (CONFIG_DM9000)
#include <linux/dm9000.h>
#include <linux/irq.h>
#endif
3、平台设备的添加/* DM9000 Support */
#if defined(CONFIG_DM9000)
static struct resource dm9000_resources[] = {
[0] = {
.start = 0x88000000,
.end = 0x88000000 + 0x3,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0x88000000 + 0x4,
.end = 0x88000000 + 0x4 +0x3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT(10),
.end = IRQ_EINT(10),
.flags = IORESOURCE_IRQ | IRQ_TYPE_LEVEL_HIGH,
},
};
static struct dm9000_plat_data s5pc100_dm9000_platdata = {
.flags = DM9000_PLATF_16BITONLY,
.dev_addr[0] = 0x00,
.dev_addr[1] = 0x00,
.dev_addr[2] = 0x3e,
.dev_addr[3] = 0x26,
.dev_addr[4] = 0x0a,
.dev_addr[5] = 0x00,
};
static struct platform_device s5pc100_device_dm9000 = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(dm9000_resources),
.resource = dm9000_resources,
.dev = {
.platform_data = & s5pc100_dm9000_platdata,
}
};
#endif
4、平台设备列表的添加:在smdkc100_device[]结构体数组中添加如下内容:
#if defined(CONFIG_DM9000)
&s5pc100_device_dm9000,
#endif$ make menuconfig
[*] Networking support (NEW) --->
Networking options --->
<*> Packet socket
<*> Unix domain sockets
[*] TCP/IP networking
[*] IP: multicasting
[*] IP: kernel level autoconfiguration
[*] IP: BOOTP support
Device Drivers --->
[*] Network device support --->
[*] Ethernet (10 or 100Mbit) --->
<*> DM9000 support
File systems --->
[*] Network File Systems --->
<*> NFS client suppor
[*] NFS client support for NFS version 3
[*] NFS client support for the NFSv3 ACL protocol extension
[*] Root file system on NFS$ make zImage
$ cp arch/arm/boot/zImage /tftpboot
7、启动开发板,修改内核启动参数,通过NFS方式挂载根文件系统我们选择的版本是busybox-1.17.3.tar.bz2下载路径为:http://busybox.net/downloads/
$ tar xvf busybox-1.17.3.tar.bz2
$ cd busybox-1.17.3
$ 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-cortex_a8-linux-gnueabi-) Cross Compiler prefix
() Additional CFLAGS
$ make
busybox默认安装路径为源码目录下的_install
$ make install
$ cd _install
$ ls
bin linuxrc sbin usr
$ mkdir dev etc mnt proc var tmp sys root
将工具链中的库拷贝到_install目录下
$ cp /home/linux/toolchain/arm-none-linux-gnueabi/libc/lib ./ -a
删除_install/lib下的所有目录、.o文件和.a文件
对库进行瘦身以减小文件系统的大小
$ arm-none-linux-gnueabi-strip lib/*
10.1、在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
10.2、在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的支持。
修改内核配置:
File systems --->
Pseudo filesystems --->
[*] Virtual memory file system support (former shm fs)
[*] Tmpfs POSIX Access Control Lists
重新编译内核
10.3、在etc下创建init.d目录,并在init.d下创建rcS文件,rcS文件内容为:
#!/bin/sh
# This is the first script called by init process
/bin/mount -a
mdev –s //挂载dev下所有节点文件
为rcS添加可执行权限:
$ chmod +x init.d/rcS
10.4、在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
根文件系统中有一个设备节点是必须的,在dev下创建console节点
$ mknod dev/console c 5 1
重要:若新制作的文件系统尺寸若超出8M,则需删除不需要的库文件。12.1、备份/source/rootfs
$ sudo mv /source/rootfs /source/rootfs_bak
12.2、将我们新建的根文件系统拷贝到/source目录下
$ sudo cp _install /source/rootfs –a
12.3、设置uboot环境变量
# setenv bootcmd tftp 20008000 zImage\; go 20008000
# setenv bootargs root=nfs nfsroot=192.168.1.100:/source/rootfs init=/linuxrc console=ttySAC0,115200 ip=192.168.1.200
# saveenv
13、重新启动开发板,查看是否能够正常挂载,功能是否正常14.1、cramfs文件系统镜像制作
由于系统提供制作cramfs文件系统的工具,可以直接使用。具体操作如下;
$ mkfs.cramfs /source/rootfs rootfs.cramfs
14.2、将rootfs.cramfs拷贝到/tftpboot目录下
$ sudo cp rootfs.cramfs /tftpboot
14.3、将rootfs.cramfs烧写到nand flash的第三个分区上
u-boot下执行如下命令
# tftp 20008000 rootfs.cramfs
# nand erase 400000 400000
# nand write 20008000 400000 400000
14.4、重新设置u-boot启动参数
# setenv bootcmd tftp 20008000 zImage\; go 20008000
# setenv bootargs root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200
# saveenv
14.5、启动开发板,测试是否成功。
[root@farsight /root] # ls /
bin etc linuxrc sbin tmp var
dev lib mnt proc test usr
[root@farsight /root] # mkdir test
mkdir: Cannot create directory `test': Read-only file system
注意:cramfs格式的文件系统是只读的此同时。另外还可以制作: