boot对Linux内核的启动
程序员文章站
2024-03-26 08:34:35
...
boot:
读取kernel到内存
设置tag参数
kernel:
- 匹配机器id(从R1读出)能否支持该机器单板。调用开发板相关的初始化函数。不同的开发板有不同的板级外设,所以初始化内容就不同。
当启动内核时首先从环境变量中读取机器ID,如果没有就使用默认的机器ID。
2.读出R2的值(是boot设置的tag参数的首地址),并解析tag参数。
3.加载驱动程序。如:flash,emmc等。
4.挂接根文件系统。
5.运行应用程序。
启动第一个应用程序inittab,根据第一个应用程序的配置rcS脚本文件,在启动需要启动的相应的应用程序。
下载内核程序:
nfs 32000000 192.168.xxx.xxx:/path //通过nfs协议下载内核到32000000
bootm 32000000 启动在32000000的程序,也就是上一步下载到板子上的内核。
烧写根文件系统:
nfs
nand erase.part rootfs
nand write.jiffs2 30000000 260000 $filesize (filesize 是boot变量中得到的)
busybox:
ls bin/ -l
安装库:
进入工具链,查找库的路径,并将里面的动态库文件拷贝到目标板中。
在目标平台中建立一个文件目录:
mkdir yyyyyy/lib
cp xxx/lib/*so* yyyyyy/lib –d
BootLoader:
启动内核:把内核从flash读入内存然后启动。
1.能读flash
2.初始化内存,时钟,
启动:
- 设置参数
- 跳转执行
- 初始化硬件:看门狗,设置时钟,设置SDRAM,初始化nand flash
- 如果BootLoader比较大,从定位SDRAM
- 把内核从nand flash 读到SDRAM
- 设置要传给内核的参数
- 跳转到内核执行
#define S3C2440_MPLL_200MHZ ((0X5C << 12)|(0X01 << 4)|(0X02))
#define MEM_CTRL_BASE 0x48000000
#define SDRAM_BASE 0x30000000
.text
.global _start
_start
*关看门狗---将看门狗地址0x53000000设置为0
ldr r0, =0x53000000 ;寄存器r0=0x53000000
mov r1,#0 ;将寄存器r1赋值为0
str r1,[r0] ;将r1中的值0赋值给r0中的地址0x53000000
*设置时钟
ldr r0,=0x4c000014
mov r1,#0x03 ;时钟的分屏系数
str r1,[r0]
mrc p15, 0, r1, c1, c0, 0 ;读出控制寄存器
orr r1, r1, #0xc0000000 ;设置为异步模式
mcr p15, 0, r1, c1, c0, 0 ;写入控制寄存器
ldr r0, =0x4c000004
ldr r1, =S3C2440_MPLL_200MHZ
str r1,[r0]
*初始化sdram
ldr r0, =MEM_CTRL_BASE
adr r1, sdram_config ;读取sdram_config的当前地址
add r3, r0, #(13 *4)
1:
ldr r2, [r1] , #4
str r2, [r0], #4
cmp r0, r3
bne 1b
*从定位---把bootloader本身的代码从flash复制到它的链接地址
ldr sp, =0x34000000
mov r0, #0
bl copy_code_to_sdram
*执行main
ldr lr, =halt
ldr pc, =main
halt:
b halt
//bl main
sdram_config:
.long 0x22011110//bwscon
.long 0x00000700//bankcon0
.long 0x00000700//bankcon1
.long 0x00000700//bankcon2
.long 0x00000700//bankcon3
.long 0x00000700//bankcon4
.long 0x00000700//bankcon5
.long 0x00018005//bankcon6
.long 0x00018005//bankcon7
.long 0x008c04f4//refresh
.long 0x000000b1//banksize
.long 0x00000030//mrsrb6
.long 0x00000030//mrsrb7
int isBootFromNorFlash(void)
{
volatile int *p = (volatile int *)0;
int val;
val = *p;
*p = 0x1235678;
if( *p == 0x12345678)
{
*p = val;
return 0;//写成功,nand 启动
}
else
{
return 1;//nor 不能像内存一样写
}
}
int copy_code_to_sdram(unsigned int *src, unsigned int *dest, unsigned int len)
{
int i = 0;
if(isBootFromNorFlash())
{
while(i < len)
{
*dest[i] = *src[i];
i++;
}
}
else
{
nand_init();
nand_read();
}
}
void clean_bss(void)
{
extern int __bss_start, __bss_end;
int *p = &__bss_start;
for(; p < &__bss_end; p++)
*p = 0;
}
void nand_init(void)
{
}
推荐阅读
-
boot对Linux内核的启动
-
CentOS启动邮件服务很慢的问题 博客分类: linux linuxsendmail启动邮件服务太慢
-
linux下启动dbca或netmgr类的图形界面报错 博客分类: 数据库
-
一步步理解Linux进程(3)--内核中进程的实现
-
linux内核的 do{}while(0)语句
-
解决weblogic在Linux下启动慢和创建域慢的方法 博客分类: weblogic weblogiclinux
-
Linux升级内核的正确姿势
-
解决spring boot应用以docker容器方式启动后,进程ID是1而导致的jstack和jmap等命令不可用的问题 博客分类: dockersprng boot docker spring-boot
-
解决spring boot应用以docker容器方式启动后,进程ID是1而导致的jstack和jmap等命令不可用的问题 博客分类: dockersprng boot docker spring-boot
-
linux内核的tcp/ip调优