linux

位置:IT落伍者 >> linux >> 浏览文章

精彩arm linux演义


发布日期:2022年07月20日
 
精彩arm linux演义

长篇连载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 kernelxc 开始都给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               

上一篇:在Linux创建库函数(5)

下一篇:TurboLinux常见问题解答