***********************准备工作***************************
1, 硬件平台:S3C6410
软件平台:Fedora14/16 + arm-linux-gcc 4.2.2-eabi
2,下载linux-3.6.5.tar.bz2,解压源码到目录 urdir (你选择要放的目录,下同)
3,添加yaffs文件系统所需的准备。(独立完整的过程请参考:http://blog.csdn.net/cocoxiaomei/article/details/8498161)
1)下载源代码命令:git clonegit://www.aleph1.co.uk/yaffs2(@qingwu:一般在终端下都有git支持)
也可以在windows下用git工具下载(这里请注意:windows下的文件可能会出现回车换行的错误,比如^M不能识别等,可以参考:
http://blog.csdn.net/cocoxiaomei/article/details/8497929
2)yaffs源代码下载完后,进入yaffs2源代码目录,执行:#./patch-kernel.sh c m ../linux-3.6.5(其中c:复制代码 ,m:使用支持多版本代码)
因为我们选择的系统为mini6410,因此接下来的修改以及配置都是在此基础上的。
************************内核源码文件修改*******************************
4,进入解压后的内核源码目录 ,修改Makefile文件。
line 195 ARCH ?= $(SUBARCH) 改为:ARCH ?= arm
line 196 CROSS_COMPILE ?= 改为:CROSS_COMPILE = arm-linux-
前者是对体系架构的定义,我们是arm平台。后者是交叉编译工具的选择。修改完成后保存退出。
5,执行 make s3c6400_defconfig,Makefile能够针对S3C6410做一系列默认配置
注:这个命令可能会出错,说没有s3c6410_defoncig的信息,如下:*** Can't find default configuration"arch/arm/configs/s3c6410_defconfig"!
这时可以执行:
[root@localhostlinux-3.6.5]#cp arch/arm/configs/s3c6400_defconfig .config,然后再运行:
[root@localhost linux-3.6.5]# make s3c6400_defconfig 。【注:这里我用的s3c6400,因为目录下只有6400跟6410最近。】
6,修改flash分区信息(line121 of mach-mini6410.c)
[root@localhost linux-3.6.5]# vim arch/arm/mach-s3c64xx/mach-mini6410.c
结构体 mtd_partition mini6410_nand_part[]保存了nand flash的分区信息,修改如下:
static structmtd_partition mini6410_nand_part[] = {
[0] = {
.name = "uboot",
.size = SZ_1M,
.offset = 0,
},
[1] = {
.name ="kernel",
.size = SZ_2M,
.offset = SZ_1M,
},
[2] = {
.name ="rootfs",
.size = SZ_1M * 0x30,
.offset = SZ_1M + SZ_2M,
},
[3] = {
.name ="file_system",
.size =MTDPART_SIZ_FULL,
.offset = SZ_1M * 0x33,
},
};
修改之后分区情况就如下表所示:
表3-1 NAND FLASH分区表
*******************************内核配置界面************************************
在内核源码目录执行:make menuconfig,进入内核配置界面(如图):
插播:我在fedora16下运行这一步,报错如下:
*** Unable to find the ncurses libraries or the
*** required header files.
*** 'make menuconfig' requires the ncurses libraries.
*** Install ncurses (ncurses-devel) and try again.
解决办法:yum install ncurses-devel,安装完之后 make menuconfig,就能进入正常配置界面了。
接下来按照自上而下的顺序进行配置
******************************内核配置过程*************************************
1,System Type:
有很多板级相关的配置选项,可以根据自己的需要选择合适的系统,这里我选择mini6410。
注意:S3C64XXDMA下只能选一个,多选可能会出现板级直接的兼容问题。
2,Device Drivers
2.1)<*> Memory Technology Device (MTD) support:
Caching block device access to MTD devices选项在mtdblock会用到。
进入NAND Device Support下,选择 N
对于一些大的整数,由于计算机本身能够显示的内置数据类型精度有限,在处理一些比较大的整数运算时就不能适用。因此需要考虑用一些结构来辅助运算。一种典型的方式就是通过数组的方式来保存这些大整数。然后通过模拟手工运算的逐位运算。下面对整数的加法和乘法做一个总结。
加法: 位相加的关系:笼统的来说,加法中数组的每一个元素都对应着整数的每一位。当两个数相加的时候,要把前面的进位和当前的和相加,然后根据结果来进行进位。如果仔细考虑的话,会发现有如下的情况存在:
假设有两个数组a[], b[], 和进位标志carryBit.
如果a[i] + b[i] + carryBit > 当前的数制,则carryBit要置位,相加的结果要减去当前的数制。
比如a[i] = 5, b[i] = 7, carryBit = 1。考虑10进制的情况。则相加的结果为13. 那么根据讨论,后面一位的进位标志为1, 当前的结果为13 - 10 = 3.
如果对上一步的讨论做进一步的提炼,我们会发现他们的运算实际上满足这么一个关系:
当前位的求和结果 = (a[i] + b[i] + carryBit) % 10,
下一位的进位标志(carryBit) = (a[i] + b[i] + carryBit) % 10
对于更加通用的数制运算,我们可以发现有同样对应的关系:
当前位的求和结果 = (a[i] + b[i] + carryBit) % 数制,
下一位的进位标志(carryBit) = (a[i] + b[i] + carryBit) % 数制。
数据的表示:在前面的逻辑关系理请之后,剩下的就是如何保存对应的数据了。一般我们展示的数字比如:12345,一般都是高位在前面,低位在后面。而在进行数组的加法运算的时候,需要从低位到高位,那么在数组中的保存方式比较合理的方式应该为int[] a = {5, 4, 3, 2, 1}.这样,当两个数组相加的时候,我们只要从数组的开头遍历就可以了。同时,因为我们保存数据的顺序和显示数据的顺序是相反的,如果后续需要显示对应的数字的话,则需要倒序输出。
另外,两个数字相加之后,保存相加结果的数组长度必须要加1,这样才能保证有足够的空间将结果保存下来。
实现:有了前面的讨论,我们就可以很容易实现如下的方法:
public static int[] genericPlus(int[] a, int[] b, int numberSystem) { int[] c = new int[a.length + 1]; int carryBit = 0; for(int i = 0; i < a.length; i++) { c[i] = (a[i] + b[i] + carryBit) % numberSystem; carryBit = (a[i] + b[i] + carryBit) / numberSystem; } c[a.length] = carryBit; return c; }乘法:
有了前面加法讨论的基础,再考虑乘法则相对方便一些了。我们在考虑一下原来乘法的思路。对于两个数组a[], b[],假定结果数组为c[]。我们对数组相乘的步骤一般如下:
1. 取b[]中的一个元素,和a[]相乘,得到一个a.length + 1长度的中间数组。
经过遍历b[],我们就得到b.length长度这么多个中间数组。
2. 对于这些中间数组,如果对应的是b[i]乘积的结果,则后面求和的时候将这个数组左移i位,然后和总结果数组c[]相加。
这样得到的结果就是乘积。对于两个数组相乘,其结果的长度为两个数组长度之和。
实现:经过前面的分析,我们可以得到如下的代码:
public static int[] arrayMultiply(int[] a, int[] b) { int[] c = new int[a.length + b.length]; for(int i = 0; i < b.length; i++) { // Generate a multiply result from b[i] * a int[] middleResult = new int[a.length + 1]; int carryBit = 0; for(int j = 0; j < a.length; j++) { middleResult[j] = (b[i] * a[j] + carryBit) % 10; carryBit = (b[i] * a[j] + carryBit) / 10; } middleResult[a.length] = carryBit; // Plus middle result to c carryBit = 0; for(int k = 0; k < middleResult.length; k++) { int sum = middleResult[k] + c[i + k] + carryBit; c[i + k] = sum % 10; carryBit = sum / 10; } } return c; }注:前面这种实现只是针对10进制的方式。如果需要换成更加通用的方式,可以将10换成传进来的进制参数。当然函数签名也要做相应的修改。
另外,这种写法只是一个比较粗略的写法,从可读性的角度来说完全可以将生成中间结果数组和将中间结果数组加到最终结果数组的两部分分成两个方法。
总结:
这里主要讨论了大整数的加法和乘法,对于减法来说,思路也很近似,相信看过这个之后大家也该知道怎么做了。这种问题本身不是很难,只是如果要在很短的时间内理清思路并不出问题,确实还是有点挑战性。前面kissinger同学曾经在这个问题上栽了,在此聊表慰问一下吧:)。
已有 0 人发表留言,猛击->>这里<<-参与讨论
ITeye推荐
- —软件人才免语言低担保 赴美带薪读研!—
package com.juck.test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class Base64Code{ //测试主方法 public static void main(String[] args){ final String fileName = "示例文件"; final String fileSuffix = ".jpg"; final String url = "XXXXXXX";//文件路径 try{ String base64Code=encoderToBase64Code(url); base64CodeToFile(base64Code,"D:\\BASE64编码字符串"+fileName+".txt"); decoderToBase64Code(base64Code,"D:\\解码"+fileName+fileSuffix); }catch(Exception e){ e.printStackTrace(); } } //文件转换程BASE64编码 public static String encoderToBase64Code(String path)throws IOException{ File file = new File(path); FileInputStream input = new FileInputStream(file); byte[] buffer = new byte[(int)file.length()]; input.read(buffer); input.close(); System.out.print(new BASE64Encoder().encode(buffer));//打印文件经过编码后的字符串 return new BASE64Encoder().encode(buffer); } //BASE64字符串解码并保存文件 public static void decoderToBase64Code(String base64Code,String targetPath) throws IOException{ byte[] buffer = new BASE64Decoder().decodeBuffer(base64Code); FileOutputStream out = new FileOutputStream(targetPath); out.write(buffer); out.close(); //BASE64字符串保存成文本 public static void base64CodeToFile(String base64Code,String targetPath) throws IOException{ byte[] buffer = base64Code.getBytes(); FileOutputStream out = new FileOutputStream(targetPath); out.write(buffer); out.close(); } } }
http://juck.iteye.com
已有 0 人发表留言,猛击->>这里<<-参与讨论
ITeye推荐
- —软件人才免语言低担保 赴美带薪读研!—