长篇连载arm linux演艺序
滚滚长江东四水浪花淘净英雄
大家好许多人和我一样正在苦读linux源代码希望有照一日宝典在手天下我有小弟不才也读了两年写的几首歪诗从本级开始把我所理解的linux如何启动贴出来不懂之处大家讨论一番也希望把linux从头到尾讨论一遍计划写它回三年写完(笑)欢迎大家动员一些牛人来参与讨论提高人气增加流量
小弟用的是armT跑LINUX 下面是第一回
长篇连载arm linux演艺第一回
话说(嘘声入正题把!)
好好
首先porting linux的时候要规划内存影像如小弟的系统有m SDRAM
地址从x xbff ffffm flash地址从xc xdff ffff
规划如下bootloader linux kernel rootdisk放在flash里
具体从 xc 开始的第一个M放bootloader
xc 开始的m放linux kernel从 xc 开始都给rootdisk
启动
首先启动后armT将地址xc 映射到(可通过跳线设置)
实际上从xc 启动进入我们的bootloader但由于flash速度慢
所以bootloader前面有一小段程序把bootloader拷贝到SDRAM 中的xAFE
再从x 运行bootloader我们叫这段小程序为flashloader
flashloader必须要首先初始化SDRAM不然往那放那些东东
equ SOURCE xC bootloader的存放地址
equ TARGET xAFE 目标地址
equ SDCTL x SDRAM控制器寄存器
// size is stored in location xCFC
global _start
_start: //入口点
//;***************************************
//;* Init SDRAM
//;***************************************
// ;***************
// ;* SDRAM
// ;***************
LDR r =SDCTL //
// ; Set Precharge Command
LDR r =x
//ldr r=x
STR r [r]
// ; Issue Precharge All Commad
LDR r =x
LDR r [r]
// ; Set AutoRefresh Command
LDR r =xA
STR r [r]
// ; Issue AutoRefresh Command
LDR r =x
LDR r [r]
LDR r [r]
LDR r [r]
LDR r [r]
LDR r [r]
LDR r [r]
LDR r [r]
LDR r [r]
// ; Set Mode Register
LDR r =xB
STR r [r]
// ; Issue Mode Register Command
LDR r =x //; Mode Register Value
LDR r [r]
// ; Set Normal Mode
LDR r =x
STR r [r]
//;***************************************
//;* End of SDRAM and SyncFlash Init *
//;***************************************
// copy code from FLASH to SRAM
_CopyCodes:
ldr r=SOURCE
ldr r=TARGET
sub rr#
ldr r[r]
_CopyLoop:
ldr r[r]
str r[r]
add rr#
add rr#
sub rr#
teq r#
beq _EndCopy
b _CopyLoop
_EndCopy:
ldr r=TARGET
mov pcr
欲知后事如何下回分解
长篇连载arm linux演艺第二回
上回书说到flashloader把bootloader load到xAFE 然回跳了过去
其实xAFE 就是烧在flash xC中的真正的bootloader:
bootloader 有几个文件组成先是STARTs也是唯一的一个汇编程序其余的都是C写成的STARTs主要初始化堆栈
_start:
ldr r=StackInit
ldr sp[r]
b main
//此处我们跳到了C代码的main函数当C代码执行完后还要调用
//下面的JumpToKernelx跳到LINXU kernel运行
equ StackInitValue __end_data+x // K __end_data在连结脚本中指定
StackInit:
long StackInitValue
global JumpToKernel
JumpToKernel:
// jump to the copy code (get the arguments right)
mov pc r
global JumpToKernelx
// r = jump address
// rr = arguments to use (these get shifted)
JumpToKernelx:
// jump to the copy code (get the arguments right)
mov r r
mov r r
mov r r
mov r r
mov r r
mov pc r
section databoot
section bssboot
欲知bootloader中的c代码如何运行请看下集
长篇连载arm linux演艺第三回
书接上回
下面让我们看看bootloader的c代码干了些什么main函数比较长让我们分段慢慢看
int main()
{
U *pSource *pDestin count;
U countDown bootOption;
U delayCount;
U fileSize i;
char c;
char *pCmdLine;
char *pMem;
init(); //初始化FLASH控制器和CPU时钟
EUARTinit(); //串口初始化
EUARTputString(\n\nDBMX Linux Bootloader ver \n);
EUARTputString(Copyright (C) Motorola Ltd\n\n);
EUARTputString((U *)cmdLine);
EUARTputString(\n\n);
EUARTputString(Press any key for alternate bootup options );
小弟的bootloader主要干这么几件事:init(); 初始化硬件打印一些信息和提供一些操作选项
Program bootloader image
Program kernel image
Program rootdisk image
Download kernel and boot from RAM
Download kernel and boot with ver x bootloader format
Boot a verx kernel
Boot with a different command line
也就是说可以在bootloader里选择重新下载kernelrootdisk并写入flash
下载的方法是用usb连接m的rootdisk也就刷的一下关于usb下载的讨论请参看先前的贴子为arm开发平台增加usb下载接口
如果不选直接回车就开始把整个linux的内核拷贝到SDRAM中运行
列位看官可能有人要问在flashloader中不是已经初始化过sdram控制器了吗?怎么init(); 中还要初始化呢各位有所不知小弟用的是syncflash
可以直接使用sdram控制器的接口切记在flash中运行的代码是不能初始化连接flash的sdram控制器的不然绝对死掉了所以当程序在flash中运行的时候去初始化sdram而现在在sdram中运行可放心大胆地初始化flash了主要是设定字宽行列延时因为缺省都是最大的
另外如果列位看官的cpu有足够的片内ram完全可以先把bootloader放在片内ram干完一切后再跳到LINUX小弟着也是不得已而为之啊
今天太晚了回去睡觉了
长篇连载arm linux演艺第四回
如果直接输入回车进入kernel拷贝工作
EUARTputString(Copying kernel from Flash to RAM \n);
count = x; // Mbytes
pSource = (U *)xC;
pDestin = (U *)x;
do
{
*(pDestin++) = *(pSource++);
count = ;
} while (count > );
}
EUARTputString(Booting kernel \n\n);
这一段没有什么可说的运行完后kernel就在x了至于为什么要
空出x的一段主要是放kelnel的一些全局数据结构如内核页表arm的页目录要有k大
我们知道linux内核启动的时候可以传入参数如在PC上如果使用LILO
当出现LILO我们可以输入root=/dev/hda或mem=M等指定文件系统的设备或内存大小在嵌入式系统上参数的传入是要靠bootloader完成的
pMem = (char *)xFF; //参数字符串的目标存放地址
pCmdLine = (char *)&cmdLine; //定义的静态字符串
while ((*(pMem++)=*(pCm