검색결과 리스트
OldPapers/linux 에 해당되는 글 37건
- 2008.02.26 GVim setting customization
- 2007.11.16 [ARM] Veneer code
- 2007.08.28 alignment, padding, packing (packed)
- 2006.06.30 ARM/Thumb Interworking and 'Unsupported call'
- 2006.06.21 Nand 자료
- 2006.06.20 NAND Flash Filesystem : YAFFS HOW-TO (2nd) 1
- 2006.02.06 vim color schema change
- 2005.11.09 ASCII Code
- 2005.11.09 C Standard Lib. 1
- 2005.11.09 ELF format
-----------------------------------------------------------------
"My Setting
source $VIMRUNTIME/../ephron_config.vim
source $VIMRUNTIME/../MyMapFunction.vim
source $VIMRUNTIME/../CustomFunction.vim
-----------------------------------------------------------------
2. ephron_config.vim
-----------------------------------------------------------------
set tags=./tags
set nu
set ci
set ai
set si
set sw=4
set ts=4
if has("gui_running")
set lines=50
set co=120
endif
"End of My Settings
"Customizing My Color Setting
colorscheme desert
"Customizing Plugin Setting
-----------------------------------------------------------------
3. CustomFunction.vim
-----------------------------------------------------------------
if version >= 500
func! GetTodayDate()
exe "read !date/t|sed 's/-//g'"
endfunc
endif
-----------------------------------------------------------------
4. myMapFuction.vim
-----------------------------------------------------------------
map <F1> v]#ezf
map <F2> v]}zf
map <F3> zo
map <F9> a// EPHRON_<Esc>:call GetTodayDate()<CR> + kkkJxA
"map <F11> :25vs ./<CR>:set nonumber<CR>^Ww
map <F11> :WMToggle<cr>
"방향키 설정
-----------------------------------------------------------------
Veneer에 대한 정의 입니다.
- The alignment of a nonpacked structure is the maximum alignment required by any of its fields. - ARM
- 구조체에서의 alignment 는 가장 큰 alignment에 맞추어진다.
이는 자동 padding 과 연계되어 실수를 하기 쉬운 부분이 된다.
struct
{
int a;
double b;
int c;
} TT;
TT의 sizeof 결과는 얼마일까? 답은 24이다.
왜냐하면 가장 큰 alignment 인 8 에 맞춰 남는 부분들이 padding 되기 때문이다.
padding
보통 우리가 아는 한에서는 4byte alignment 이다. 그리고 이보다 작을 경우에는 compiler 에서 자동 padding을 넣어준다. 이렇게 하는 이유는 performance 상의 이유이다. 메모리 접근시 유리하다.
packing 하기(packed 의 사용)
그러나 이러한 자동 padding 은 코드 호환성은 상당히 떨어진다.
왜냐하면 compiler 에 따라 자동 padding 하는 방식이 다를 수도 있기 때문이다. 그래서 performance를 떨어트리더라도 코드 호환성을 높이기 위해 자동 padding 을 하지 않게 된다.
즉, alignment 에 맞춰 padding을 넣지 않고 순수한 data가 차지하는 byte만을 메모리에 잡는다.
이렇게 하는 것을 packing 이라고 한다.
packing 하게 되면 기본적으로 alignment 를 1로 잡는다.
arm 계열
__packed 명령을 이용하여 packing 한다.
__align(n) 명령을 통해 특정 n byte 로 align이 가능하다.
gcc
__attribute__((packed))
__attribute__((align(n))) 과 같이 한다.
VC (MS 계열)
#pragma pack(push)
#pragma pack(4)
~~~~~~~~~
#pragma pack(pop)
VC 에서는 align 이 없고 pack 명령어를 통해 다 처리한다.
ARM/Thumb Interworking and 'Unsupported call'
Description
When building an ARM/Thumb Interworking Image, the linker may give messages like:
For SDT 2.50/2.51:
Error: Unsupported call from Thumb code to ARM symbol arm_sub in thumb.o(C$$code). For SDT 2.11a:
Warning: Unsupported call from Thumb code to ARM symbol arm_sub in thumb.o(C$$code). For SDT 2.11:
1 Thumb to ARM interworking calls generated, use '-info interwork' to listInterworking call from Thumb to ARM code symbol arm_sub in thumb.o(C$$code). Solution
These messages indicate that ARM-to-Thumb or Thumb-to-ARM interworking calls have been detected by the linker, but the called routines have not been compiled for interworking. The example above shows a call from the (Thumb) object module thumb.o to the routine arm_sub() in another module.
Even if the link appears to be successful, you should interpret such messages as being errors, because the image may not execute correctly.
For the case above, you should recompile/reassemble for interworking the (C/asm) module(s) containing arm_sub (let's call it FUNC).
If FUNC is a C file, you should recompile it using the option '-apcs /interwork'.
If FUNC is an assembler file, you should:
use the 'INTERWORK' area assembler attribute for these routines e.g. AREA func, CODE, READONLY, INTERWORK
check the called routine (arm_sub) use a BX LR instruction to return.
check the calling routine uses a BL instruction to call the routine arm_sub.
If the use of '-apcs /interwork' (for armcc & tcc) and 'INTERWORK' (for armasm & tasm) is applied consistently in your project, then the linker will generate the correct interworking veneers, and you will no longer see the message(s) above.
If the object file causing the error is supplied by a 3rd party vendor (e.g. an RTOS) which you do not have the source code for, then you may have to ask your supplier to provide suitably recompiled/reassembled object files.
For more details, see the SDT 2.11 User Guide, chapter 12, 'Interworking ARM and Thumb' or the SDT 2.50 User Guide, chapter 7, 'Interworking ARM and Thumb'.
글쓴이 : jazz0719 조회 : 3216 날짜 : 2004/06/30 16:40:51
% style % -->
오랫만에 글올리는군요. 다들 잘 지내셨어요?
저번엔 U-Boot에 NAND fusing 관련하여, MTD기반으로 연동하는 방법을 올렸었죠 ?
(공구보드 U-Boot소스. 2410-09-bluesky-u-boot-1.0.0.tar.gz도 살짝 보니까
이런방식이더군요.)
이번에 고도리님 등등과 자체프로젝트(^^?)를 추진하고 있는데, YAFFS작업이 있어서
이 기회에 cmd_nand.c의 JFFS지원 루틴을 분석하여, U-Boot에서 YAFFS 이미지 fusing도
지원하도록 수정해보았습니다.
질문올라온거 보면 yaffs image를 U-Boot의 nand write[.jffs2] 명령을 이용하여
fusing 시도하는 분이 계시던데, 절대 안될겁니다.(^---^).
YAFFS 이미지포맷이 JFFS2등 다른 이미지파일과 다르고, Spare Area(OOB)의 처리가
되어야 하기 때문입니다.
아래 찬찬히 읽어보시면 이해되실거예요.
(보드 specific 코드 - 형욱보드..로 표기)
- 장형욱 씀.
NAND Flash Filesystem : YAFFS
yaffs를 지원하도록 리눅스커널 설정
mtd driver 패치 설치
MTD(Memory Technology Devices)는 임베디드 디바이스에서 고형체 파일시스템(solid state filesystem)을구성하는데 사용하는 플래시 메모리, RAM, 그리고 그 비슷한 다른 칩셋 등 메모리 장치로 yaffs도 mtd를 통해 연결됨
mtd관련모듈을 yaffs를 지원하도록 최신 버전으로 패치(안할경우 fs/yaffs 컴파일시 에러 발생)
http://www.linux-mtd.infradead.org/에서 mtd-snapshot...tar.gz2 최신버전 다운로드
[mtd]/patch> sh patchin.sh -c -j [linux] : kernel mtd모듈 패치
-c : symbolic link를 만들지 않고 직접 커널소스로 mtd copy
-j : jffs2 지원
변경내용 : [linux]/drivers/mtd/, [linux]/include/linux/mtd/
NAND 관련 driver 코드 작성(형욱보드_nand.c)
falinux사이트에서 관련소스를 다운로드(http://www.falinux.com/download/data/kernel.zip)
[linux]/drivers/mtd/nand/ez_x5.c를 pwpro_nand.c로 바꾸고 아래와 같이 수정
: 하드웨어 관련 컨트롤 함수, IO 주소공간 지정, NAND 파티션 테이블 작성 등.
NAND 플래시 상 MTD 파티션 구분
Creating 3 MTD partitions on "NAND 16MiB 3,3V":
mtd0,mtdblock0 : 0x00004000-0x00190000 (1584K) : "Linux Kernel Partition"
mtd1,mtdblock1 : 0x00190000-0x00640000 (4800K) : "Root Filesystem(YAFFS) Partition"
mtd2,mtdblock2 : 0x00640000-0x00fa0000 (9600K) : "Configuration Partition"
소스
/*
* drivers/mtd/nand/형욱보드_nand.c
*
* Copyright (C) 2003 JANG, Hyung-Wook (jazz0719@dreamwiz.com)
*
* Support board : 형욱보드
*/
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
/* modified by hwjang. */
#include <asm-ppc/delay.h>
#include <asm-ppc/processor.h>
#define PWPRO_NAND_BASE 0xf0000000
#define PWPRO_NAND_BASE_D0 PWPRO_NAND_BASE
#define PWPRO_NAND_ACCESS_START (0x000) // not use
#define PWPRO_NAND_DATA (0x00000)
#define PWPRO_NAND_CMD (0x00001)
#define PWPRO_NAND_ADDR (0x00002)
#define PWPRO_NAND_ACCESS_END (0x300) // not use
#define NAND_MAXCHIP (1)
static struct mtd_info *pwpro_nand_mtd = NULL;
#define SZ_1K (1024)
#define SZ_1M (1024*1024)
#define __PWPRO_GPIO
/* modified by hwjang. add NAND Flash IO address mapping. */
#define FLASH_BASE_ADDR 0xF0000000
/*
#define FLASH_DATA_REG *(volatile unsigned char*)(FLASH_BASE_ADDR + 0x00000)
#define FLASH_CMD_REG *(volatile unsigned char*)(FLASH_BASE_ADDR + 0x00001)
#define FLASH_ADDR_REG *(volatile unsigned char*)(FLASH_BASE_ADDR + 0x00002)
#define FLASH_CS0_SET *(volatile unsigned char*)(FLASH_BASE_ADDR + 0x80000)
#define FLASH_CS0_CLR *(volatile unsigned char*)(FLASH_BASE_ADDR + 0xA0000)
*/
#define FLASH_DATA_REG (FLASH_BASE_ADDR + 0x00000)
#define FLASH_CMD_REG (FLASH_BASE_ADDR + 0x00001)
#define FLASH_ADDR_REG (FLASH_BASE_ADDR + 0x00002)
#define FLASH_CS0_SET (FLASH_BASE_ADDR + 0x80000)
#define FLASH_CS0_CLR (FLASH_BASE_ADDR + 0xA0000)
#if defined(__PWPRO_GPIO) /* Clocking and Chip Control */
#define DCRN_CPC0_CGCR0 0x0b1 /* Clock Generation Control Register 0 */
#define GPIO0_OR 0xEF600700
#define GPIO0_TCR 0xEF600704
#define GPIO0_ODR 0xEF600714
#define GPIO0_IR 0xEF60071C
#define GPIO_MASK_NAND_FLASH_MEM (1<<(31-15))
#define gpio_init() (*(volatile unsigned int*)GPIO0_TCR = 0x10000000)
#define gpio_read() (*(volatile unsigned int*)GPIO0_IR)
#define gpio_write(n) (*(volatile unsigned int*)GPIO0_OR = (n))
static void _flash_gpio_init(void)
{
unsigned long temp;
unsigned int val;
temp = mfdcr(DCRN_CPC0_CGCR0);
temp |= 0x00200000;
mtdcr(DCRN_CPC0_CGCR0, temp);
val = (*(volatile unsigned int*) GPIO0_TCR);
val &= ~(GPIO_MASK_NAND_FLASH_MEM);
(*(volatile unsigned int*) GPIO0_TCR) = val;
val = (*(volatile unsigned int*) GPIO0_ODR);
val &= ~(GPIO_MASK_NAND_FLASH_MEM);
(*(volatile unsigned int*) GPIO0_ODR) = val;
val = gpio_read();
val &= ~GPIO_MASK_NAND_FLASH_MEM;
gpio_write(val);
}
#endif /* __PWPRO_GPIO */
/*
* Define partitions for flash device
*/
const static struct mtd_partition partition_info[] =
{
{
name : "형욱보드 Linux Kernel Partition",
offset: 0x00004000,
size : 1584*SZ_1K
},
{
name : "형욱보드 Root Filesystem(YAFFS) Partition",
offset: 0x00190000,
size : 4800*SZ_1K
},
{
name : "형욱보드 Configuration Partition",
offset: 0x00640000,
size : 9600*SZ_1K
}
};
#define PWPRO_NAND_NUM_PARTITIONS 3
/*
* hardware specific access to control-lines
*/
/* void pwpro_nand0_hwcontrol(int cmd) */
void pwpro_nand0_hwcontrol(struct mtd_info *mtd, int cmd)
{
/* int dummy; */
switch(cmd)
{
/*
case NAND_CTL_SETNCE: dummy = readb(EZ_NAND_BASE_D0 + EZ_NAND_DATA) ; break;
case NAND_CTL_CLRNCE: dummy = readb(EZ_NAND_BASE_D0 + EZ_NAND_ACCESS_END); break;
*/
case NAND_CTL_SETNCE:
writeb(0, FLASH_CS0_SET); /* chip enable */
writeb(NAND_CMD_RESET, FLASH_CMD_REG); /* reset */
udelay(20); /* delay */
break;
case NAND_CTL_CLRNCE:
break;
default:
break;
}
}
/*
* Send command to NAND device
*/
void pwpro_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
{
register struct nand_chip *this = mtd->priv;
register unsigned long NAND_IO_ADDR = this->IO_ADDR_W;
// Write out the command to the device.
if (command != NAND_CMD_SEQIN)
{
writeb (command, NAND_IO_ADDR + PWPRO_NAND_CMD );
}
else
{
if (mtd->oobblock == 256 && column >= 256)
{
column -= 256;
writeb (NAND_CMD_READOOB, NAND_IO_ADDR + PWPRO_NAND_CMD );
writeb (NAND_CMD_SEQIN , NAND_IO_ADDR + PWPRO_NAND_CMD );
}
else if (mtd->oobblock == 512 && column >= 256)
{
if (column < 512)
{
column -= 256;
writeb (NAND_CMD_READ1, NAND_IO_ADDR + PWPRO_NAND_CMD);
writeb (NAND_CMD_SEQIN, NAND_IO_ADDR + PWPRO_NAND_CMD);
}
else
{
column -= 512;
writeb (NAND_CMD_READOOB, NAND_IO_ADDR + PWPRO_NAND_CMD);
writeb (NAND_CMD_SEQIN , NAND_IO_ADDR + PWPRO_NAND_CMD);
}
}
else
{
writeb (NAND_CMD_READ0 , NAND_IO_ADDR + PWPRO_NAND_CMD);
writeb (NAND_CMD_SEQIN , NAND_IO_ADDR + PWPRO_NAND_CMD);
}
}
// Serially input address
if (column != -1 || page_addr != -1)
{
if (column != -1) writeb (column, NAND_IO_ADDR + PWPRO_NAND_ADDR);
if (page_addr != -1)
{
writeb ((unsigned char) (page_addr & 0xff), NAND_IO_ADDR + PWPRO_NAND_ADDR);
writeb ((unsigned char) ((page_addr >> 8) & 0xff), NAND_IO_ADDR + PWPRO_NAND_ADDR);
// One more address cycle for higher density devices
if (mtd->size & 0x0c000000)
{
writeb ((unsigned char) ((page_addr >> 16) & 0x0f), NAND_IO_ADDR + PWPRO_NAND_ADDR);
}
}
}
switch (command)
{
case NAND_CMD_PAGEPROG:
case NAND_CMD_ERASE1:
case NAND_CMD_ERASE2:
case NAND_CMD_SEQIN:
case NAND_CMD_STATUS:
return;
case NAND_CMD_RESET:
if( this->dev_ready ) break;
writeb (NAND_CMD_STATUS, NAND_IO_ADDR + PWPRO_NAND_CMD);
while ( !(readb (this->IO_ADDR_R) & 0x40));
return;
default:
if (!this->dev_ready)
{
udelay (this->chip_delay);
return;
}
}
/* while (!this->dev_ready()); */
while (!this->dev_ready);
}
/*
* Main initialization routine
*/
int __init pwpro_nand_init (void)
{
struct nand_chip *this;
// Allocate memory for MTD device structure and private data
pwpro_nand_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL);
if (!pwpro_nand_mtd)
{
printk ("Unable to allocate 형욱보드 MTD device structure.\n");
return -ENOMEM;
}
// Get pointer to private data
this = (struct nand_chip *) (&pwpro_nand_mtd[1]);
// Initialize structures
memset((char *) pwpro_nand_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
// Link the private data with the MTD structure
pwpro_nand_mtd->priv = this;
// Set address of NAND IO lines
this->IO_ADDR_R = PWPRO_NAND_BASE_D0 + PWPRO_NAND_DATA;
this->IO_ADDR_W = PWPRO_NAND_BASE_D0 + PWPRO_NAND_DATA;
// Set address of hardware control function
this->hwcontrol = pwpro_nand0_hwcontrol;
// Set commamd function
this->cmdfunc = pwpro_nand_command ;
// 15 us command delay time */
this->chip_delay = 15;
// this->eccmode = NAND_ECC_SOFT;
// pwpro_nand_mtd->oobinfo.useecc = -1;
#if defined(__PWPRO_GPIO)
_flash_gpio_init();
#endif /* __POWATCH_GPIO */
// Scan to find existence of the device
/* if (nand_scan (pwpro_nand_mtd)) */
if (nand_scan (pwpro_nand_mtd, NAND_MAXCHIP))
{
kfree (pwpro_nand_mtd);
return -ENXIO;
}
// Allocate memory for internal data buffer
this->data_buf = kmalloc (sizeof(u_char) * (pwpro_nand_mtd->oobblock + pwpro_nand_mtd->oobsize), GFP_KERNEL);
if (!this->data_buf)
{
printk ("Unable to allocate NAND data buffer for 형욱보드-NAND.\n");
kfree (pwpro_nand_mtd);
return -ENOMEM;
}
// Register the partitions
add_mtd_partitions(pwpro_nand_mtd, partition_info, PWPRO_NAND_NUM_PARTITIONS);
// Return happy
return 0;
}
module_init(pwpro_nand_init);
/*
* Clean up routine
*/
#ifdef MODULE
static void __exit pwpro_nand_cleanup (void)
{
struct nand_chip *this = (struct nand_chip *) &pwpro_nand_mtd[0];
// Unregister the device
del_mtd_device (pwpro_nand_mtd);
// Free internal data buffer
kfree (this->data_buf);
// Free the MTD device structure
kfree (pwpro_nand_mtd);
}
module_exit(pwpro_nand_cleanup);
#endif
MODULE_LICENSE("GPL");
MODULE_AUTHOR("JANG, Hyung-Wook <jazz0719@dreamwiz.com");
MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on 형욱보드");
pwpro_nand.c를 커널컴파일 때 추가할 수 있도록 설정
[linux]/drivers/mtd/nand/Config.in 에 추가
dep_tristate ' NAND Device Support' CONFIG_MTD_NAND $CONFIG_MTD
if [ "$CONFIG_MTD_NAND" = "y" -o "$CONFIG_MTD_NAND" = "m" ]; then
bool ' NAND Flash Device on 형욱보드' CONFIG_MTD_NAND_PWPRO
fi
[linux]/drivers/mtd/nand/Makefile 에 추가
obj-$(CONFIG_MTD_NAND_PWPRO) += pwpro_nand.o
NAND Flash에 접근할 수 있도록 IO 주소공간을 커널에 등록
[linux]/arch/ppc/platforms/walnut.c 에 다음내용을 추가 (위에서 이미 등록됨. 확인)
void __init
board_io_mapping(void)
{
/* modified by hwjang */
...
/* CS1 - NAND FLASH */
io_block_mapping( 0xF0000000, 0xF0000000, 0x00100000, _PAGE_IO );
...
}
NAND ECC 경고메세지 관련
YAFFS는 MTD/NAND driver의 ECC기능을 쓰지않고, YAFFS에서 제공하는 것을 쓰므로 이로인한 아래의 경고메세지를 주석처리한다
[linux]/drivers/mtd/nand/nand.c 수정
case NAND_ECC_NONE:
// printk(KERNEL_WARNING ...)
yaffs를 kernel fs에 포함
http://www.aleph1.co.uk/armlinux/projects/yaffs/index.html(yaffs소스),
http://www.toby-churchill.org/(ballon_yaffs소스) 다운로드
[linux]/fs/yaffs 생성.
yaffs소스에서 [linux]/fs/yaffs아래에 devextras.h yaffs_fs.c yaffs_guts.c yaffs_guts.h
yaffs_mtdif.cyaffs_mtdif.h yaffsinterface.h, yportenv.h, yaffs_ecc.h, yaffs_ecc.c 를 copy
[linux]/fs/yaffs에 [ballon_yaffs]/Makefile을 copy하고 아래와 같이 수정
obj-y := yaffs_fs.o yaffs_guts.o yaffs_mtdif.o yaffs_ecc.o
[linux]/fs/Config.in의 앞부분에 아래 추가하여 커널 컴파일 configuration시 yaffs 선택할 수 있도록 함
tristate "Yaffs filesystem on NAND" CONFIG_YAFFS_FS
(document에서는 CONFIG_MTD_NAND가 정의되어있을때면 설정가능하도록 되어있으나,
실제 nand flash에 접근할때는 mtd가아닌 yaffs의 ecc, verify write기능을 쓰기 때문에 이렇게 설정해야함
[linxux]fs/Makefile에 추가
subdir-$(CONFIG_YAFFS_FS) += yaffs
컴파일 에러 발생시 추가 수정내용 (옵션)
[linux]/include/linux/serialP.h 수정 : async_icount 구조체 정의 관련
/* modified by hwjang. for yaffs filesystem support */
/* #if (LINUX_VERSION_CODE < 0x020300) */
#if (LINUX_VERSION_CODE >= 0x020300)
/* Unfortunate, but Linux 2.2 needs async_icount defined here and
* it got moved in 2.3 */
#include <linux/serial.h>
#endif
[linux]/include/linux/mtd/mtd.h 추가 : 2.5버전이하에서 사용하는 BUG_ON함수가 previewkit 소스에는 제공하지 않으므로 2.5이상 버전의 커널 소스트리의 bug.h파일을 [linux]/include/asm-ppc/bug.h 로 copy
#include <asm-ppc/bug.h>
kernel에 mtd, yaffs가 적용되도록 환경설정
Load configuration : arc/ppc/deconfig 한후 아래 내용 추가
Loadable module support
[*] Kernel module loader : /sbin/insmod yaff.o하지 않아도 커널이 자동적으로 yaff module을 등록시키도록 하기 위함.
General setup
[*] Default bootloader kernel arguments
Initial kernel command string: "console=ttyS0,9600 console=tty0 root=/dev/mtdblock0"
: 루트파일시스템을 플래시에 구성된 yaffs파일시스템으로 mtd를 통해 연결. 아래 참고.
Memory Technolygy Devices(MTD)
<*> Memory Technology Device (MTD) support
[*] Debugging(verbocity=0)
<*> MTD partitioning support
<*> Direct char Device access to MTD device
<*> Caching block device access to MTD devices
NAND Flash Device Drivers
<*> NAND Device Support
[*] NAND Flash Device on 형욱보드
[*] Verify NAND page writes
Fliesystem
<*> Yaffs filesystem on NAND
Save as poswatch_pro.menuconfig
[linux]>make clea
[linux]>make dep
[linux]>make uImage
-> yaffs 플래시파일시스템 지원 u-boot용 커널 생성
: [linux]/arch/ppc/boot/images/vmlinux.UBoot
[linux]>make zImage
-> Poswatch openbios용 압축커널이미지(arch/ppc/boot/images/zImage.treeboot) 생성(http://www.geocrawler.com/archives/3/8358/2002/1/50/7622546/)
U-Boot를 yaffs를 지원하여 Stand-alone으로 동작하도록 수정
include/configs/형욱보드.h
mtd partition 0으로부터 리눅스 커널 이미지를 램으로 로드하여, 부팅.
/* autoboot command */
#define CONFIG_BOOTCOMMAND "nand read 200000 4000 (vmlinux.UBoot사이즈);bootm 200000"
mtd partition 1의 yaffs.image를 root filesystem으로 인식.
#define CONFIG_BOOTARGS "root=/dev/mtdblock1 rw"
yaffs rootfs 구성
directory 구성
yaffs : working dir
- rootfs_yaffs : 위에서 구성한 rootfs를 copy ( cp -dprR 이용)
$ cd rootfs_yaffs
mknod dev/mtd0 c 90 0
mknod dev/mtd1 c 90 1
mknod dev/mtdblock0 b 31 0
mknod dev/mtdblock1 b 31 1
$ vi etc/fstab
/dev/mtdblock1 / yaffs default 0 0
아래의 설정은 http://doc.kldp.org/KoreanDoc/html/Boot_Process-KLDP/inittabfile.html 참조.
vi etc/inittab
::sysinit:/etc/init.d/rcS 추가 (이상하게 앞의 si 키워드 없애야 동작함. 향후 검토)
vi etc/init.d/rcS 수정(맨앞)
/sbin/insmod yaffs.o : menuconfig에서 Loadable support>kernel module loader선택했다면 제외할것.
mount -t yaffs /dev/mtdblock1 / -> flash의 yaffs파일시스템이 /로 마운트
yaffs 이미지 작성.
yaffs/utils에서 yaffs 이미지 작성용 툴을 제공
mkyaffsimage : root filesystem 디렉토리로부터 NAND flash용 yaffs 이미지 작성
mkyaffs : flash erase
yaffs compile
yaffs/Makefile, yaffs/utils/Makefile을 아래와 같이 수정
KERNELDIR = [linux]
MAKETOOLS =
...
# USE_RAM_FOR_TEST = -DCONFIG_YAFFS_RAM_ENABLED
yaffs$ make
yaffs/utils$ make
http://62.49.201.250/balloon/releases/utils/mkyaffsimage 다운로드
$ mv mkyaffsimage mkyaffsimage.ballon
Ihttp://www.intrinsyc.com/support/I-Linux/405-cube/cerfcube405ep.htm#misc/cd.htm으로부터 mkyaffsimage 다운로드
$ mv mkyaffsimage mkyaffsimage.cerf
$ mkyaffsimage.cerf rootfs_yaffs yaffs.image convert: NAND flash용 yaffs 이미지(yaffs.image)생성
U-Boot에 YAFFS 이미지 지원 NAND flash 처리루틴 추가 (cmd_nand.c 기반)
NAND flash 관련 명령어는 common/cmd_nand.c에서 정의됨
common/cmd_nand.c
U_BOOT_CMD(
nand, 5, 1, do_nand,
"nand - NAND sub-system\n",
"info - show available NAND devices\n"
"nand device [dev] - show or set current device\n"
"nand read[.jffs2[s]] addr off size\n"
"nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
" at offset `off' to/from memory address `addr'\n"
"nand erase [clean] [off size] - erase `size' bytes from\n"
" offset `off' (entire device if not specified)\n"
"nand bad - show bad blocks\n"
"nand read.oob addr off size - read out-of-band data\n"
"nand write.oob addr off size - write out-of-band data\n"
);
nand 관련 명령어 셋 컴파일되도록 설정
$ vi common/Makefile
COBJS = cmd_nand.o 추가
$ vi include/configs/WALNUT405.h : CFG_CMD_NAND 추가
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
CFG_CMD_PCI | \
CFG_CMD_IRQ | \
CFG_CMD_NAND )
board/.../형욱보드.c
/* modified by hwjang : NAND initialization */
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
extern ulong
nand_probe(ulong physadr);
void
nand_init(void)
{
#define FLASH_BASE_ADDR 0xF0000000
ulong totlen = 0;
printf ("Probing at 0x%.8x\n", FLASH_BASE_ADDR);
totlen = nand_probe (FLASH_BASE_ADDR);
printf ("%4lu MB\n", totlen >>20);
}
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
$ vi include/configs/형욱보드.h : 각시스템의 설정에 맞게 각 매크로를 define해주세요.
/* modified by hwjang */
/*-----------------------------------------------------------------------
* NAND-FLASH stuff
*-----------------------------------------------------------------------
*/
#define CONFIG_NAND
#define CONFIG_YAFFS /* use yaffs filesystem on nand flash */
#define CFG_NAND_BASE 0xF0000000
#define DCRN_CPC0_CGCR0 0x0b1
#define GPIO0_TCR_ADDR 0xEF600704
#define GPIO0_ODR_ADDR 0xEF600718
#define GPIO0_IR_ADDR 0xEF60071C
#define GPIO_MASK_NAND_FLASH_MEM (1<<(31-15))
#define gpio_read() (*(volatile unsigned int*)GPIO0_IR)
#define gpio_write(n) (*(volatile unsigned int*)GPIO0_ODR_ADDR = (n))
#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
#define SECTORSIZE 512
#define ADDR_COLUMN 1
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3
#define NAND_ChipID_UNKNOWN 0x00
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
#define CFG_NAND_CE_SET (CFG_NAND_BASE + 0x00080000)
#define CFG_NAND_CE_CLR (CFG_NAND_BASE + 0x000A0000)
#define CFG_NAND_CMD_REG (CFG_NAND_BASE + 0x00000001)
#define CFG_NAND_ADDR_REG (CFG_NAND_BASE + 0x00000002)
#define NAND_DISABLE_CE(nand) do { *(volatile __u8 *)(CFG_NAND_CE_CLR) = 0;} while(0)
#define NAND_ENABLE_CE(nand) do { *(volatile __u8 *)(CFG_NAND_CE_SET) = 0;} while(0)
#define NAND_CTL_CLRALE(nandptr) do { ; } while(0)
#define NAND_CTL_SETALE(nandptr) do { ; } while(0)
#define NAND_CTL_CLRCLE(nandptr) do { ; } while(0)
#define NAND_CTL_SETCLE(nandptr) do { ; } while(0)
#define NAND_WAIT_READY(nand) while ((gpio_read() & GPIO_MASK_NAND_FLASH_MEM) ? 0:1)
#define WRITE_NAND_COMMAND(d, adr) do{ *(volatile __u8 *)(CFG_NAND_CMD_REG) = (__u8)(d); } while(0)
#define WRITE_NAND_ADDRESS(d, adr) do{ *(volatile __u8 *)(CFG_NAND_ADDR_REG) = (__u8)(d); } while(0)
#define WRITE_NAND(d, adr) ( writeb(d, adr) )
#define READ_NAND(adr) ( readb(adr) )
$ vi lib_ppc/board.c : flash 초기화 안해줌(수정 가능)
/* modified by hwjang : no flash initialization */
#if 0
/* #if !defined(CFG_NO_FLASH) */
puts ("FLASH: ");
if ((flash_size = flash_init ()) > 0) {
YAFFS 이미지 Fusing 루틴 추가 (cmd_nand.c)
# nand write.yaffs (yaffs.image가 로딩된 ram addr) (NAND flash offset) (yaffs.image 사이즈)
가 동작하도록 명령어 셋과 처리루틴 추가
YAFFS의 경우 U-Boot에서 지원하는 JFFS2와 동작하는 상황이 다르며, 아래사항을 처리해야 함
Page Write 시 OOB영역 처리 : yaffs.image는 data(1st/2nd half array, 512bytes) + oob(spare array, 16bytes)의 연속으로 구성되며, JFFS2와 다르게 spare area(OOB영역)에 yaffs.image의 값을 쓸 수 있도록 수정
ECC disable : YAFFS는 NAND_ECC_NONE모드
size 문제 : (yaffs.image 사이즈)는 oob영역까지 포함된 사이즈, U-Boot에서는 data영역만의 사이즈 기반(즉 FLASH address기반)으로 처리하므로, yaffs의 경우 이를 적당히 조절해야 함. 처리하지 않을 경우 의도보다 FLASH 영역을 넘어서 잘못된 값을 Fusing. bad block 발생.
nand write.yaffs 명령어셋 추가
#define NANDRW_YAFFS 0x08
nand write.yaffs 명령을 인식하고, nand_write_yaffs()를 호출하도록 설정.
int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
...
else if (cmdtail && !strncmp(cmdtail, ".yaffs", 2))
cmd |= NANDRW_YAFFS;
...
}
/* cmd: 0: NANDRW_WRITE write, fail on bad block
* 1: NANDRW_READ read, fail on bad block
* 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks
* 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks
* 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
* 8: NANDRW_WRITE | NANDRW_YAFFS write, yaffs // hwjang
*/
static int nand_rw (struct nand_chip* nand, int cmd,
size_t start, size_t len,
size_t * retlen, u_char * buf)
{
/* size관련처리 */
int pages_per_block = (nand->erasesize) / (nand->oobblock);
if (cmd & NANDRW_YAFFS) {
// len passed is yaffs image size (including oob_data).
// modified to size except oob_data to work properly in u-boot
int num_pages_yaffs = len / (nand->oobblock + nand->oobsize);
len = num_pages_yaffs << nand->page_shift;
}
..
else if ((cmd == (NANDRW_WRITE | NANDRW_JFFS2)) || (cmd == (NANDRW_WRITE | NANDRW_YAFFS))) {
//else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
/* skip bad block */
start += erasesize;
continue;
}
...
else if (cmd & NANDRW_YAFFS) {
ret = nand_write_yaffs (nand, start,
min(len, eblk + erasesize - start),
&n, (u_char*)buf, NULL);
// hwjang : yaffs image contains oob_data ( size : 16 Bytes in each page )
// so buf pointer should be increased to point at data_buf of the next block.
buf += (pages_per_block << 4);
}
}
nand->data_buf[]에 OOB영역까지 포함한 yaffs.image의 값을 할당하고, OOB영역까지 page programming되도록 설정
static int nand_write_yaffs (struct nand_chip* nand, size_t to, size_t len,
size_t * retlen, const u_char * buf, u_char * ecc_code)
{
int i, page, col, cnt, ret = 0;
//hwjang
int pages_per_block = (nand->erasesize) / (nand->oobblock);
/* Do not allow write past end of device */
if ((to + len) > nand->totlen) {
printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
return -1;
}
/* Shift to get page */
page = ((int) to) >> nand->page_shift;
/* Get the starting column */
col = to & (nand->oobblock - 1);
/* Initialize return length value */
*retlen = 0;
/* Select the NAND device */
#ifdef CONFIG_OMAP1510
archflashwp(0,0);
#endif
NAND_ENABLE_CE(nand); /* set pin low */
/* Check the WP bit */
NanD_Command(nand, NAND_CMD_STATUS);
if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
printf ("%s: Device is write protected!!!\n", __FUNCTION__);
ret = -1;
goto out;
}
/* Loop until all data is written */
// hwjang : yaffs image contains oob_data ( size : 16 Bytes in each page )
// so additional length should be checked.
while (*retlen < len + (pages_per_block << 4)) {
/* Invalidate cache, if we write to this page */
if (nand->cache_page == page)
nand->cache_page = -1;
/* Write data into buffer */
if ((col + len) >= nand->oobblock)
// hwjang : write including oob_data in yaffs image
for (i = col, cnt = 0; i < nand->oobblock + nand->oobsize; i++, cnt++)
nand->data_buf[i] = buf[(*retlen + cnt)];
else
for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++)
nand->data_buf[i] = buf[(*retlen + cnt)];
/* We use the same function for write and writev !) */
ret = nand_write_page_yaffs (nand, page, col, i, NULL);
if (ret)
goto out;
/* Next data start at page boundary */
col = 0;
/* Update written bytes count */
*retlen += cnt;
/* Increment page address */
page++;
}
/* Return happy */
*retlen = len;
out:
/* De-select the NAND device */
NAND_DISABLE_CE(nand); /* set pin high */
#ifdef CONFIG_OMAP1510
archflashwp(0,1);
#endif
return ret;
}
OOB영역에 접근하는 ECC관련코드를 제거(nand_write_page()와 비교해볼것).
timing 설정(아래참조)
static int nand_write_page_yaffs (struct nand_chip *nand,
int page, int col, int last, u_char * ecc_code)
{
int i;
unsigned long nandptr = nand->IO_ADDR;
/* Prepad for partial page programming !!! */
for (i = 0; i < col; i++)
nand->data_buf[i] = 0xff;
/* Postpad for partial page programming !!! oob is already padded */
for (i = last; i < nand->oobblock; i++)
nand->data_buf[i] = 0xff;
/* Send command to begin auto page programming */
NanD_Command(nand, NAND_CMD_READ0);
NanD_Command(nand, NAND_CMD_SEQIN);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
/* Write out complete page of data */
for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
/* Send command to actually program the data */
NanD_Command(nand, NAND_CMD_PAGEPROG);
udelay(300); // hwjang
NanD_Command(nand, NAND_CMD_STATUS);
#ifdef NAND_NO_RB
{ u_char ret_val;
do{
ret_val = READ_NAND(nandptr); /* wait till ready */
} while((ret_val & 0x40) != 0x40);
}
#endif
/* See if device thinks it succeeded */
if (READ_NAND(nand->IO_ADDR) & 0x01) {
printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);
return -1;
}
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
/*
* The NAND device assumes that it is always writing to
* a cleanly erased page. Hence, it performs its internal
* write verification only on bits that transitioned from
* 1 to 0. The device does NOT verify the whole page on a
* byte by byte basis. It is possible that the page was
* not completely erased or the page is becoming unusable
* due to wear. The read with ECC would catch the error
* later when the ECC page check fails, but we would rather
* catch it early in the page write stage. Better to write
* no data than invalid data.
*/
/* Send command to read back the page */
if (col < nand->eccsize)
NanD_Command(nand, NAND_CMD_READ0);
else
NanD_Command(nand, NAND_CMD_READ1);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
udelay(9); // hwjang
/* Loop through and verify the data */
for (i = col; i < last; i++) {
if (nand->data_buf[i] != readb (nand->IO_ADDR)) {
printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page);
return -1;
}
}
#endif
return 0;
}
형욱보드 설정에 맞춘 wait timing 세팅
하드웨어 측정 결과
구분
하드웨어 R/B pin Busy timing
소스 설정값(udelay 적용값)
write
t_PROG = 180 us
300 us
erase
t_BER = 2000 us
2500 us
read
t_R = 7.20 us
9 us
$ vi common/cmd_nand.c
static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
size_t * retlen, u_char *buf, u_char *ecc_code)
{
...
/* Send the read command */
NanD_Command(nand, NAND_CMD_READ0);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
udelay(9); // hwjang
/* Read in a page + oob data */
NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
...
}
static int nand_write_page (struct nand_chip *nand,
int page, int col, int last, u_char * ecc_code)
{
...
/* Write out complete page of data */
for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
/* Send command to actually program the data */
NanD_Command(nand, NAND_CMD_PAGEPROG);
udelay(300); // hwjang
NanD_Command(nand, NAND_CMD_STATUS);
...
}
static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
size_t * retlen, u_char * buf)
{
...
if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
len256 = (ofs | 0x7) + 1 - ofs;
NanD_ReadBuf(nand, buf, len256);
NanD_Command(nand, NAND_CMD_READOOB);
NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
}
udelay(9); // hwjang
NanD_ReadBuf(nand, &buf[len256], len - len256);
...
}
static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
size_t * retlen, const u_char * buf)
{
...
/* treat crossing 8-byte OOB data for 2M x 8bit devices */
/* Note: datasheet says it should automaticaly wrap to the */
/* next OOB block, but it didn't work here. mf. */
if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
len256 = (ofs | 0x7) + 1 - ofs;
for (i = 0; i < len256; i++)
WRITE_NAND(buf[i], nandptr);
NanD_Command(nand, NAND_CMD_PAGEPROG);
udelay(300);
NanD_Command(nand, NAND_CMD_STATUS);
...
for (i = len256; i < len; i++)
WRITE_NAND(buf[i], nandptr);
NanD_Command(nand, NAND_CMD_PAGEPROG);
udelay(300); // hwjang
NanD_Command(nand, NAND_CMD_STATUS);
...
}
static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
{
...
while(len) {
/*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
mychip = &nand->chips[ofs >> nand->chipshift];
/* always check for bad block first, genuine bad blocks
* should _never_ be erased.
*/
if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
/* Select the NAND device */
NAND_ENABLE_CE(nand); /* set pin low */
NanD_Command(nand, NAND_CMD_ERASE1);
NanD_Address(nand, ADDR_PAGE, ofs);
NanD_Command(nand, NAND_CMD_ERASE2);
udelay(2500); // hwjang
NanD_Command(nand, NAND_CMD_STATUS);
...
}
NAND FLASH로부터 STAND-ALONE으로 동작
# tftpboot 200000 /tftpboot/vmlinux.UBoot
# tftpboot 400000 /tftpboot/yaffs.image
# nand erase (nand시작번지) (nand 사이즈)
# nand write 200000 4000 (vmlinux.UBoot 사이즈)
# nand write.yaffs 400000 190000 (yaffs.image 사이즈)
# reset
(재부팅)
# nand read 200000 4000 (vmlinux.UBoot사이즈);bootm 200000 실행되고
(콘솔메시지)
U-Boot 1.1.1 (Jun 30 2004 - 15:21:21)
CPU: IBM PowerPC 405GPr Rev. B at 266.500 MHz (PLB=133, OPB=66, EBC=66 MHz)
PCI sync clock at 33 MHz, internal PCI arbiter enabled
16 kB I-Cache 16 kB D-Cache
Board: ### No HW ID - assuming WALNUT405
I2C: ready
DRAM: 32 MB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
NAND:Probing at 0xf0000000
16 MB
Hit any key to stop autoboot: 0
=> tftpboot 200000 /tftpboot/uImage
ENET Speed is 10 Mbps - HALF duplex connection
TFTP from server 192.168.1.210; our IP address is 192.168.1.200
Filename '/tftpboot/uImage'.
Load address: 0x200000
Loading: #################################################################
#################################################################
############
done
Bytes transferred = 722310 (b0586 hex)
=> tftpboot 400000 /tftpboot/yaffs.image
ENET Speed is 10 Mbps - HALF duplex connection
TFTP from server 192.168.1.210; our IP address is 192.168.1.200
Filename '/tftpboot/yaffs.image'.
Load address: 0x400000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
############################################################
done
Bytes transferred = 3631056 (3767d0 hex)
=> nand write 200000 4000 b0586
NAND write: device 0 offset 16384, size 722310 ... 722310 bytes written: OK
=> nand write.yaffs 400000 190000 3767d0
NAND write: device 0 offset 1638400, size 3631056 ... 3521024 bytes written: OK
=> nand bad
Device 0 bad blocks:
0x00000000
=> reset
U-Boot 1.1.1 (Jun 30 2004 - 15:21:21)
CPU: IBM PowerPC 405GPr Rev. B at 266.500 MHz (PLB=133, OPB=66, EBC=66 MHz)
PCI sync clock at 33 MHz, internal PCI arbiter enabled
16 kB I-Cache 16 kB D-Cache
Board: ### No HW ID - assuming WALNUT405
I2C: ready
DRAM: 32 MB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
NAND:Probing at 0xf0000000
16 MB
Hit any key to stop autoboot: 0
NAND read: device 0 offset 16384, size 2097152 ... 2097152 bytes read: OK
## Booting image at 00200000 ...
Image Name: Linux-2.4.24-pre2
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 722246 Bytes = 705.3 kB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
...(중간생략)
NAND device: Manufacturer ID: 0xec, Chip ID: 0x73 (Samsung NAND 16MiB 3,3V)
Creating 3 MTD partitions on "NAND 16MiB 3,3V":
0x00004000-0x00190000 : "형욱보드 Linux Kernel Partition"
mtd: Giving out device 0 to 형욱보드 Linux Kernel Partition
0x00190000-0x00640000 : "형욱보드 Root Filesystem(YAFFS) Partition"
mtd: Giving out device 1 to 형욱보드 Root Filesystem(YAFFS) Partition
0x00640000-0x00fa0000 : "형욱보드 Configuration Partition"
mtd: Giving out device 2 to 형욱보드 Configuration Partition
...(중간생략)
yaffs: dev is 7937 name is "1f:01"
VFS: Mounted root (yaffs filesystem).
Freeing unused kernel memory: 100k init
serial console detected. Disabling virtual terminals.
init started: BusyBox v0.60.2 (2002.12.19-10:50+0000) multi-call binary
(none) login: root
$ ls
$ cd /tmp
$ ls
$ cat abcd > test.txt
cat: abcd: No such file or directory
$ echo abcd > test.txt
$ ls
test.tx
source [color schema path]
1. 데이터 변환 함수
2. 디렉토리 조작 함수
3. 버퍼 조작 함수
4. 파일 조작 함수
5. stream 입출력 함수
6. Low level 입출력 함수
7. Mathematics
8. 메모리 조작 함수
9. 탐색과 정렬 함수
10. 문자열 조작 함수
11. 시간 함수
12. 문자 분류 및 변환 함수
13. 기타 함수
1. 데이터 변환 함수
문자나 문자열을 수치 값으로 변환시키거나 대문자를 소문자로 소문자를 대문자로 변환하는 함수로 stdlib.h에 정의되어 있다.
헤더 파일 : #include
atof
형식 : double atof(char *string)
설명 : 문자열을 부동소수점 값으로 변환하는 함수 부동소수점으로 변환할 수 없는 문자열인 경우 0을 반환한다.
atoi
형식 : int atoi(char *string)
설명 : 문자열을 정수 값으로 변환하는 함수, 변환할 수 없는 경우에는 0을 반환한다.
atol
형식 : int atol(char *string)
설명 : 문자열을 long integer값으로 변환하는 함수, 변환할 수 없는 경우에는 0을 반환한다.
itoa
형식 : char *itoa(int value, char *string, int radix)
설명 : 정수형 숫자를 문자열로 변환하는 함수
ltoa
형식 : char *ltoa(long value, char *string, int radix)
설명 ; long integer형 숫자를 문자열로 변환하는 함수
strtod
형식 : double strtod(char *string, char *endptr)
설명 : 문자열을 부동소수점 값으로 변환하는 함수, 실패한 경우 0을 반환한다. 변환할 수 없는 문자를 만난 경우, 읽기를 중단한다.
strtol
형식 : long strtol(char *string, char *endptr, int radix)
설명 : 문자열을 long integer형 숫자로 변환하는 함수, 변환할 수 없는 문자열인 경우 0을 반환한다.
strtoul
형식 : unsigned long strtoul(char *string, char *endptr, int radix)
설명 : 문자열을 unsigned long형의 숫자로 변환하는 함수, 변환할 수 없는 문자열인 경우 0을 반환한다.
2. 디렉토리 조작 함수
헤더 파일 : #include
chdir
형식 : int chdir(char *path)
설명 : 현재 디렉토리를 주어진 경로로 바꾸는 함수
getcwd
형식 : char *getcwd(char *path, int numchars)
설명 : 현재의 작업 디렉토리의 이름을 반환하는 함수
mkdir
형식 : int mkdir(char *path)
설명 ; 주어진 경로를 사용하여 디렉토리를 만드는 함수
rmdir
형식 : int rmdir(char *path)
설명 : 주어진 경로의 디렉토리를 삭제하는 함수
3. 버퍼 조작 함수
헤더 파일 : #include
memchr
형식 : void *memchr(void *s, int c, size_t n)
설명 : 버퍼에 문자를 찾는 함수
memcmp
형식 : int memcmp(void *s1, void s2, size_t n)
설명 : 두 버퍼를 비교하는 함수
memcpy
형식 : void *memcpy(void *dest, void *src, size_t n)
설명 : 버퍼의 내용을 복사하는 함수
memmove
형식 : void *memmove(void *dest, void *src, size_t n)
설명 : 바이트 수만큼 src버퍼에서 dest버퍼로 이동시키는 함수
memset
형식 : void *memset(void *s, int c, size_t n)
설명 : 주어진 문자로 버퍼로 채우는 함수
4. 파일 조작 함수
헤더 파일 : #include
chmod
형식 : int chmod(char *path, int pmode)
설명 : 파일의 permission을 바꾸는 함수
fstat
형식 : int fstat(int handle, struct stat *buffer)
설명 : 파일의 상태 정보를 가져오는 함수
remove
형식 : int remove(char *path)
설명 : 파일을 삭제하는 함수
rename
형식 : int rename(char *oldname, char *newname)
설명 : 파일의 이름을 바꾸는 함수
stat
형식 : int stat(char *path, struct stat *buffer)
설명 : 파일의 상태 정보를 가져오는 함수
umask
형식 : unsigned umask(unsigned pmode)
설명 : 파일의ㅣ permission을 mask시키는 함수
5. Stream 입출력 함수
헤더 파일 : #include
clearerr
형식 : void clearerr(FILE *file_pointer)
설명 : stream의 에러 지시자를 지우는 함수
fclose
형식 : int fclose(FILE *file_pointer)
설명 : 파일을 닫는 함수, 정상적으로 수행되면 0을 에러가 발생되면 EOF을 반환한다.
feof
형식 : int feof(FILE *file_pointer)
설명 : 파일의 끝을 검사하는 함수, 지정된 파일이 EOF이면 0이외의 값을 반환한다.
ferror
형식 : int ferror(FILE *file_pointer)
설명 : 파일의 입출력 동안 에러가 발생되었는지를 검사하는 함수, 에러가 있으면 0이외의 값을 반환한다.
fflush
형식 : int fflush(FILE *file_pointer)
설명 : 버퍼의 내용을 파일에 쓰는 함수, 정상적으로 수행이 끝나면 0을 반환하고 그 이외에는 EOF를 반환한다.
fgetc
형식 : int fgetc(FILE *file_pointer)
설명 : stream으로부터 한 문자를 가져오는 함수, 에러 발생이나 파일의 끝인 경우에는 EOF를 반환한다.
fgetpos
형식 : int fgetpos(FILE *file_pointer, fpos_t current_pos)
설명 : stream에서 현재 위치를 가져오는 함수
fgets
형식 : char *fgets(char *string, int maxchar, FILE *file_pointer)
설명 : 파일에서 문자열을 읽는 함수, 읽어들이는 단위는 EOF나 \n을 만나거나 n-1개의 문자 길이 만큼이다. 실패한 경우 NULL을 반환한다.
fopen
형식 : FILE *fopen(char *filename, char *access_mode)
설명 : 파일을 열기 위한 함수, 에러가 발생되면 NULL을 반환한다.
fprintf
형식 : int fprintf(FILE *file_pointer, char *format_string, args)
설명 : 파일에 주어진 형식으로 데이터를 쓰기 위한 함수, 정상적으로 수행이 되면 출력한 문자의 수를 반환한다. 만약 에러가 발생되면 EOF를 반환한다.
fputc
형식 : int fputc(int c, FILE *file_pointer)
설명 : 문자를 stream에 쓰기 위한 함수, 정상적으로 수행이 되면 출력한 문자의 수를 반환한다. 에러가 발생되면 EOF를 반환한다.
fputchar
형식 : int fputchar(int c)
설명 : 문자를 stdout에 쓰기 위한 함수
fputs
형식 : int fputs(char *string, FILE *file_pointer)
설명 : 문자열을 stream에 쓰기 위한 함수, 에러가 발생되면 EOF를 반환한다.
fread
형식 : size_t fread(char *buffer, size_t size, size_t count, FILE *file_pointer)
설명 : stream으로부터 unformatted data를 buffer에 쓰기 위한 함수, 읽어들인 블록의 수를 반환한다.
freopen
형식 : FILE *freopen(char *filename, char *access mode, FILE *file_pointer)
설명 : 파일 포인터를 다른 파일에 재 할당하기 위한 함수
fscanf
형식 : int fscaf(FILE *file_pointer, char *format string, args)
설명 : stream으로부터 formatted input을 읽기 위한 함수, stream파일에서 형식대로 읽혀진 데이터 수를 반환한다. format의 형식은 scanf()와 같다.
fseek
형식 : int fseek(FILE *file_pointer, long offset, int origin)
설명 : 파일의 현재 위치에서 새로운 위치로 변경하는 함수, 정상적으로 수행했을 경우 0을 반환한다.
fsetpos
형식 : int fsetpos(FILE *file_pointer, fpos_t *current pos)
설명 : 파일의 현재 위치에서 새로운 위치로 변경하는 함수
ftell
형식 : long ftell(FILE *file_pointer)
설명 : 파일에서의 현재 위치를 가져오는 함수 에러가 발생되면 -1을 반환한다.
fwrite
형식 : size_t fwrite(char *buffer, size_t size, size_t count, FILE *file_pointer)
설명 : 버퍼에 있는 unformatted data를 stream에 쓰기 위한 함수
getc
형식 : int getc(FILE *file_pointer)
설명 : 문자를 stream으로부터 읽기 위한 함수
getchar
형식 : int getchar(void)
설명 : srdin으로부터 문자를 읽기 위한 함수
gets
형식 : char *gets(char *buffer)
설명 : srdin으로부터 라인을 버퍼로 읽는 함수
printf
형식 : int printf(int c, FILE *file_pointer)
설명 : formatted output을 stdout에 쓰는 함수
putc
형식 : int putc(int c, FILE *file_pointer)
설명 : 문자를 steam에 쓰기 위한 함수
putchar
형식 : int putchar(int c)
설명 : 문자를 stdout에 쓰기 위한 함수
puts
형식 : int puts(char *string)
설명 : 문자열을 stdout에 쓰기 위한 함수
rewind
형식 : void rewind(FILE *file_pointer)
설명 : 파일을 rewind하기 위한 함수
scanf
형식 : int scanf(char *format_string, args)
설명 : stdin으로부터 formatted input을 읽는 함수
setbuf
형식 : void setbuf(FILE *file_pointer, char *buffer)
설명 : stream을 위해 새로운 버퍼를 지정하는 함수
setvbuf
형식 : int setvbuf(FILE *file_pointer, char *buffer, int buf_type, size_t buf_size)
설명 : 새로운 버퍼를 지정하고 제어하는 함수
sprintf
형식 : int sprintf(char *string, char *format_string, args)
설명 : formatted output을 문자열로 쓰는 함수
sscanf
형식 : int sscanf(char *buffer, char *format_string, args)
설명 : 문자열로부터 formatted input을 읽는 함수
tmpfile
형식 : FILE *tmpfile(void)
설명 : temporary 파일의 이름을 가져오기 위한 함수
tmpnam
형식 : char *tmpnam(char *file_name)
설명 : temporary 파일의 이름을 가져오기 위한 함수
ungetc
형식 : int ungetc(int c, FILE *file_pointer)
설명 : 문자를 stream의 버퍼에 되돌려 주는 함수
6. Low level 입출력 함수
헤더 파일 : #include 외에 #include , #include , #include , #include
close
형식 : int close(int handle)
설명 : unbuffered I/O를 위해 열어 놓은 파일을 닫기 위한 파일, 정상적으로 수행되었을 경우 0을 반환한다. 에러가 발생되었을 경우에는 -1을 반환한다.
creat
형식 : int creat(char *filename, int pmode)
설명 : 주어진 permission을 갖는 새로운 파일을 생성하기 위한 파일, 에러가 발생되었을 경우에는 -1을 반환한다.
eof
형식 : int eof(int handle)
설명 : 파일의 끝을 검사하는 파일, 지정된 파일의 현재 위치가 파일의 끝이면 1을 반환하고 그렇지 않을 경우에는 0을 반환한다.
lseek
형식 : long lseek(int handle, long offset, int orgin)
설명 : 파일의 주어진 위치로 이동하는 함수
open
형식 : int open(char *filename, int oflag, unsigned pmode)
설명 : low-level I/O를 위해 파일을 여는 함수
read
형식 : int read(int handle, char *buffer, unsigned length)
설명 : 파일로부터 바이너리 데이터를 버퍼로 읽는 함수, 읽은 문자의 바이트 수를 반환한다. 파일의 끝일 경우에는 EOF를 반환한다. 에러가 발생되면 -1을 반환한다.
write
형식 : int write(int handle, char *buffer, unsigned count)
설명 : 버퍼에 있는 바이너리 데이터를 파일에 쓰는 함수, 정상적으로 수행되었을 경우에는 쓴 문자의 바이트 수를 반환한다. 에러가 발생되었을 경우에는 -1을 반환한다.
7. Mathematics
헤더 파일 : #intclude
abs
형식 : int abs(int n)
설명 : 정수의 절대값을 구하는 함수
acos
형식 : double acos(double x)
설명 : x의 arc cosine을 계산하는 함수
asin
형식 : double asin(double x)
설명 : x의 arc sine을 계산하는 함수
atan
형식 : double atan(double x)
설명 : x의 arc tangent를 계산하는 함수
atan2
형식 : double atan2(double y, double x)
설명 : y/x의 arc tangent를 계산하는 함수
ceil
형식 : double ceil(double x)
설명 : x를 초과하는 가장 작은 integral 값을 구하는 함수
cos
형식 : double cos(double x)
설명 : cosine을 계산하는 함수
cosh
형식 : double cosh(double x)
설명 : x의 hyperbolic cosine을 계산하는 함수
div
형식 : div_t div(int number, int denom)
설명 : nunber/denom을 계산하여 몫과 나머지로 이루어진 구조체 div_t를 반환한다.
div_t의 형식은 다음과 같다.
type struct{
int quot;
int rem;
} div_t;
exp
형식 : x의 exponential을 계산하는 함수
fabs
형식 : double fabs(double x)
설명 : x의 절대값을 구하는 함수
floor
형식 : double floor(double x)
설명 : x보다 작은 가장 큰 integral값을 구하는 함수
fmod
형식 : double fmod(double x, double y)
설명 : x/y의 나머지를 반환하는 함수
frexp
형식 : double frexp(double x, int *expptr)
설명 : x를 mantissa와 exponent로 분리하는 함수
labs
형식 : labs(long n)
설명 : long integer의 절대값을 찾는 함수
ldexp
형식 : double ldexp(double x, int exp)
설명 : mantissa와 exponent로 값을 계산하여 반환하는 함수
ldiv
형식 : ldiv_t ldiv(long number, long denom)
설명 : long integer를 나눗셈하는 함수
log
형식 : double log(double x)
설명 : log(x)를 계산하는 함수
log10
형식 : double log10(double x)
설명 : base 10인 x의 log을 구하는 함수
modf
형식 : double modf(double x, double *inptr)
설명 : x를 fraction부분과 integer부분으로 분리하는 함수
pow
형식 : double pow(double x, double y)
설명 : x의 y승을 구하는 함수
rand
형식 : int rand(void)
설명 : 0에서 32사이의 random 정수를 구하는 함수
random
형식 : int random(int max_num)
설명 : 0에서 max_num)사이의 random 정수를 구하는 함수
randomize
형식 : void randomize(void)
설명 : random 수를 발생시키기 위해 seed를 지정하는 함수
sin
형식 : double sin(double x)
설명 : sine을 계산하는 함수
sinh
형식 : double sinh(double x)
설명 : x의 hyperbolic sine을 계산하는 함수
sqrt
형식 : double sqrt(double x)
설명 : x의 양의 제곱근을 계산하는 함수
srand
형식 : void srand(unsigned seed)
설명 : random 수 발생을 위해 새로운 seed를 지정하는 함수
tan
형식 : double tan(double x)
설명 : x의 tangent를 계산하는 함수
tanh
형식 : double tanh(double x)
설명 : x의 hyperbloic tangent를 계산하는 함수
8. 메모리 조작 함수
헤더 파일 : #include
calloc
형식 : void *calloc(size_t num_elem, size_t elem_size)
설명 : 배열을 할당하고 모든 원소를 0으로 초기화하는 함수
free
형식 : void free(void *mem_address)
설명 : 할당된 메모리 블록을 되돌려 주는 함수
malloc
형식 : void *malloc(size_t num_bytes)
설명 : 메모리 블록을 할당하는 함수
realloc
형식 : 메모리 블록을 재 할당하는 함수
9. 탐색과 정렬 함수
헤더 파일 : #include
bsearch
형식 : void *bsearch(void *key, void *base, size_t num, size_t width, int (*com pare)(void *elem1, void *elem2)
설명 : 이진 탐색을 수행하는 함수
qsort
형식 : void qsort(void *base, size_t num, size_t width, int (*compare)(void *elem1, void *elem2)
설명 : quick sort 알고리즘을 이용하여 정렬을 수행하는 함수
10. 문자열 조작 함수
헤더 파일 : #include
strcat
형식 : int strcat(char *string1, char *string2)
설명 : 두 문자열을 결합하여 하나의 문자열로 만드는 함수
strcmp
형식 : int strcmp(char *string1, char *string2)
설명 : 문자열을 알파벳 순서로 비교하는 함수, 두 문자열이 같으면 0을 반환한다. 만약 같지 않으면 다음과 같은 값을 반환한다.
string1 < string2 이면 음수 값을 반환
string1 > string2 이면 양수 값을 반환
strcpy
형식 : char *strcpy(char *string1, char *string2)
설명 : 문자열 string2를 string1으로 복사하는 함수
strerror
형식 : char *strerror(int errnum)
설명 : 주어진 에러 번호에 해당되는 에러 메시지를 가져오는 함수
strlen
형식 : int strlen(char *string)
설명 : 문자열의 길이를 구하는 함수 이때 NULL문자는 제외하고 길이를 구한다.
strncat
형식 : char *strncat(char *string1, char *string2, size_t n)
설명 : string2의 문자를 string1 끝에 붙이는 함수
strncmp
형식 : int strncmp(char *string1, char *string2, size_t n)
설명 : 두 문자열의 처음 n개의 문자를 비교하는 함수
strncpy
형식 : char *strncpy(char *string1, char *string2, size_t n)
설명 : string2의 처음 n개의 문자를 string1에 복사하는 함수
strnset
형식 : char *strnset(char *string, int c, size_t n)
설명 : 문자열의 처음 n개 문자를 c로 만드는 함수
strrchr
형식 : char *strrchr(char *string, int c)
설명 : 문자열에서 마지막에 나오는 문자 c를 찾는 함수 만약, 해당되는 문자가 발견되지 않은 경우에는 NULL을 반환한다.
11. 시간 함수
헤더 파일 : #include
asctime
형식 : char *asctime(struct tm *time)
설명 : struct tm 형식의 시간을 문자열로 바꾸는 함수
clock
형식 : clock_t clock(void)
설명 : clock tick으로 경과된 시간을 가져오는 함수
ctime
형식 : char *ctime(time_t *time)
설명 : 이진 시간을 문자열로 바꾸는 함수
difftime
형식 : double difftime(time_t time1, time_t time2)
설명 : 두 시간 사이의 차를 초단위로 계산하는 함수
gmtime
형식 : struct_tm *gmtime(time_t *time)
설명 : Greenwich Meam Time(GMT)을 tm structuregudtlr으로 가져오는 함수
localtime
형식 : struct tm *localtime(time_t *time)
설명 : local time을 tm structure형식으로 가져오는 함수
time
형식 : time_t time(time_t *timeptr)
설명 : GMT 1970년부터 경과된 현재 시간을 가져오는 함수
12. 문자 분류 및 변환 함수
헤더 파일 : #include
isalnum
형식 : int isalnum(int c)
설명 : c가 alphanumeric이면 참값을 반환
isalpha
형식 : int isalpha(int c)
설명 : c가 letter이면 참값을 반환
isascii
형식 : int isascii(int c)
설명 : c가 ASCII이면 참값을 반환
iscntrl
형식 : int iscntrl(int c)
설명 : c가 control 문자이면 참값을 반환
isdigit
형식 : int isdigit(int c)
설명 : c가 decimal digit이면 참값을 반환
isgraph
형식 : int isgraph(int c)
설명 : c가 graphic c문자이면 참값을 반환
islower
형식 : int islower(int c)
설명 : c가 소문자이면 참값을 반환
isprint
형식 : int isprint(int c)
설명 : c가 인쇄 가능한 문자이면 참값을 반환
ispunct
형식 : int ispunct(int c)
설명 : c가 punctuation 문자이면 참값을 반환
isspace
형식 : int isspace(int c)
설명 : c가 공백 문자이면 참값을 반환
isupper
형식 : int tsupper(int c)
설명 : c가 대문자이면 참값을 반환
isxdigit
형식 : int isxdigit(int c)
설명 : c가 hexadecimal digit이면 참값을 반환
toascii
형식 : int toascii(int c)
설명 : c를 ASCII로 변환하는 함수
tolower
형식 : tolower(int c)
설명 : c를 소문자로 변환하는 함수
toupper
형식 : int toupper(int c)
설명 : c를 대문자로 변환하는 함수
13. 기타 함수
다음은 화면 제어에 관한 라이브러리 함수들이다.
헤더 파일 : #include
clreol
형식 : void clreol(void)
설명 : 커서의 현 위치 행을 지우는 함수
clrscr
형식 : void clrscr(void)
설명 : 현재 사용 중인 윈도우를 지우고 커서를 왼쪽 상단으로 이동시키는 함수
deline
형식 : void deline(void)
설명 : 커서가 있는 행을 삭제하는 함수
gettext
형식 : int gettext(int left, int top, int right, int bottom, void *dest)
설명 : 지정된 텍스트 화면의 내용을 dest로 읽어 들이는 함수
gettextinfo
형식 : void gettextinfo(struct text_info r)
설명 : 현재의 텍스트 모드의 정보를 구조체 r로 읽어 들이는 함수, 구조체의 r의 형식은 다음과 같다.
struct text_info {
unsigned char currmode;
unsigned char screenheigh;
unsigned char screenwidth;
unsigned char normattr;
unsigned char winleft;
unsigned char wintop;
unsigned char winright;
unsigned char winbottom;
unsigned char curx;
unsigned char cury;
} *r;
The Executable and Linking Format (ELF)
The executable and linking format (ELF) was originally developed by Unix System Laboratories and is rapidly becoming the standard in file formats[8]. The ELF standard is growing in popularity because it has greater power and flexibility than the a.out and COFF binary formats[3]. ELF now appears as the default binary format on operating systems such as Linux, Solaris 2.x, and SVR4. Some of the capabilities of ELF are dynamic linking, dynamic loading, imposing runtime control on a program, and an improved method for creating shared libraries[3]. The ELF representation of control data in an object file is platform independent, an additional improvement over previous binary formats. The ELF representation permits object files to be identified, parsed, and interpreted similarly, making the ELF object files compatible across multiple platforms and architectures of different size.
The three main types of ELF files are executable, relocatable, and shared object files. These file types hold the code, data, and information about the program that the operating system and/or link editor need to perform the appropriate actions on these files. The three types of files are summarized as follows:
- An executable file supplies information necessary for the operating system to create a process image suitable for executing the code and accessing the data contained within the file.
- A relocatable file describes how it should be linked with other object files to create an executable file or shared library.
- A shared object file contains information needed in both static and dynamic linking.
In the next section we overview the ELF file format including a detailed description of each of the five section types that an ELF file might include. These five types are (1) the ELF header, (2) the program header table, (3) the section header table, (4) the ELF sections, and (5) the ELF segments. In Section 2.4.2, we describe the representation of data in an ELF file. The interested reader may consult reference [8] for additional information about the ELF format.