国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
ARM的嵌入式Linux移植體驗(yàn)之操作系統(tǒng)

 嵌入式操作系統(tǒng)并不總是必須的,因?yàn)槌绦蛲耆梢栽诼惆迳线\(yùn)行。盡管如此,但對于復(fù)雜的系統(tǒng),為使其具有任務(wù)管理、定時器管理、存儲器管理、資 源管理、事件管理、系統(tǒng)管理、消息管理、隊(duì)列管理和中斷處理的能力,提供多任務(wù)處理,更好的分配系統(tǒng)資源的功能,很有必要針對特定的硬件平臺和實(shí)際應(yīng)用移 植操作系統(tǒng)。鑒于Linux的源代碼開放性,它成為嵌入式操作系統(tǒng)領(lǐng)域的很好選擇。國內(nèi)外許多知名大學(xué)、公司、研究機(jī)構(gòu)都加入了嵌入式Linux的研究行 列,推出了一些著名的版本:

  ·RT-Linux提供了一個精巧的實(shí)時內(nèi)核,把標(biāo)準(zhǔn)的Linux核心作為實(shí)時核心的一個進(jìn)程同用戶的實(shí)時進(jìn)程一起調(diào)度。RT-Linux已成 功地應(yīng)用于航天飛機(jī)的空間數(shù)據(jù)采集、科學(xué)儀器測控和電影特技圖像處理等廣泛的應(yīng)用領(lǐng)域。如NASA(美國國家宇航局)將裝有 RT-Linux的設(shè)備放在飛機(jī)上,以測量Georage咫風(fēng)的風(fēng)速;
  ·uCLinuxMicro-Control-Linux,u表示MicroC表示Control)去掉了MMU(內(nèi)存管理)功能,應(yīng)用于沒有虛擬內(nèi)存管理的微處理器/微控制器,它已經(jīng)被成功地移植到了很多平臺上。

  本章涉及的mizi-linux由韓國mizi公司根據(jù)Linux 2.4內(nèi)核移植而來,支持S3C2410A處理器。

  1.Linux內(nèi)核要點(diǎn)

  和其他操作系統(tǒng)一樣,Linux包含進(jìn)程調(diào)度與進(jìn)程間通信(IPC)、內(nèi)存管理(MMU)、虛擬文件系統(tǒng)(VFS)、網(wǎng)絡(luò)接口等。

<!--[endif]-->

  Linux內(nèi)核源代碼包括多個目錄:

 ?。?span lang="EN-US">1arch:包括硬件特定的內(nèi)核代碼,如arm、mipsi386等;
  (2drivers:包含硬件驅(qū)動代碼,如char、cdrom、scsi、mtd等;
 ?。?span lang="EN-US">3)include:通用頭文件及針對不同平臺特定的頭文件,如asm-i386、asm-arm等;
 ?。?span lang="EN-US">4)init:內(nèi)核初始化代碼;
 ?。?span lang="EN-US">5)ipc:進(jìn)程間通信代碼;
 ?。?span lang="EN-US">6)kernel:內(nèi)核核心代碼;
 ?。?span lang="EN-US">7)mm:內(nèi)存管理代碼;
 ?。?span lang="EN-US">8)net:與網(wǎng)絡(luò)協(xié)議棧相關(guān)的代碼,如ipv4、ipv6ethernet等;
  (9fs:文件系統(tǒng)相關(guān)代碼,如nfs、vfat等;
 ?。?span lang="EN-US">10)lib:庫文件,與平臺無關(guān)的strlen、strcpy等,如在string.c中包含:

char * strcpy(char * dest,const char *src)
{
  char *tmp = dest;
  while ((*dest++ = *src++) != ‘\0‘)
  /* nothing */;
  return tmp;
}

 ?。?span lang="EN-US">11Documentation:文檔

Linux內(nèi)核的實(shí)現(xiàn)中,有一些數(shù)據(jù)結(jié)構(gòu)使用非常頻繁,對研讀內(nèi)核的人來說至為關(guān)鍵,它們是:

  1.task_struct

   Linux內(nèi)核利用task_struct數(shù)據(jù)結(jié)構(gòu)代表一個進(jìn)程,用task_struct指針形成一個task數(shù)組。當(dāng)建立新進(jìn)程的時候,Linux 為新的進(jìn)程分配一個task_struct結(jié)構(gòu),然后將指針保存在task數(shù)組中。調(diào)度程序維護(hù)current指針,它指向當(dāng)前正在運(yùn)行的進(jìn)程。

  2.mm_struct

  每個進(jìn)程的虛擬內(nèi)存由mm_struct結(jié)構(gòu)代表。該結(jié)構(gòu)中包含了一組指向vm-area_struct結(jié)構(gòu)的指針,vm-area_struct結(jié)構(gòu)描述了虛擬內(nèi)存的一個區(qū)域。

  3.inode

  Linux虛擬文件系統(tǒng)中的文件、目錄等均由對應(yīng)的索引節(jié)點(diǎn)(inode)代表。

  2.Linux移植項(xiàng)目

  mizi-linux已經(jīng)根據(jù)Linux 2.4內(nèi)核針對S3C2410A這一芯片進(jìn)行了有針對性的移植工作,包括:

 ?。?span lang="EN-US">1
)修改根目錄下的Makefile文件

  a.指定目標(biāo)平臺為ARM

#ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
ARCH := arm

  b.指定交叉編譯器:

CROSS_COMPILE = arm-linux-

 ?。?span lang="EN-US">2
)修改arch目錄中的文件

  根據(jù)本章第一節(jié)可知,Linuxarch目錄存放硬件相關(guān)的內(nèi)核代碼,因此,在Linux內(nèi)核中增加對S3C2410的支持,最主要就是要修改arch目錄中的文件。

  a.arch/arm/Makefile文件中加入:

ifeq ($(CONFIG_ARCH_S3C2410),y)
TEXTADDR = 0xC0008000
MACHINE = s3c2410
Endif

  b.arch\arm\config.in文件中加入:

if [ "$CONFIG_ARCH_S3C2410" = "y" ]; then
comment ‘S3C2410 Implementation‘
dep_bool ‘ SMDK (MERI TECH BOARD)‘ CONFIG_S3C2410_SMDK $CONFIG_ARCH_S3C2410
dep_bool ‘ change AIJI‘ CONFIG_SMDK_AIJI
dep_tristate ‘S3C2410 USB function support‘ CONFIG_S3C2410_USB $CONFIG_ARCH_S3C2100
dep_tristate ‘ Support for S3C2410 USB character device emulation‘ CONFIG_S3C2410_USB_CHAR $CONFIG_S3C2410_USB
fi # /* CONFIG_ARCH_S3C2410 */

  arch\arm\config.in文件還有幾處針對S3C2410的修改。

  c.arch/arm/boot/Makefile文件中加入:

ifeq ($(CONFIG_ARCH_S3C2410),y)
ZTEXTADDR = 0x30008000
ZRELADDR = 0x30008000
endif

d.linux/arch/arm/boot/compressed/Makefile文件中加入:

ifeq ($(CONFIG_ARCH_S3C2410),y)
OBJS += head-s3c2410.o
endif

  加入的結(jié)果是head-s3c2410.S文件被編譯為head-s3c2410.o。

  e.加入arch\arm\boot\compressed\ head-s3c2410.S文件

#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/mach-types.h>

.section ".start", #alloc, #execinstr

__S3C2410_start:

@ Preserve r8/r7 i.e. kernel entry values
@ What is it?
@ Nandy

@ Data cache, Intstruction cache, MMU might be active.
@ Be sure to flush kernel binary out of the cache,
@ whatever state it is, before it is turned off.
@ This is done by fetching through currently executed
@ memory to be sure we hit the same cache

bic r2, pc, #0x1f
add r3, r2, #0x4000 @ 16 kb is quite enough...
1: ldr r0, [r2], #32
teq r2, r3
bne 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches

#if 0
@ disabling MMU and caches
mrc p15, 0, r0, c1, c0, 0 @ read control register
bic r0, r0, #0x05 @ disable D cache and MMU
bic r0, r0, #1000 @ disable I cache
mcr p15, 0, r0, c1, c0, 0
#endif

/*
* Pause for a short time so that we give enough time
* for the host to start a terminal up.
*/
mov r0, #0x00200000
1: subs r0, r0, #1
bne 1b

  該文件中的匯編代碼完成S3C2410特定硬件相關(guān)的初始化。

  f.arch\arm\def-configs目錄中增加配置文件

  g.arch\arm\kernel\Makefile中增加對S3C2410的支持

no-irq-arch := $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
$(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
$(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \
$(CONFIG_ARCH_S3C2400) $(CONFIG_ARCH_S3C2410) \
$(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_PXA)
obj-$(CONFIG_MIZI) += event.o
obj-$(CONFIG_APM) += apm2.o

h.修改arch/arm/kernel/debug-armv.S文件,在適當(dāng)?shù)奈恢迷黾尤缦玛P(guān)于S3C2410的代碼:

#elif defined(CONFIG_ARCH_S3C2410)

.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled ?
moveq \rx, #0x50000000 @ physical base address
movne \rx, #0xf0000000 @ virtual address
.endm

.macro senduart,rd,rx
str \rd, [\rx, #0x20] @ UTXH
.endm

.macro waituart,rd,rx
.endm

.macro busyuart,rd,rx
1001: ldr \rd, [\rx, #0x10] @ read UTRSTAT
tst \rd, #1 << 2 @ TX_EMPTY ?
beq 1001b
.endm

  i.修改arch/arm/kernel/setup.c文件

  此文件中的setup_arch非常關(guān)鍵,用來完成與體系結(jié)構(gòu)相關(guān)的初始化:

void __init setup_arch(char **cmdline_p)
{
struct tag *tags = NULL;
struct machine_desc *mdesc;
char *from = default_command_line;

ROOT_DEV = MKDEV(0, 255);

setup_processor();
mdesc = setup_machine(machine_arch_type);
machine_name = mdesc->name;

if (mdesc->soft_reboot)
reboot_setup("s");

if (mdesc->param_offset)
tags = phys_to_virt(mdesc->param_offset);

/*
* Do the machine-specific fixups before we parse the
* parameters or tags.
*/
if (mdesc->fixup)
mdesc->fixup(mdesc, (struct param_struct *)tags,
&from, &meminfo);

/*
* If we have the old style parameters, convert them to
* a tag list before.
*/
if (tags && tags->hdr.tag != ATAG_CORE)
convert_to_tag_list((struct param_struct *)tags,
meminfo.nr_banks == 0);

if (tags && tags->hdr.tag == ATAG_CORE)
parse_tags(tags);

if (meminfo.nr_banks == 0) {
meminfo.nr_banks = 1;
meminfo.bank[0].start = PHYS_OFFSET;
meminfo.bank[0].size = MEM_SIZE;
}

init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;

memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = ‘\0‘;
parse_cmdline(&meminfo, cmdline_p, from);
bootmem_init(&meminfo);
paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);

/*
* Set up various architecture-specific pointers
*/
init_arch_irq = mdesc->init_irq;

#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
#endif
#endif
}

  j.修改arch/arm/mm/mm-armv.c文件(arch/arm/mm/目錄中的文件完成與ARM相關(guān)的MMU處理)

  修改

init_maps->bufferable = 0;

  為

init_maps->bufferable = 1;

  要輕而易舉地進(jìn)行上述馬拉松式的內(nèi)核移植工作并非一件輕松的事情,需要對Linux內(nèi)核有很好的掌握,同時掌握硬件特定的知識和相關(guān)的匯編。幸 而mizi公司的開發(fā)者們已經(jīng)合力為我們完成了上述工作,這使得小弟們在將mizi-linux移植到自身開發(fā)的電路板的過程中只需要關(guān)心如下幾點(diǎn):

  (1)內(nèi)核初始化:Linux內(nèi)核的入口點(diǎn)是start_kernel()函數(shù)。它初始化內(nèi)核的其他部分,包括捕獲,IRQ通道,調(diào)度,設(shè)備驅(qū)動,標(biāo)定延遲循環(huán),最重要的是能夠fork"init"進(jìn)程,以啟動整個多任務(wù)環(huán)境。

  我們可以在init中加上一些特定的內(nèi)容。

  (2)設(shè)備驅(qū)動:設(shè)備驅(qū)動占據(jù)了Linux內(nèi)核很大部分。同其他操作系統(tǒng)一樣,設(shè)備驅(qū)動為它們所控制的硬件設(shè)備和操作系統(tǒng)提供接口。

  本文第四章將單獨(dú)講解驅(qū)動程序的編寫方法。

   (3)文件系統(tǒng):Linux最重要的特性之一就是對多種文件系統(tǒng)的支持。這種特性使得Linux很容易地同其他操作系統(tǒng)共存。文件系統(tǒng)的概念使得用戶能 夠查看存儲設(shè)備上的文件和路徑而無須考慮實(shí)際物理設(shè)備的文件系統(tǒng)類型。Linux透明的支持許多不同的文件系統(tǒng),將各種安裝的文件和文件系統(tǒng)以一個完整的 虛擬文件系統(tǒng)的形式呈現(xiàn)給用戶。

  我們可以在K9S1208 NAND FLASH上移植cramfs、jfss2、yaffsFLASH文件系統(tǒng)。

  3. init進(jìn)程

  在init函數(shù)中"加料",可以使得Linux啟動的時候做點(diǎn)什么,例如廣州友善之臂公司的demo板在其中加入了公司信息:

static int init(void * unused)
{
lock_kernel();
do_basic_setup();

prepare_namespace();

/*
* Ok, we have completed the initial bootup, and
* we‘re essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff..
*/
free_initmem();
unlock_kernel();

if (open("/dev/console", O_RDWR, 0) < 0)
printk("Warning: unable to open an initial console.\n");

(void) dup(0);
(void) dup(0);

/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/

printk("========================================\n");
printk("= Friendly-ARM Tech. Ltd. =\n");
printk("= http://www.arm9.net =\n");
printk("= http://www.arm9.com.cn =\n");
printk("========================================\n");

if (execute_command)
execve(execute_command,argv_init,envp_init);
execve("/sbin/init",argv_init,envp_init);
execve("/etc/init",argv_init,envp_init);
execve("/bin/init",argv_init,envp_init);
execve("/bin/sh",argv_init,envp_init);
panic("No init found. Try passing init= option to kernel.");
}

  這樣在Linux的啟動過程中,會額外地輸出:

========================================
= Friendly-ARM Tech. Ltd. =
= http://www.arm9.net =
= http://www.arm9.com.cn =
========================================

  4.文件系統(tǒng)移植

  文件系統(tǒng)是基于被劃分的存儲設(shè)備上的邏輯上單位上的一種定義文件的命名、存儲、組織及取出的方法。如果一個Linux沒有根文件系統(tǒng),它是不能被正確的啟動的。因此,我們需要為Linux創(chuàng)建根文件系統(tǒng),我們將其創(chuàng)建在K9S1208 NAND FLASH上。

  Linux的根文件系統(tǒng)可能包括如下目錄(或更多的目錄):

 ?。?span lang="EN-US">1/bin (binary):包含著所有的標(biāo)準(zhǔn)命令和應(yīng)用程序;
 ?。?span lang="EN-US">2)/dev (device):包含外設(shè)的文件接口,在Linux下,文件和設(shè)備采用同種地方法訪問的,系統(tǒng)上的每個設(shè)備都在/dev里有一個對應(yīng)的設(shè)備文件;
 ?。?span lang="EN-US">3)/etc (etcetera):這個目錄包含著系統(tǒng)設(shè)置文件和其他的系統(tǒng)文件,例如/etc/fstab(file system table)記錄了啟動時要mount filesystem
 ?。?span lang="EN-US">4)/home:存放用戶主目錄;
  (5/lib(library):存放系統(tǒng)最基本的庫文件;

6/mnt:用戶臨時掛載文件系統(tǒng)的地方;
 ?。?span lang="EN-US">7
/proclinux提供的一個虛擬系統(tǒng),系統(tǒng)啟動時在內(nèi)存中產(chǎn)生,用戶可以直接通過訪問這些文件來獲得系統(tǒng)信息;
 ?。?span lang="EN-US">8)/root:超級用戶主目錄;
 ?。?span lang="EN-US">9)/sbin:這個目錄存放著系統(tǒng)管理程序,如fsck、mount等;
 ?。?span lang="EN-US">10)/tmp(temporary):存放不同的程序執(zhí)行時產(chǎn)生的臨時文件;
 ?。?span lang="EN-US">11)/usr(user):存放用戶應(yīng)用程序和文件。

  采用BusyBox是縮小根文件系統(tǒng)的好辦法,因?yàn)槠渲刑峁┝讼到y(tǒng)的許多基本指令但是其體積很小。眾所周知,瑞士軍刀以其小巧輕便、功能眾多而聞名世界,成為各國軍人的必備工具,并廣泛應(yīng)用于民間,而BusyBox也被稱為嵌入式Linux領(lǐng)域的"瑞士軍刀"。

  此地址可以下載BusyBoxhttp://www.busybox.net,當(dāng)前最新版本為1.1.3。編譯好busybox后,將其放入/bin目錄,若要使用其中的命令,只需要建立link,如:

ln -s ./busybox ls
ln -s ./busybox mkdir

  4.1 cramfs

  在根文件系統(tǒng)中,為保護(hù)系統(tǒng)的基本設(shè)置不被更改,可以采用cramfs格式,它是一種只讀的閃存文件系統(tǒng)。制作cramfs文件系統(tǒng)的方法為:建立一個目錄,將需要放到文件系統(tǒng)的文件copy到這個目錄,運(yùn)行"mkcramfs 目錄名 image"就可以生成一個cramfs文件系統(tǒng)的image文件。例如如果目錄名為rootfs,則正確的命令為:

mkcramfs rootfs rootfs.ramfs

  我們使用下面的命令可以mount生成的rootfs.ramfs文件,并查看其中的內(nèi)容:

mount -o loop -t cramfs rootfs.ramfs /mount/point

  此地址可以下載mkcramfs工具:http://sourceforge.net/projects/cramfs/。

  4.2 jfss2

  對于cramfs閃存文件系統(tǒng),如果沒有ramfs的支持則只能讀,而采用jfss2The Journalling Flash File System version 2)文件系統(tǒng)則可以直接在閃存中讀、寫數(shù)據(jù)。jfss2 是一個日志結(jié)構(gòu)(log-structured)的文件系統(tǒng),包含數(shù)據(jù)和原數(shù)據(jù)(meta-data)的節(jié)點(diǎn)在閃存上順序地存儲。jfss2記錄了每個擦 寫塊的擦寫次數(shù),當(dāng)閃存上各個擦寫塊的擦寫次數(shù)的差距超過某個預(yù)定的閥值,開始進(jìn)行磨損平衡的調(diào)整。調(diào)整的策略是,在垃圾回收時將擦寫次數(shù)小的擦寫塊上的數(shù)據(jù)遷移到擦寫次數(shù)大的擦寫塊上以達(dá)到磨損平衡的目的。

  與mkcramfs類似,同樣有一個mkfs.jffs2工具可以將一個目錄制作為jffs2文件系統(tǒng)。假設(shè)把/bin目錄制作為jffs2文件系統(tǒng),需要運(yùn)行的命令為:

mkfs.jffs2 -d /bin -o jffs2.img

  4.3 yaffs

  yaffs 是一種專門為嵌入式系統(tǒng)中常用的閃存設(shè)備設(shè)計的一種可讀寫的文件系統(tǒng),它比jffs2 文件系統(tǒng)具有更快的啟動速度,對閃存使用壽命有更好的保護(hù)機(jī)制。為使Linux支持yaffs文件系統(tǒng),我們需要將其對應(yīng)的驅(qū)動加入到內(nèi)核中 fs/yaffs/,并修改內(nèi)核配置文件。使用我們使用mkyaffs工具可以將NAND FLASH中的分區(qū)格式化為yaffs格式(如/bin/mkyaffs /dev/mtdblock/0命令可以將第1MTD塊設(shè)備分區(qū)格式化為yaffs),而使用mkyaffsimage(類似于mkcramfs、 mkfs.jffs2)則可以將某目錄生成為yaffs文件系統(tǒng)鏡像。

  嵌入式Linux還可以使用NFS(網(wǎng)絡(luò)文件系統(tǒng))通過以太網(wǎng)掛接根文件系統(tǒng),這是一種經(jīng)常用來作為調(diào)試使用的文件系統(tǒng)啟動方式。通過網(wǎng)絡(luò)掛接的根文件系統(tǒng),可以在主機(jī)上生成ARM 交叉編譯版本的目標(biāo)文件或二進(jìn)制可執(zhí)行文件,然后就可以直接裝載或執(zhí)行它,而不用頻繁地寫入flash。

  采用不同的文件系統(tǒng)啟動時,要注意通過第二章介紹的BootLoader修改啟動參數(shù),如廣州友善之臂的demo提供如下三種啟動方式:

  (1)從cramfs掛接根文件系統(tǒng):root=/dev/bon/2();  
 ?。?span lang="EN-US">2
)從移植的yaffs掛接根文件系統(tǒng):root=/dev/mtdblock/0
 ?。?span lang="EN-US">3)從以太網(wǎng)掛接根文件系統(tǒng):root=/dev/nfs。

  5.小結(jié)

  本章介紹了嵌入式Linux的背景、移植項(xiàng)目、init進(jìn)程修改和文件系統(tǒng)移植,通過這些步驟,我們可以在嵌入式系統(tǒng)上啟動一個基本的Linux。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
樹莓派上為內(nèi)核添加系統(tǒng)調(diào)用
4. Linux2.6.14內(nèi)核編譯、移植 (含LCD移植)
新內(nèi)核移植示例
Linux內(nèi)核配置、編譯及Makefile簡述
Linux2.6.34.2在TQ6410上的移植詳解
linux-2.6內(nèi)核移植
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服