① linux.asm
计算机语言有后缀名吗?
常见的编程语言源文件后缀名
众所周知,编程语言源文件的后缀名可以帮助我们快速的判断其是哪种语言,从而选择合适的编译器,方便我们后期的学习和操作。
在介绍编程语言源文件后缀名之前,我们先把编程语言分个类:常见的分类为机器语言(由二进制码0和1构成)、汇编语言、高级语言三个。还可以将其分为编译语言(典型的有C、C++、Go、Swift、object-c以及汇编等)和解释性语言(Javascript、python、php、perl、Ruby等)以及混合性语言(Java和C#等)
机器语言
首先我们要明白,机器语言和后缀名没有必然联系;其次,机器语言一般不需要编译和解释,对一般的单片机或嵌入式CPU,机器语言的后缀名一般为.bin(直接的二进制文件)或.hex(16进制文本),对操作系统来说,机器语言就是可执行文件,在windows系统中,典型的是.exe.dll.com.sys等,而在linux系统中机器语言一般没有后缀,因为在Linux中,带有扩展名的文件,只能代表程序的关联,并不能说明文件是可以执行,从这方面来说,Linux的机器语言扩展名没有太大的意义。
简述BootLoader的功能和启动过程?
作用原理
编辑
⒈BootLoader所支持的CPU和嵌入式板
每种不同的CPU体系结构都有不同的BootLoader。有些BootLoader也支持多种体系结构的CPU,比如U-Boot就同时支持ARM体系结构和MIPS体系结构。除了依赖于CPU的体系结构外,BootLoader实际上也依赖于具体的嵌入式板级设备的配置。这也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种CPU而构建的,要想让运行在一块板子上的BootLoader程序也能运行在另一块板子上,通常也都需要修改BootLoader的源程序。
⒉BootLoader的安装媒介(InstallationMedium)
系统加电或复位后,所有的CPU通常都从某个由CPU制造商预先安排的地址上取指令。比如,基于ARM7TDMIcore的CPU在复位时通常都从地址0x00000000取它的第一条指令。而基于CPU构建的嵌入式系统通常都有某种类型的固态存储设备(比如:ROM、EEPROM或FLASH等)被映射到这个预先安排的地址上。因此在系统加电后,CPU将首先执行BootLoader程序。
⒊用来控制BootLoader的设备或机制
主机和目标机之间一般通过串口建立连接,BootLoader软件在执行时通常会通过串口来进行输入、输出,比如:输出打印信息到串口,从串口读取用户控制字符等。
⒋BootLoader的启动过程
BootLoader的启动过程可分为单阶段(Single-Stage)和多阶段(Multi-Stage)两种。通常多阶段的BootLoader具有更复杂的功能,更好的可移植性。从固态存储设备上启动的BootLoader大多采用两阶段,即启动过程可以分为stage1和stage2:stage1完成初始化硬件,为stage2准备内存空间,并将stage2复制到内存中,设置堆栈,然后跳转到stage2。
⒌BootLoader的操作模式(OperationMode)
大多数BootLoader都包含两种不同的操作模式。启动加载模式和下载模式。
(1)启动加载(Bootloading)模式:这种模式也称为“自主”模式,也即BootLoader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。这种模式是BootLoader的正常工作模式。
(2)下载(Downloading)模式:在这种模式下目标机上的BootLoader将通过串口连接或网络连接等通信手段从主机下载文件。从主机下载的文件通常首先被BootLoader保存到目标机的RAM中然后再被BootLoader写到目标机上的固态存储设备中。
⒍BootLoader与主机之间进行文件传输所用的通信设备及协议
分为两种情况。一种是目标机使用串口与主机相连。这时的传输协议通常是xmodem/ymodem/zmodem中的一种。第二种可以用网络连接的方式传输文件,这时使用的协议多为tftp。
解析
编辑
网上关于Linux的BOOTLOADER文章不少了,但是大都是vivi,blob等比较庞大的程序,读起来不太方便,编译出的文件也比较大,而且更多的是面向开发用的引导代码,做成产品时还要裁减,这一定程度影响了开发速度,对初学者学习开销也比较大,在此分析一种简单的BOOTLOADER,是在三星公司提供的2410BOOTLOADER上稍微修改后的结果,编译出来的文件大小不超过4k,希望对大家有所帮助.
重要概念
压缩后的KERNEL,按照文档资料,现在不提倡使用DECOMPRESSEDKERNEL,而要使用COMPRESSEDKERNEL,它包括了解压器.因此要在ram分配时给压缩和解压的KERNEL提供足够空间,这样它们不会相互覆盖.
当执行指令跳转到COMPRESSEDKERNEL后,解压器就开始工作,如果解压器探测到解压的代码会覆盖掉COMPRESSEDKERNEL,那它会直接跳到COMPRESSEDKERNEL后存放数据,并且重新定位KERNEL,所以如果没有足够空间,就会出错.
Jffs2FileSystem
可以使armlinux应用中产生的数据保存在FLASH上,我的板子还没用到这个.
RAMDISK
使用RAMDISK可以使ROOTFILESYSTEM在没有其他设备的情况下启动.一般有两种加载方式,最常用的一种是,把COMPRESSEDRAMDISKIMAGE放到指定地址,然后由BOOTLOADER把这个地址通过启动参数的方式ATAG_INITRD2传递给KERNEL.具体看代码分析.
启动参数(摘自IBMdeveloper)
在调用内核之前,应该作一步准备工作,即:设置Linux内核的启动参数。Linux2.4.x以后的内核都期望以标记列表(taggedlist)的形式来传递启动参数。启动参数标记列表以标记ATAG_CORE开始,以标记ATAG_NONE结束。每个标记由标识被传递参数的tag_header结构以及随后的参数值数据结构来组成。数据结构tag和tag_header定义在Linux内核源码的include/asm/setup.h头文件中.
在嵌入式Linux系统中,通常需要由BOOTLOADER设置的常见启动参数有:ATAG_CORE、ATAG_MEM、ATAG_CMDLINE、ATAG_RAMDISK、ATAG_INITRD等。
(注)参数也可以用COMMANDLINE来设定,在我的BOOTLOADER里,我两种都用了.
开发环境
CPU:S3C2410,BANK6上有64M的SDRAM(两块),BANK0上有32MNORFLASH,串口当然是逃不掉的.这样,按照数据手册,地址分配如下:
0x4000_0000开始是4k的片内DRAM.
0x0000_0000开始是32MFLASH16bit宽度
0x3000_0000开始是64MSDRAM32bit宽度
注意:控制寄存器中的BANK6和BANK7部分必须相同.
0x4000_0000(片内DRAM)存放4k以内的BOOTLOADERIMAGE
0x3000_0100开始存放启动参数
0x3120_0000存放COMPRESSEDKERNELIMAGE
0x3200_0000存放COMPRESSEDRAMDISK
0x3000_8000指定为
0x3040_0000指定为
开发环境:RedhatLinux,armgcctoolchain,armlinuxKERNEL
如何建立armgcc的编译环境:建议使用toolchain,而不要自己去编译armgcc,偶试过好多次,都以失败告终.
先下载arm-gcc3.3.2toolchain
将arm-linux-gcc-3.3.2.tar.bz2解压到/toolchain
tarjxvfarm-linux-gcc-3.3.2.tar.bz2
mv/usr/local/arm/3.3.2/toolchain
在makefile中在把arch=armCROSS_COMPILE设置成toolchain的路径
还有就是INCLUDE=-I../include-I/root/my/usr/local/arm/3.3.2/include.,否则库函数就不能用了
启动方式
可以放在FLASH里启动,或者用Jtag仿真器.由于使用NORFLASH,根据2410的手册,片内的4KDRAM在不需要设置便可以直接使用,而其他存储器必须先初始化,比如告诉memorycontroller,BANK6里有两块SDRAM,数据宽度是32bit,==.否则memorycontrol会按照复位后的默认值来处理存储器.这样读写就会产生错误.
所以第一步,通过仿真器把执行代码放到0x4000_0000,(在编译的时候,设定TEXT_BAS
E=0x40000000)
第二步,通过AxD把linuxKERNELIMAGE放到目标地址(SDRAM)中,等待调用
第三步,执行BOOTLOADER代码,从串口得到调试数据,引导armlinux
代码分析
讲了那么多执行的步骤,是想让大家对启动有个大概印象,接着就是BOOTLOADER内部的代码分析了,BOOTLOADER文章内容网上很多,我这里精简了下,删除了不必要的功能.
BOOTLOADER一般分为2部分,汇编部分和c语言部分,汇编部分执行简单的硬件初始化,C部分负责复制数据,设置启动参数,串口通信等功能.
BOOTLOADER的生命周期:
⒈初始化硬件,比如设置UART(至少设置一个),检测存储器==.
⒉设置启动参数,这是为了告诉内核硬件的信息,比如用哪个启动界面,波特率==.
⒊跳转到LinuxKERNEL的首地址.
⒋消亡
同时在linux中GRUB(GRandUnifiedBootloader)是一个系统默认自带的多重启动管理器。它可以在多个操作系统共存时选择引导哪个系统。尽管引导操作系统看上去是件平凡且琐碎的任务,但它实际上很重要。如果引导装入器不能很好地完成工作或者不具有弹性,那么就可能锁住系统或者无法引导计算机??
如何编写驱动程序?
代码:#includelinux/mole.h>#includelinux/kernel.h>#includeasm/io.h>#includelinux/miscdevice.h>#includelinux/fs.h>#includeasm/uaccess.h>//流水灯代码#defineGPM4CON0x110002e0#*ledcon=NULL;staticunsignedlong*leddat=NULL;//自定义write文件操作(不自定义的话,内核有默认的一套文件操作函数)staticssize_ttest_write(structfile*filp,constchar__user*buff,size_tcount,loff_t*offset){intvalue=0;intret=0;ret=_from_user(value,buff,4);//底层驱动只定义基本操作动作,不定义功能if(value==1){*leddat|=0x0f;*leddat=0xfe;}if(value==2){*leddat|=0x0f;*leddat=0xfd;}if(value==3){*leddat|=0x0f;*leddat=0xfb;}if(value==4){*leddat|=0x0f;*leddat=0xf7;}return0;}//文件操作结构体初始化staticstructfile_operationsg_tfops={.owner=THIS_MODULE,.write=test_write,};//杂设备信息结构体初始化staticstructmiscdeviceg_tmisc={.minor=MISC_DYNAMIC_MINOR,.name="test_led",.fops=g_tfops,};//驱动入口函数杂设备初始化staticint__inittest_misc_init(void){//IO地址空间映射到内核的虚拟地址空间ledcon=ioremap(GPM4CON,4);leddat=ioremap(GPM4DAT,4);//初始化led*ledcon=0xffff0000;*ledcon|=0x00001111;*leddat|=0x0f;//杂设备注册函数misc_register(g_tmisc);return0;}//驱动出口函数staticvoid__exittest_misc_exit(void){//释放地址映射iounmap(ledcon);iounmap(leddat);}//指定模块的出入口函数mole_init(test_misc_init);mole_exit(test_misc_exit);MODULE_LICENSE("GPL");(1)linuxswift语言扩展阅读:include用法:#include命令预处理命令的一种,预处理命令可以将别的源代码内容插入到所指定的位置;可以标识出只有在特定条件下才会被编译的某一段程序代码;可以定义类似标识符功能的宏,在编译时,预处理器会用别的文本取代该宏。插入头文件的内容#include命令告诉预处理器将指定头文件的内容插入到预处理器命令的相应位置。有两种方式可以指定插入头文件:1、#include文件名>2、#include"文件名"如果需要包含标准库头文件或者实现版本所提供的头文件,应该使用第一种格式。如下例所示:#includemath.h>//一些数学函数的原型,以及相关的类型和宏如果需要包含针对程序所开发的源文件,则应该使用第二种格式。采用#include命令所插入的文件,通常文件扩展名是
.h
,文件包括函数原型、宏定义和类型定义。只要使用#include命令,这些定义就可被任何源文件使用。如下例所示:#include"myproject.h"//用在当前项目中的函数原型、类型定义和宏你可以在#include命令中使用宏。如果使用宏,该宏的取代结果必须确保生成正确的#include命令。例1展示了这样的#include命令。【例1】在#include命令中的宏#ifdef_DEBUG_#defineMY_HEADER"myProject_dbg.h"#else#defineMY_HEADER"myProject.h"#endif#includeMY_HEADER当上述程序代码进入预处理时,如果_DEBUG_宏已被定义,那么预处理器会插入myProject_dbg.h
的内容;如果还没定义,则插入myProject.h
的内容。② 澶у︾敓鍑犲ぇ缂栫▼璇瑷浣犻兘浼氩摢鍑犵嶏纻
6澶х紪绋嬭瑷浣犻兘浼氩摢鍑犵?
涓銆乧璇瑷
C璇瑷璇炵敓浜1972骞达纴鍙浠ョО涔嬩负鐜颁唬楂樼骇璇瑷镄勯蓟绁栵纴鐢辫宪钖岖殑璐濆皵瀹为獙瀹ゅ彂鏄庛侰璇瑷鏄浜轰滑杩芥眰缁撴瀯鍖栵纴妯″潡鍖栵纴楂樻晥鐜囩殑钬滆瑷涔嬭姳钬濄傚湪搴曞眰缂栫▼锛屾瘆濡傚祵鍏ュ纺锛岀梾姣掑紑鍙戠瓑搴旂敤锛屽彲浠ユ浛浠f眹缂栬瑷𨱒ュ紑鍙戠郴缁熺▼搴忥纴鍦ㄩ珮灞傚簲鐢锛屼篃鍙浠ュ紑鍙戜粠镎崭綔绯荤粺(UNIX/LINUX/WINDOWS閮藉熀浜嶤璇瑷寮鍙) 鍒板悇绉嶅簲鐢ㄨ蒋浠躲
浜孋++璇瑷
浣滀负C璇瑷镄勬墿灞曪纴c++鏄璐濆皵瀹为獙瀹や簬80骞翠唬鎺ㄥ嚭镄勚俢++鏄涓绉嶆贩钖堣瑷锛屾棦鍙浠ュ疄鐜伴溃钖戝硅薄缂栫▼锛屼篃鍙浠ュ紑鍙愠璇瑷闱㈠悜杩囩▼椋庢牸镄勭▼搴忋侰璇瑷璁╃▼搴忓憳绗涓娆″彲浠ラ氲繃缁撴瀯鍖栫殑鐞嗗康缂栧啓鍑烘槗浜庣悊瑙g殑澶嶆潅绋嫔簭锛涘敖绠C璇瑷鏄涓涓浼熷ぇ镄勮瑷锛屼絾鏄绋嫔簭镄勪唬镰侀噺杈惧埌30000琛屼互涓婃椂.绋嫔簭锻桦氨涓嶈兘寰埚ソ镄勪粠镐讳綋涓婃妸鎻″拰鎺у埗杩欎釜绋嫔簭銆傚洜姝.鍦80骞翠唬鍒濇湡锛屽緢澶氲蒋浠堕”鐩閮介溃涓存棤娉曡В鍐崇殑闂棰樿屼笉鑳介‘鍒╄繘琛屻1979骞.璐濆皵瀹为獙瀹ゅ彂鏄庝简Ct+銆俢t+链鍒濈殑钖嶅瓧鍙锅气滃甫绫荤殑c钬濓纴钖庢潵镓嶆敼钖嶅彨ct+銆傚浗鍐呴氱敤鍙娉曪细钬渃锷犲姞钬濆浗闄呴氱敤璇绘硶"CPLUSPLUS钬濄
涓夈丣AVA璇瑷
鐢辩编锲絊UN鍏鍙(琚玂RACLE鍏鍙告敹璐) 鍙戞槑浜1995骞达纴 鏄鐩鍓崭笟鐣屽簲鐢ㄦ渶骞挎硾锛屼娇鐢ㄤ汉鏁版渶澶氱殑璇瑷锛岃繛缁澶氩勾鎺掑悕涓栫晫绗涓锛 鍙浠ョО涔嬩负钬滆$畻链鸿瑷鐣岀殑鑻辫钬濄侸AVA骞挎硾搴旂敤浜庝紒涓氱骇杞浠跺紑鍙戯纴瀹夊崜绉诲姩寮鍙戯纴澶ф暟鎹浜戣$畻绛夐嗗烟.
鍑犱箮娑夊强涓佹墍链夎屼笟銆傚叧浜嶫AVA镄勫彂灞曞巻鍙插拰鐗规э纴 灏嗗湪钖庨溃涓挞棬浠嬬粛銆
锲涖丣AVA SC RIFT璇瑷
JAVASCRIPT鏄涓绉嶈剼链璇瑷锛 宸辩粡琚骞挎硾鐢ㄥ瓙WEB搴旂敤寮鍙戯绂搴旂敤锣冨浗瓒婃潵瓒婂ぇ锛岄吨瑕佹ц秺𨱒ヨ秺楂樸傜洰鍓.娴佽岀殑H5寮鍙戠殑镙稿绩鍏跺疄灏辨槸JAVASCRIPT璇瑷銆
浜旓纴PHP璇瑷
pHP铡熷嬩负PERSONAL HOMEPAGE镄勭缉鍐欙纴 宸辩粡姝e纺镟村悕
涓"PHP HYPERTEXT PREPROCESSOR"銆侾HP璇瑷锛 涓鑸鐢ㄤ簬WEB寮鍙戦嗗烟锛氩ぇ閲忕殑涓灏忓瀷缃戠珯浠ュ强镆愪簺澶у瀷缃戠珯浣跨敤PHP寮鍙戙
鍏銆丳YTHON璇瑷
PYTHON鍙戞槑浜1989骞达纴 璇娉旷粨鏋勭亩鍗曪纴 鏄揿︽槗镍傦绂PYTHON鍏锋湁涓板瘜鍜屽己澶х殑搴撱傚畠甯歌鏄电О涓鸿兑姘磋瑷锛岃兘澶熸妸鐢ㄥ叾浠栬瑷鍒朵綔镄勫悇绉嶆ā鍧(灏ゅ叾鏄痗lC++) 寰堣交𨱒惧湴镵旂粨鍦ㄤ竴璧枫侾VT HON骞挎硾搴旂敤浜庯细锲惧舰澶勭悊锛 绉戝﹁$畻锛 WEB缂栫▼锛 澶氩獟浣揿簲鐢锛 寮曟搸寮鍙戯绂 灏ゅ叾鏄鍦ㄦ湭𨱒ュぇ鐑鏂瑰悜链哄櫒瀛︿範鍜屼汉宸ユ櫤鑳戒笂链夐潪甯稿ぇ镄勬綔锷涖
涓僌BJECT-C鍜孲WIFT璇瑷
D BJECT-C阃氩父鍐欎綔OBJECTIVE-C鎴栬匫BJ-C鎴杘.鏄镙规嵁C璇瑷镓琛岖敓鍑烘潵镄勮瑷锛岀户镓夸简C璇瑷镄勭壒镐э纴鏄镓╁厖C镄勯溃闱㈠悜瀵硅薄缂栫▼璇瑷銆俹涓昏佺敤瀛愯娴鏋滆蒋浠剁殑寮鍙戙係WIFT.鑻规灉浜2014骞碬WDC(鑻规灉寮鍙戣呭ぇ浼) 鍙戝竷镄勬柊寮鍙戣瑷锛 鍙涓庡绩鍏卞悓杩愯屼簬MACOS鍜10s骞冲彴锛 鐢ㄤ簬鎼寤哄熀瀛愯娴鏋滃钩鍙扮殑搴旂敤绋嫔簭銆
鍏銆丆#(CSHARP) 璇瑷
#鏄寰杞鍏鍙稿彂甯幂殑涓绉嶉溃钖戝硅薄镄勶纴杩愯屼簬.NET FRAMEWORK涔嬩笂镄勯珮绾х▼搴忚捐¤瑷銆侰#鍦ㄥ熀浜嶹INDOWS镎崭綔绯荤粺镄勫簲鐢ㄥ紑鍙戣繖涓棰嗗烟鍦ㄥ彇浠c++.鍗犳嵁涓诲煎湴浣嶃傗沧垚涔熻惂浣曡触涔熻惂浣曗*C#镄勫井杞韬浠斤纴涔熸垚涓轰简鍙戝𪾢镄勯樆锷涳纴鍦ㄥ叾浠东棰嗗烟搴旂敤杈冨皯銆
③ 现在软件开发,一般都用什么语言啊,要怎么学
不难学,软件开发主要就是学习编程语言和逻辑架构,以及项目开发的实现,最主要的就是学习编程语言,一般入门都还是很简单的,主要还是要多实例练习。