Search Results for 'Research/SystemProg'

27 POSTS

  1. 2013.09.17 objdump 를 이용해서 shared object library 정보 알아보기
  2. 2012.07.18 커널에서 함수별 스택 사용량
  3. 2012.01.27 cgrep
  4. 2012.01.26 export LC_ALL=C
  5. 2011.04.22 runtime control of printk times
  6. 2010.03.08 DirectFB Internals - Things You Need to Know to Write Your DirectFBgfxdriver
  7. 2010.03.02 What are the relationships among the main DirectFB types? Screen, Layers, Surface, ...
  8. 2009.11.30 신규 칩셋 선택시 검토할 사항
  9. 2009.06.02 Unaligned memory access
  10. 2009.02.19 Comparison of lightweight web servers
  11. 2008.04.04 objcopy
  12. 2007.10.19 memory allocation
  13. 2007.08.30 CPU에서 사용하는 두가지 캐쉬
  14. 2005.11.22 리눅스 메모리 관리의 이해를 돕는 그림
  15. 2005.11.22 A Map of the Networking Code in Linux Kernel 2.4.20
  16. 2005.07.28 kernel 파라미터 조정하기
  17. 2005.07.27 printk 사용시 주의할 점...
  18. 2005.06.15 MIPS linux cross compiler 제작예제
  19. 2005.02.28 context switching animation(x86) - ucos
  20. 2004.06.13 strongarm의 명령 한라인 수행하는데 걸리는 클럭과 계산 하는 방법을 알고 싶습니다 ..
  21. 2004.06.13 왜 arm-linux-gcc에서는 #pragma pack이 안될까? (출처:www.kelp.or.kr)
  22. 2004.06.07 가상 메모리
  23. 2004.06.06 커널 디버깅 기능 활성화과정
  24. 2004.06.06 압축 해제 이후 커널 패치 과정
  25. 2003.12.10 [Q] relocation of bss and data
  26. 2003.12.01 Glabl변수의 초기화 및 영역
  27. 2002.12.04 커널에서 double형의 연산이 가능한가요?

shared library에서 export 된 함수 리스트를 보고 싶을 떄

-> objdump -t *.so


shared library의 dependancy를 알고 싶을 때

-> objdump -p *.so





저작자 표시 비영리 변경 금지
신고

커널에서 함수별 스택 사용량

Posted 2012.07.18 16:25

#arm-linux-objdump -d vmlinux | 커널소스경로/scripts/checkstak.pl arm

저작자 표시 비영리 변경 금지
신고

cgrep

Posted 2012.01.27 10:57
#!/bin/bash

function usage()
{
   echo 'cgrep grep pattern from *.[chSs] or *.cpp or *.hpp or *.mk or [Mm]akefile'
}

if [ $# -eq 0 ]; then
    usage
    exit 1
fi
 
find . -type f -name "*.[chSs]" -o -name "*.cpp" -o -name "*.hpp" -o -name "*.mk" -o -name "[Mm]akefile" | xargs grep --color=auto -n "$1"

                                                                                                                                                          

신고

export LC_ALL=C

Posted 2012.01.26 16:34
grep 등을 이용하여 패턴 검색을 할때, 예를 들어 아래 쉘스크립트와 같은 경우,

rev=`svn info 2>/dev/null`
rev=`echo "${rev}" | grep '^Revision' | awk '{print $NF}'`
설정된 로케일이 영문으로 설정된 경우는 문제없겠지만, 아래와 같이 한글로 설정된 경우에는 위 스크립트는 정상적으로 동작이 안될 것이다.

sunny@sunny-desk:~/project/01_WBS/0.2$ svn info
 경로: .
URL: https://svnhost/svn/ProjectRepo/trunk
저장소 루트: https://svnhost/svn/ProjectRepo
저장소 UUID: 0af9682f-c0b8-1742-9153-f717f418bd9a
리비전: 13
노드 종류: 디렉토리
스케쥴: 일반
마지막 수정 작업자: sunny
마지막 수정 리비전: 13
마지막 수정 일자: 2012-01-17 20:58:14 +0900 (2012-01-17, 화)

따라서, 시스템 로케일이 한글이 경우에도 쉘스크립트가 제대로 동작되게 하려면, 아래와 같이 export LC_ALL=C을 추가하면 된다.

export LC_ALL=C
rev=`svn info 2>/dev/null`
rev=`echo "${rev}" | grep '^Revision' | awk '{print $NF}'`


 sunny@sunny-desk:~/project/01_WBS/0.2$ svn info
Path: .
URL: https://svnhost/svn/ProjectRepo/trunk
Repository Root: https://svnhost/svn/ProjectRepo
Repository UUID: 0af9682f-c0b8-1742-9153-f717f418bd9a
Revision: 13
Node Kind: directory
Schedule: normal
Last Changed Author: sunny
Last Changed Rev: 13
Last Changed Date: 2012-01-17 20:58:14 +0900 (Tue, 17 Jan 2012)







신고

runtime control of printk times

Posted 2011.04.22 16:18

source URL: http://elinux.org/Printk_Times


You can enable and disable printk timestamps at runtime, by writing to /sys/module/printk/parameters/time.

# cat /sys/module/printk/parameters/time
N
# echo 1 >/sys/module/printk/parameters/time
# cat /sys/module/printk/parameters/time
Y
# echo "sample log message" >/dev/kmsg
# dmesg | tail
....
[3814526.197336] sample log message
신고
elc2008_directfb_gfx.pdf


신고

What are the relationships among the main DirectFB types?

There are several one-to-one and one-to-many relationships here:

  • 1 IDirectFB (top-level) <--> N Screens
  • 1 Screen <--> N Layers
  • 1 Layer <--> 1 Primary Surface
  • 1 Layer <--> N Windows
  • 1 Window <--> 1 Window Surface
  • 1 Surface <--> N Subsurfaces

The most common case is one screen with one display layer, but DFB supports multiple instances of each.

Layers and Screens

Each screen can have one or more layers. Usually, a screen will have only one, but system that support overlays may have multiple layers with the hardware letting one layer show through another.

Screens and Windows

A screen cannot directly create a window, but you can ask a screen for the ID of its primary layer, then ask the IDirectFB interface to give you an interface to that layer, then use that interface to create a window.

Surfaces and Windows

Each window has a surface associated with it; drawing to that surface isn't immediately visible on the screen, as the window manager is responsible for compositing the surfaces of the windows to the primary surface based on their update regions and the stacking order, and the window manager is notified of changes by using the Flip() method of the surface.

Surfaces and Layers

A layer also has a surface associated with it; this surface is a direct representation of the layer's screen memory. You can only access this surface when you're in exclusive mode, otherwise you need to create a window and have the window manager draw to the surface.

신고

Glibc 지원 여부 (uclibc만 지원하는 경우도 있음. (broadcom))

frambuffer driver 지원 여부 - 지원하지 않는 경우도 있음.

DirectFB 지원 여부

신고

Unaligned memory access

Posted 2009.06.02 17:19

The problem starts in the memory chip. Memory is capable to read certain number of bytes at a time. If you try to read from unaligned memory address, your request will cause RAM chip to do two read operations. For instance, assuming RAM works with units of 8 bytes, trying to read 8 bytes from relative offset of 5 will cause RAM chips to do two read operations. First will read bytes 0-7. Second will read bytes 8-15. As a result, the relatively slow memory access will become even slower.

diagram1.png

신고

Comparison of lightweight web servers

Posted 2009.02.19 02:17

Comparison of lightweight web servers

From Wikipedia, the free encyclopedia

Jump to: navigation, search

Lightweight web servers are Web servers which have been designed to run with very small resource overhead because of hardware, environment, or simply for the challenge of it.

Many of these systems have been created as a mental exercise to determine if a modern webserver could be written to run on limited resources such as those provided in a graphing calculator, a Commodore 64, or in 64 kB (64 KiB) total of memory. Others have been written as commercial endeavors to create webservers with low overhead for embedded systems (network router configuration pages) or low memory environments.

[edit] Overview

Server  ↓ Creator  ↓ Operating Systems  ↓ Development Language  ↓ Software license  ↓ Size (kB)  ↓ Last Stable Version  ↓ Home  ↓
0W Maxim Zotov Linux and FreeBSD C BSD-like 111
[1]
Abyss Aprelium Windows, Linux, Mac OS X and FreeBSD
Closed source 455
[2]
ebb Ryah Dahl Linux Ruby MIT ?
[3]
thin Marc-André Cournoyer Linux Ruby Ruby [4] ?
[5]
Anti-Web httpd Doug Hoyte and others Linux, Win32 C GPL ?
[6]
AppWeb Mbedthis/ Michael O'Brien Windows, Linux, FreeBSD, Mac OS X, VxWorks C++ GPL / Dual License [7] 350
[8]
Arachnida HTTP(S) server and client Ronald Landheer-Cieslak Windows, Linux, POSIX C++ GPL/BSD Dual License 500
[9]
Redleafd Alfeiks Kaänoken (MadTirra/Tirra) Linux C/Scheme GPL 200
[10]
BadBlue Working Resources Inc. Windows C++ Closed source 703
[11]
BarracudaDrive Real Time Logic Windows, Embedded Linux, Mac PowerPC
Closed source 713
[12]
Barracuda Web Server SDK Real Time Logic Unix, Windows, Mac, and most embedded systems C and Lua Closed source 100 - 500
[13]
Boa ? Unix C, Perl GPL [14] 120 0.94.14rc21 (2005-02-23) [15]
astahttpd Rio Astamal Linux PHP 5.2.x GPL 520
[16]
bozohttpd Matthew R. Green Unix C BSD 32
[17]
Cherokee Álvaro López Ortega Linux, Solaris, *BSD, Windows C GPL 686
[18]
cgttpd Davide Libenzi Linux C
?
[19]
chttpd Greg Olszewski Linux/Win32 C
17
[20]
cheetah Luke Reeves Linux C GPLv2 17
[21]
CoreHTTP ? Linux C GPL [22] 25
[23]
Dandelion Graeme Pietersz Linux, Windows, MacOS, Unix, any on which Tcl runs Tcl GPLv2, GPLv3 45
[24]
Darkhttpd Emil Mikulic UNIX C BSD ?
[25]
Devwex Seanox Software Solutions Any OS with Java 1.2 or higher Java Closed source 30
[26] (German)
dlib C++ http server Davis E. King Linux, Solaris, Windows, Mac OS X, BSD C++ Boost Software License [27] 10
[28]
FlyingAnt CD Web Server Wrensoft Windows, Linux, Mac OS X
Closed source 50
[29]
Fnord
Linux C GPLv2 18
[30]
foXServe Kdev/Davide Cantaluppi Embedded LX 832 fox board
Apache ?
[31]
Gforth httpd Bernd Paysan POSIX-style OS Forth GPL 273 SLOC
[32]
Mathopd Michiel Boland POSIX-style OS C ? 79 1.5 (2007-07-21) [33]
GoAhead WebServer GoAhead VxWorks, Windows CE, Windows, Lynx, Linux, QNX, eCOS, QNX, Netware, OS X, ChorusOS, pSOS, uCOS, IRIX, HP-UX, RTEMS, iRMX/INtime C Dual License [34] 110
[35]
Hiawatha Hugo Leisink Linux, BSD, Mac OS X, Windows C GPL [36] 100
[37]
HTTP File Server Massimo Melina (aka rejetto) Windows Delphi GPL 500
[38]
HTTPi Cameron Kaiser Unix Perl Floodgap Free Software License (FFSL) [39] 58
[40]
ihttpd ? Unix C
40
[41]
KLone KoanLogic Linux, NetBSD, OpenBSD, FreeBSD, QNX, VxWorks, Darwin/Mac OS X, Windows C GPL 200
[42]
Kolibri SENKAS Windows C++ GPL ?
[43]
Kolibri+ SENKAS Windows C++ Closed source ?
[44]
leahhtpd GNU Unix, Linux, Windows C
?
[45]
libmicrohttpd GNU Unix, Linux, Windows C LGPL 25
[46]
libwebserver Luis Figueiredo Unix, Linux, Windows C LGPL [47] 231
[48]
lighttpd Jan Kneschke Unix, Linux, Windows C BSD [49] ? 1.4.20 (Sep 30, 2008) [50]
Lite Netquestion HTTP Web Server ? AIX

28
?
Mongoose Sergey Lyubka Windows, QNX, *BSD, Solaris, Linux, Portable to any OS C MIT 40 2.3 [51]
Monkey HTTP Daemon Eduardo Silva Linux C GPLv2 45
[52]
muhttpd Robbert Haarman UNIX C ? 25
[53]
NaninHttpd ? All Ruby Ruby
14
[54]
NanoHTTPD Jarno Elonen Any OS with Java 1.1 or higher Java Modified BSD 28
[55]
Webserver included with JRE 1.6+ Sun Any OS with Java 1.6 or higher Java Sun Java license 0 (already included with java libraries)
[56]
NanoWeb Vincent Negrier, Mario Salzer, and others Any that supports PHP PHP 4.3
?
[57]
nginx Igor Sysoev Unix-like C BSD 468 0.6.34 (Nov 27, 2008) [58]
NicheStack HTTP Server InterNiche Technologies [59] Any 16 or 32bit embedded C Closed source 9 v3.1 [60]
nostromo - nhttpd Marcus Glocker Unix-like, OpenBSD developed C MIT 55
[61]
Null httpd ? Linux, Windows[1] C
52
[62]
nweb ? Unix C
36
[63]
Obelisk-HTTP Filipe Caldas Any OS with Python Python
50 0.4.4 (Sep 27, 2007) [64]
PS-HTTPD Anders Karlsson
PostScript GPL 8
[65]
publicfile Dan J. Bernstein Any POSIX OS C Public Domain 29
[66]
qshttpd Cosmin Gorgovan Unix C GPL 16
[67]
Rupy ? Any OS with Java 1.4 or higher Java LGPL 45
[68]
SAS ? Linux Assembly
0.941
[69]
Seminole GladeSoft eCos, VxWorks, POSIX, Win32, uCOS C
?
[70]
Shttp Yingyuan Cheng Linux C GPLv2 16
[71]
Simple HTTPD Charlie Lee Unix C
12
[72]
Spud ? Embedded PIC16F876

1
[73]
SWILL David Beazley and Sotiria Lampoudi Windows, Unix C
116
[74]
Techlogica HTTP Server Kyle White Windows

292
[75]
thttpd Acme Labs Unix C
50[2] 2.25b (2003-12-29) [76]
TinyWeb Maxim Masiutin Win32 Delphi
53
[77]
Tntnet Tommi Mäkitalo Unix C++ LGPL 940
[78]
UIP Adam Dunkels Embedded 8bit C
?
[79]
VQEmbWeb Gareth Cronin Any OS with support for Java 5 Java
12
[80]
webAce Fredric White Embedded Fairchild ACE1101MT8[3] ACE1101MT8 microcontroller instructions
1 (1074 bytes)[3]
http://d116.com/ace/
wxWebServer Fedja Stevanovic Windows, Mac OS X, Linux C++
?
[81]
Allegro Embedded WebServer ? Portable to any OS C ? ?
[82]
Mini httpd Jef Poskanzer UNIX C GPL 41
[83]
Micro HTTPD Jef Poskanzer UNIX C GPL 4.98
[84]
JS httpd Jef Poskanzer UNIX Javascript GPL 4.16
[85]
Plain Old Webserver David Kellogg Any OS Mozilla Firefox runs on Javascript GPL 80.1
[86]
Pure Perl CGId Erik Aronesty Any OS perl runs on Perl GPL 11.5
[87]
Wt emweb Linux/BSD/Solaris/..., Windows 2000/XP/Vista, Mac OS X, Others C++ GPL/Commercial Dual License [88] 250
[89]
Xavante The Kepler Project Linux, BSD, Windows, Mac OS X, Others Lua GPL compatible 38
[90]
ZwebServer http://zotagsearch.com/euphorica/#aboutme[dead link] Travis Cunningham[clarification needed] Windows 2000/XP/Vista C#
132
http://zotagsearch.com/zwebserver/[dead link]
Server Creator Operating Systems Development Language License Size (kB) Latest Stable Version Home

[edit] See also

[edit] References

  1. ^ NullLogic. NullLogic - Projects. Retrieved 2009-01-18
  2. ^ "Web Server Comparisons (July 1998)". acme.com. http://www.acme.com/software/thttpd/benchmarks.html. 
  3. ^ a b Fredric White. webACE Server. 2001-08-05. Retrieved 2009-01-18
신고

'Research > SystemProg' 카테고리의 다른 글

신규 칩셋 선택시 검토할 사항  (0) 2009.11.30
Unaligned memory access  (0) 2009.06.02
Comparison of lightweight web servers  (0) 2009.02.19
objcopy  (0) 2008.04.04
memory allocation  (0) 2007.10.19
CPU에서 사용하는 두가지 캐쉬  (0) 2007.08.30

objcopy

Posted 2008.04.04 15:26
출처 : http://blog.naver.com/letov/70012723177


objcopy는 오브젝트 파일을 다른 오브젝트 파일로 복사할 때 사용한는데, 선택적으로 필요한 부분만
을 복사할 수 있기 때문에 파일의 사이즈를 줄이는 데 주로 사용되고, 바이너리 포맷을 바꾸는 데도 이
용된다.
ex) objcopy hello hello.new
hello 파일을 hello.new로 복사, 기존의 hello와 동일하다.
ex) objcopy -O binary hello hello.new
위 명령은 hello 파일에서 인스트럭션과 데이터만을 뽑아서 hello.new로 만든다. 이렇게 만들어진
hello.new는 ELF 헤더도 붙지 않은 순수한 바이너리 그 자체다. 주로 부트 로더를 만들 때 이런 식으
로 사용하는데 이유는 모든 CPU마다 전원이 인가되었을 때 CPU가 인스트럭션을 처음 읽어서 실행할
번지가 정해져 있다. 예를 들면 i386 계열은 0xfffffff0 번지이고 ARM 계열 CPU는 0x0 번지며
MPC860 CPU 같은 경우 0xff00100번지다.
무슨 말이냐하면 i386 계열 CPU는 전원이 켜지는 순간 BIOS의 POST(Power On Self Test) 프로그
램이 위치하는 0xfffffff0 번지의 인스트럭션을 제일 처음 읽어서 수행한다.
i386 PC 외의 CPU 같은 경우 처음 수행하는 프로그램은 부트 로더인데 이러한 부트 로더는 인스트럭
션이 제일 앞에 와있는 바이너리여야 한다. 즉 ELF 헤더가 붙어서는 안 된다는 이야기다. ELF 헤더는
운영체제에서 필요한 정보지 CPU에서 필요한 정보는 아니다.
ex) objcopy -S hello hello.new
모든 심볼들과 재비치 정보들을 제거하여 hello.new 파일을 만든다. 그래서 바이너리 파일의 사이즈가
확실히 줄어든다.
- 참고 문헌 : 유닉스, 리눅스 프로그래밍 필수 유틸리디
신고

'Research > SystemProg' 카테고리의 다른 글

Unaligned memory access  (0) 2009.06.02
Comparison of lightweight web servers  (0) 2009.02.19
objcopy  (0) 2008.04.04
memory allocation  (0) 2007.10.19
CPU에서 사용하는 두가지 캐쉬  (0) 2007.08.30
리눅스 메모리 관리의 이해를 돕는 그림  (0) 2005.11.22

memory allocation

Posted 2007.10.19 16:30
06MemoryAllocation.ppt
신고

'Research > SystemProg' 카테고리의 다른 글

Comparison of lightweight web servers  (0) 2009.02.19
objcopy  (0) 2008.04.04
memory allocation  (0) 2007.10.19
CPU에서 사용하는 두가지 캐쉬  (0) 2007.08.30
리눅스 메모리 관리의 이해를 돕는 그림  (0) 2005.11.22
A Map of the Networking Code in Linux Kernel 2.4.20  (0) 2005.11.22

CPU에서 사용하는 두가지 캐쉬

Posted 2007.08.30 10:45
※ CPU에서 사용하는 두가지 캐쉬



Write Back(Behind) → 80486이후 마이크로 프로세서에서 사용하는 방식인데,



L1 Cache(명령어캐쉬)에 저장된 데이타가 필요할 경우에만 주메모리에 기록됩니다.



기록시에는 CPU 대기(CPU Wait-State)시간을 사용해서 후면작업(백그라운드)을



하듯이 데이타 기록(Write)과정을 처리합니다.




Write Through → 데이타 쓰기작업을 L1캐쉬와 주메모리에서 필요시에는 동시에



병렬로 처리합니다. 유휴시간이 아니라 그때그때 바로바로 데이타 쓰기작업을 합니다.



캐쉬에 쓰기작업중에 캐쉬에 대한 데이타 읽기가 요구될 경우에도 동시 작업으로



처리합니다. Write Back은 동시 요구시에 읽기가 끝난후에 쓰기작업을 재계합니다.



낙후된 기술로, Write Back보다 효율면에서 뒤떨어지는 방식입니다
신고

'Research > SystemProg' 카테고리의 다른 글

objcopy  (0) 2008.04.04
memory allocation  (0) 2007.10.19
CPU에서 사용하는 두가지 캐쉬  (0) 2007.08.30
리눅스 메모리 관리의 이해를 돕는 그림  (0) 2005.11.22
A Map of the Networking Code in Linux Kernel 2.4.20  (0) 2005.11.22
kernel 파라미터 조정하기  (0) 2005.07.28
...
신고
--
신고

kernel 파라미터 조정하기

Posted 2005.07.28 16:47
보통 커널의 파라미터를 조정할때 proc 에서 echo 를 이용하여 redirect
로 직접 쓰는 경우가 많았다. 이렇게 조정을 할 경우에는 또 rc.local 같
은 파일에 따로 기입을 해 줘야 하는 불편함이 있었다.

RedHat 6.2 이후 배포판에는 sysctl 이라는 package가 추가되어 이것들을
관리를 할수 있게 되었다. 일단 조정할수 있는 모든 parameter 들은

$ sysctl -a

명령으로 확인을 할수가 있다. 그리고 특정값을 수정하기 위해서는
/etc/sysctl.conf 에 해당 키(이건 sysctl -a 명령에서 리스트를 확인
할수 있다)와 키값을 지정한 다음

$ sysctl -p

명령으로 바로 적용을 시킬수 있다. 물론 sysctl.conf 에 기입이 되면
부팅시 마다 자동으로 적용이 된다.

만약 잠시만 바꾸어 보고 싶다면

$ sysctl -w net.ipv4.icmp_echo_ignore_all=0

과 같이 직접 값을 넣어 줄수도 있다. 이럴 경우에는 부팅이 되어 있는
순간만 적용이 된다. -p 옵션은 sysctl.conf 가 아닌 다른 파일을 설정
파일로 지정을 할수 있게 한다. 옵션값이 없으면 default 로
/etc/sysctl.conf 를 읽어 들이며 따로 path 를 지정하면 해당 path 에
있는 파일을 읽어 들인다.


신고

printk 사용시 주의할 점...

Posted 2005.07.27 10:41
타입을 주의하여 사용하여야 한다. 가령 예를 들어, 다음에서 보면,

static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
{
     struct mtd_part *part = PART(mtd);

     if ((len + ofs) > mtd->size)
         return -EINVAL;
     printk(__FUNCTION__ ": ofs = %Lx, part->offset = %lx, len = %lx n", ofs, part->offset, (unsigned int)len);
     return part->master->unlock(part->master, ofs + part->offset, len);
}

ofs는 loff_t 타입인데, loff_t 타입은 long long 타입의 typedef 이다.
따라서, ofs 값을 표시할 때, 위와 같이 %L (L은 long long type) 을 사용하지 않고, %l 이나, %x 등을 사용하면,
ofs 값이 제대로 출력되지 않을 뿐 아니라, 뒤에 출력하는 값마저 영향을 받아서 엉뚱한 값이 출력된다.
신고

MIPS linux cross compiler 제작예제

Posted 2005.06.15 11:49
http://kelp.or.kr/korweblog/?story=04/06/04/0386624 KELP - Korea Embedded Linux Project 제목: MIPS linux cross compiler 제작예제

글쓴이: 이영진
글쓴날: 2004년 06월 04일 오후 08:59
URL : http://kelp.or.kr/korweblog/?story=04/06/04/0386624


안녕하세요. (주) 시그마컴 연구 3팀입니다.
ARM에 비해 상대적으로 이용자가 적은 MIPS에 관련된 글을 하나 올리겠습니다.

http://www.gnu.org에서 binutils, gcc, glibc, glibc-linuxthread를 다운 받는다.

작업디렉토리 : $(WORK) 에 다운 받은 파일들이 놓여있다고 가정한다. 굳이 target이란 디렉토리 밑에 작업 환경을 꾸민 이유는 관리하기에 단순무식해서 편하다는 장점때문이다. 작업한 시스템은 Mandrake 1.0 community 인가 하는 버전이고 binutil-2.15, gcc-3.4.0, glibc-2.3.2이며 따로 패치된 것이 아니다.
http://laronde.org/~brad/mips/mips-cross-toolchain/ 이 싸이트의 것을 그대로 따라한다. 또한 http://www.kegel.com/crosstool 에서도 많은 도움을 얻었다.

1 binutils
별로 어려운게 없다. 그냥 설치할 위치를 지정해 주고 target에다가 mipsel-linux 혹은 mips-linux를 적용해 주면 된다. libdir은 뭔지 나도 잘 모르겠다.

$ cd $(WORK)
$ tar xjf binutils-??.bz2
$ mkdir target; cd target; mkdir binutils
$ cd binutils
$ $(WORK)/binutils-??/configure --prefix=/opt/host/mispel-linux
--target=mipsel-linux --libdir='${exec_prefix}'/mipsel-linux/i386-linux/lib
$ make
$ sudo make install


2. static gcc #
완전한 gcc를 만들기 위해서는 glibc가 필요하지만 아직 glibc를 빌드 하기 전이다. 따라서 static버전의 c언어 컴파일러부터 제작한후에 glibc를 빌드하고 다시 gcc를 빌드하는 과정을 거친다. 이 과정에서 static gcc를 빌드 하기 위해서는 커널 헤더 파일과 시스템 헤더 파일이 필요하다. 다른 곳에서 만들어진 크로스 컴파일러의 것을 복사하거나 단순히 호스트의 /usr/include를 임시로 복사해서 사용할 수도 있다. 단 이때에도 커널 헤더파일은 해당 타겟 시스템 것을 복사하는 것이 좋다. 물론 이 방법들은 모두 에러 가능성을 다분히 지니고 있는 단점이 있다. 이 예제에서는 시스템 헤더 파일(/usr/include)을 작업 디렉토리에 복사하고 asm, asm-generic, linux 디렉토리를 커널 것으로 대체했다.
* 저도 이게 어느 수준의 헤더가 필요한지 잘 몰라서요. 보통은 비슷한 버전 대의 기존 도구의 헤더를 슬쩍 빌립니다. ^_^
binutils을 인스톨 한 후에 그 PATH의 바이너리들을 PATH에 걸어둔다. configure시에 enable-language 는 c만 지정하고 disable_shared옵션을 걸고 앞서 설명한 헤더 파일이 존재하는 디렉토리를 with-headers로 지정한다.

$ export PATH=/opt/host/mipsel-linux/bin:$PATH
$ cd $(WORK)
$ tar xjf gcc-??.bz2
$ cd target; mkdir gcc
$ cd gcc
$ sudo $(WORK)/gcc-??/configure --prefix=/opt/host/mipsel-linux
--target=mipsel-linux --enable-languages=c --disable-shared
--with-headers=/home/romntica/CCK/test/include
$ make
$ sudo make install
configure시에 sudo를 하는 것은 지정한 헤더파일($with-headers)과 함께 필요한 파일들을 $prefix/mipsel-linux/sys-include로 복사 하기 때문이다.

3 glibc #
자 이제 말도 많고 탈도 많은 glibc를 만들어보자. 많은 사람들이 이 부분에서 어려움을 호소하거나 포기하는 경우가 있다. 그렇지만 어려울 것 없다. 검색 엔진을 활용하면 된다.
google에서 mips glibc로 검색을 해보았더니 관련 패치에 관한 사이트가 몇 개 나왔다. 내용들을 잘 살펴보고 필요한 것을 적용하기만 하면 된다. 이 예제에서는 다음의 패치를 적용하였다. 물론 여기서 사용된 패치가 꼭 필요하거나 전혀 필요치 않다거나의 여부는 따지지 않는다. 꼭 이것뿐 만이 아니고 개발하려는 장치명으로 검색하시면 gcc나 binutils나 glibc에도 적용할 만한 유용한 패치가 많이 있습니다. 예를 들어 제가 도시바 TX49계열의 칩을 사용했는데 그냥 하면 MULTX인가?? 곱셈연산자를 활용을 못하는 것을 binutils를 패치하고나면 해당 연산자를 사용할 수 있게 해주는 패치가 있었습니다.
우선 linuxthread를 add-on하기 위해 glibc-?? 디렉토리의 서브디렉토리로 압축 해제해준다.
$ cd $(WORK)
$ tar xjf glibc-??.bz2
$ cd glibc-??
$ cd $(WORK)/target; mkdir glibc
$ cd glibc
$ tar xjf ../glibc-linuxthread-??.bz2

그리고 다음의 패치를 적용한다. (죄송합니다. 컴파일 전에 diff를 때렸어야 했는데 clean해도 깨끗이 안되는군요. 파일이 너무 커지다보니 실수로 지워버린 것도 있을 것입니다. 문의하시면 답변해 드리겠습니다.)
diff -urN glibc-2.3.2/Makeconfig glibc-2.3.2-fixed/Makeconfig
--- glibc-2.3.2/Makeconfig 2003-01-06 05:31:36.000000000 +0000
+++ glibc-2.3.2-fixed/Makeconfig 2004-06-04 16:39:10.711288024 +0000
@@ -637,7 +637,7 @@
$(foreach lib,$(libof-$(basename $(@F)))
$(libof-$(<F)) $(libof-$(@F)),$(CPPFLAGS-$(lib)))
$(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F)))
-override CFLAGS = -std=gnu99
+override CFLAGS = -std=gnu9x
$(filter-out %frame-pointer,$(+cflags)) $(sysdep-CFLAGS)
$(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) $(CFLAGS-$(@F))

diff -urN glibc-2.3.2/elf/dl-conflict.c glibc-2.3.2-fixed/elf/dl-conflict.c
--- glibc-2.3.2/elf/dl-conflict.c 2002-10-17 17:05:51.000000000 +0000
+++ glibc-2.3.2-fixed/elf/dl-conflict.c 2004-06-04 13:48:20.897496568 +0000
@@ -33,6 +33,7 @@
_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
ElfW(Rela) *conflictend)
{
+#ifndef _DL_HAVE_NO_ELF_MACHINE_RELA
if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_RELOC, 0))
_dl_printf ("nconflict processing: %sn",
l->l_name[0] ? l->l_name : rtld_progname);
@@ -64,4 +65,5 @@
for (; conflict < conflictend; ++conflict)
elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset);
}
+#endif
}
--- glibc-2.3.2/resolv/Makefile 2003-02-25 23:40:08.000000000 +0000
+++ glibc-2.3.2-fixed/resolv/Makefile 2004-06-04 18:46:07.402374976 +0000
@@ -93,6 +93,8 @@
tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
$(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@
+ifeq (no,$(cross-compiling))
ifneq (no,$(PERL))
tests: $(objpfx)mtrace-tst-leaks
endif
+endif
diff -urN glibc-2.3.2/stdio-common/sscanf.c glibc-2.3.2-fixed/stdio-common/sscanf.c
--- glibc-2.3.2/stdio-common/sscanf.c 2002-08-10 18:09:08.000000000 +0000
+++ glibc-2.3.2-fixed/stdio-common/sscanf.c 2004-06-04 14:15:10.784756504 +0000
@@ -27,9 +27,7 @@
/* Read formatted input from S, according to the format string FORMAT. */
/* VARARGS2 */
int
-sscanf (s, format)
- const char *s;
- const char *format;
+sscanf (const char *s, const char *format, ...)
{
va_list arg;
int done;
diff -urN glibc-2.3.2/string/bits/string2.h glibc-2.3.2-fixed/string/bits/string2.h
--- glibc-2.3.2/string/bits/string2.h 2002-05-25 06:09:18.000000000 +0000
+++ glibc-2.3.2-fixed/string/bits/string2.h 2004-06-04 17:50:57.070621896 +0000
@@ -76,7 +76,7 @@
use unaligned memory accesses. */
# define __STRING2_COPY_TYPE(N)
typedef struct { unsigned char __arr[N]; }
- __STRING2_COPY_ARR##N __attribute__ ((packed))
+ __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
__STRING2_COPY_TYPE (2);
__STRING2_COPY_TYPE (3);
__STRING2_COPY_TYPE (4);
diff -urN glibc-2.3.2/sysdeps/mips/Makefile glibc-2.3.2-fixed/sysdeps/mips/Makefile
--- glibc-2.3.2/sysdeps/mips/Makefile 2000-09-06 20:26:50.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/mips/Makefile 2004-06-04 17:53:16.754386736 +0000
@@ -6,3 +6,11 @@
ifeq ($(subdir),setjmp)
sysdep_routines += setjmp_aux
endif
+
+ifeq ($(subdir),csu)
+ifeq (yes,$(build-shared))
+# Compatibility
+sysdep_routines += divdi3
+shared-only-routines += divdi3
+endif
+endif
diff -urN glibc-2.3.2/sysdeps/mips/dl-machine.h glibc-2.3.2-fixed/sysdeps/mips/dl-machine.h
--- glibc-2.3.2/sysdeps/mips/dl-machine.h 2003-02-12 09:42:22.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/mips/dl-machine.h 2004-06-04 13:49:03.153072744 +0000
@@ -55,7 +55,9 @@
to avoid the asserts in dl-lookup.c from blowing. */
#define ELF_MACHINE_JMP_SLOT R_MIPS_REL32
#define elf_machine_type_class(type) ELF_RTYPE_CLASS_PLT
-
+
+/* MIPS doesn't support RELA */
+#define _DL_HAVE_NO_ELF_MACHINE_RELA
/* Translate a processor specific dynamic tag to the index
in l_info array. */
#define DT_MIPS(x) (DT_MIPS_##x - DT_LOPROC + DT_NUM)
diff -urN glibc-2.3.2/sysdeps/mips/mips64/bsd-_setjmp.S glibc-2.3.2-fixed/sysdeps/mips/mips64/bsd-_setjmp.S
--- glibc-2.3.2/sysdeps/mips/mips64/bsd-_setjmp.S 2002-12-31 19:13:27.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/mips/mips64/bsd-_setjmp.S 2004-06-04 13:55:25.649924384 +0000
@@ -22,6 +22,7 @@
in setjmp doesn't clobber the state restored by longjmp. */

#include <sysdep.h>
+#include <sys/asm.h>

#ifdef __PIC__
.option pic2
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/bits/mman.h glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/bits/mman.h
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/bits/mman.h 2001-07-07 19:21:35.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/bits/mman.h 2004-06-04 14:02:26.079009448 +0000
@@ -59,6 +59,8 @@
# define MAP_DENYWRITE 0x2000 /* ETXTBSY */
# define MAP_EXECUTABLE 0x4000 /* mark it as an executable */
# define MAP_LOCKED 0x8000 /* pages are locked */
+# define MAP_POPULATE 0x10000
+# define MAP_NONBLOCK 0x20000
#endif

/* Flags to `msync'. */
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/bits/siginfo.h glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/bits/siginfo.h
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/bits/siginfo.h 2002-12-05 00:22:19.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/bits/siginfo.h 2004-06-04 13:59:42.053945048 +0000
@@ -119,8 +119,10 @@
signals. */
enum
{
- SI_ASYNCNL = -6, /* Sent by asynch name lookup completion. */
+ SI_ASYNCNL = -60, /* Sent by asynch name lookup completion. */
# define SI_ASYNCNL SI_ASYNCNL
+ SI_TKILL = -6,
+# define SI_TKILL SI_TKILL
SI_SIGIO, /* Sent by queued SIGIO. */
# define SI_SIGIO SI_SIGIO
SI_MESGQ, /* Sent by real time mesq state change. */
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/clone.S glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/clone.S
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/clone.S 2001-07-07 19:21:35.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/clone.S 2004-06-04 13:09:34.246201328 +0000
@@ -63,7 +63,7 @@
syscall

bnez a3,error
- beqz v0,__thread_start
+ beqz v0,.Lthread_start

/* Successful return from the parent */
addiu sp,32
@@ -85,6 +85,7 @@
debug info. */

ENTRY(__thread_start)
+.Lthread_start:
/* cp is already loaded. */
.cprestore 16
/* The stackframe has been created on entry of clone(). */
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/kernel_stat.h glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/kernel_stat.h
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/kernel_stat.h 2000-11-20 08:45:43.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/kernel_stat.h 2004-06-04 15:51:16.873177824 +0000
@@ -1,3 +1,5 @@
+#ifndef _KERNEL_STAT_H
+#define _KERNEL_STAT_H 1
/* Definition of `struct stat' used in the kernel.. */
struct kernel_stat
{
@@ -26,3 +28,4 @@
unsigned int st_flags;
unsigned int st_gen;
};
+#endif
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pread.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pread.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pread.c 2003-01-27 18:55:20.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pread.c 2004-06-04 14:09:59.519076080 +0000
@@ -34,6 +34,24 @@
# endif
# define __NR_pread __NR_pread64
#endif
+#ifdef __NR_O32_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_O32_pread
+# error "__NR_O32_pread and __NR_O32_pread64 both defined???"
+# endif
+# define __NR_O32_pread __NR_O32_pread64
+#endif
+#ifdef __NR_N32_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N32_pread
+# error "__NR_N32_pread and __NR_N32_pread64 both defined???"
+# endif
+# define __NR_N32_pread __NR_N32_pread64
+#endif
+#ifdef __NR_N64_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N64_pread
+# error "__NR_N64_pread and __NR_N64_pread64 both defined???"
+# endif
+# define __NR_N64_pread __NR_N64_pread64
+#endif

#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0

diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pread64.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pread64.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pread64.c 2003-01-27 18:55:20.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pread64.c 2004-06-04 14:10:25.987052336 +0000
@@ -33,6 +33,25 @@
# endif
# define __NR_pread __NR_pread64
#endif
+#ifdef __NR_O32_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_O32_pread
+# error "__NR_O32_pread and __NR_O32_pread64 both defined???"
+# endif
+# define __NR_O32_pread __NR_O32_pread64
+#endif
+#ifdef __NR_N32_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N32_pread
+# error "__NR_N32_pread and __NR_N32_pread64 both defined???"
+# endif
+# define __NR_N32_pread __NR_N32_pread64
+#endif
+#ifdef __NR_N64_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N64_pread
+# error "__NR_N64_pread and __NR_N64_pread64 both defined???"
+# endif
+# define __NR_N64_pread __NR_N64_pread64
+#endif
+

#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0

diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pwrite.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pwrite.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pwrite.c 2003-01-27 18:55:20.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pwrite.c 2004-06-04 14:11:12.383998928 +0000
@@ -34,6 +34,24 @@
# endif
# define __NR_pwrite __NR_pwrite64
#endif
+#ifdef __NR_O32_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_O32_pwrite
+# error "__NR_O32_pwrite and __NR_O32_pwrite64 both defined???"
+# endif
+# define __NR_O32_pwrite __NR_O32_pwrite64
+#endif
+#ifdef __NR_N32_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N32_pwrite
+# error "__NR_N32_pwrite and __NR_N32_pwrite64 both defined???"
+# endif
+# define __NR_N32_pwrite __NR_N32_pwrite64
+#endif
+#ifdef __NR_N64_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N64_pwrite
+# error "__NR_N64_pwrite and __NR_N64_pwrite64 both defined???"
+# endif
+# define __NR_N64_pwrite __NR_N64_pwrite64
+#endif

#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0

diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pwrite64.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pwrite64.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pwrite64.c 2003-01-27 18:55:20.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pwrite64.c 2004-06-04 14:11:34.494637600 +0000
@@ -33,7 +33,24 @@
# endif
# define __NR_pwrite __NR_pwrite64
#endif
-
+#ifdef __NR_O32_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_O32_pwrite
+# error "__NR_O32_pwrite and __NR_O32_pwrite64 both defined???"
+# endif
+# define __NR_O32_pwrite __NR_O32_pwrite64
+#endif
+#ifdef __NR_N32_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N32_pwrite
+# error "__NR_N32_pwrite and __NR_N32_pwrite64 both defined???"
+# endif
+# define __NR_N32_pwrite __NR_N32_pwrite64
+#endif
+#ifdef __NR_N64_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N64_pwrite
+# error "__NR_N64_pwrite and __NR_N64_pwrite64 both defined???"
+# endif
+# define __NR_N64_pwrite __NR_N64_pwrite64
+#endif
#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0

extern ssize_t __syscall_pwrite (int fd, const void *__unbounded buf, size_t count,
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/syscalls.list glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/syscalls.list
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/syscalls.list 2003-01-31 03:39:32.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/syscalls.list 2004-06-04 17:54:47.274625568 +0000
@@ -32,50 +32,12 @@
socket - socket i:iii __socket socket
socketpair - socketpair i:iiif __socketpair socketpair

-#
-# These are defined locally because the caller is also defined in this dir.
-#
-s_llseek llseek _llseek i:iiipi __syscall__llseek
-s_sigaction sigaction sigaction i:ipp __syscall_sigaction
-s_ustat ustat ustat i:ip __syscall_ustat
-sys_mknod xmknod mknod i:sii __syscall_mknod
-
# System calls with wrappers.
+s_readahead EXTRA readahead i:iipi __syscall_readahead
rt_sigaction - rt_sigaction i:ippi __syscall_rt_sigaction
rt_sigpending - rt_sigpending i:pi __syscall_rt_sigpending
rt_sigprocmask - rt_sigprocmask i:ippi __syscall_rt_sigprocmask
rt_sigqueueinfo - rt_sigqueueinfo i:iip __syscall_rt_sigqueueinfo
rt_sigsuspend - rt_sigsuspend i:pi __syscall_rt_sigsuspend
rt_sigtimedwait - rt_sigtimedwait i:pppi __syscall_rt_sigtimedwait
-s_execve EXTRA execve i:spp __syscall_execve
-s_exit _exit exit i:i __syscall_exit
-s_fcntl fcntl fcntl i:iiF __syscall_fcntl
-s_fcntl64 fcntl64 fcntl64 i:iiF __syscall_fcntl64
-s_fstat64 fxstat64 fstat64 i:ip __syscall_fstat64
-s_ftruncate64 ftruncate64 ftruncate64 i:iiii __syscall_ftruncate64
-s_getcwd getcwd getcwd i:pi __syscall_getcwd
-s_getdents getdents getdents i:ipi __syscall_getdents
-s_getdents64 getdents getdents64 i:ipi __syscall_getdents64
-s_getpriority getpriority getpriority i:ii __syscall_getpriority
-s_ipc msgget ipc i:iiiip __syscall_ipc
-s_lstat64 lxstat64 lstat64 i:sp __syscall_lstat64
-s_mmap2 mmap64 mmap2 b:aniiii __syscall_mmap2
-s_poll poll poll i:pii __syscall_poll
-s_pread64 pread64 pread i:ibniii __syscall_pread
-s_ptrace ptrace ptrace i:iipp __syscall_ptrace
-s_pwrite64 pwrite64 pwrite i:ibniii __syscall_pwrite
-s_readahead EXTRA readahead i:iiii __syscall_readahead
-s_reboot reboot reboot i:iii __syscall_reboot
-s_setrlimit setrlimit setrlimit i:ip __syscall_setrlimit
-s_sigpending sigpending sigpending i:p __syscall_sigpending
-s_sigprocmask sigprocmask sigprocmask i:ipp __syscall_sigprocmask
-s_stat64 xstat64 stat64 i:sp __syscall_stat64
-s_truncate64 truncate64 truncate64 i:siii __syscall_truncate64

-# Todo: we can pass 6 args in registers, no need for the wrapper
-sys_sysctl sysctl _sysctl i:p __syscall__sysctl
-sys_fstat fxstat fstat i:ip __syscall_fstat
-sys_lstat lxstat lstat i:sp __syscall_lstat
-sys_readv readv readv i:ipi __syscall_readv
-sys_stat xstat stat i:sp __syscall_stat
-sys_writev writev writev i:ipi __syscall_writev
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/xstatconv.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/xstatconv.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/xstatconv.c 2001-07-07 19:21:35.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/xstatconv.c 2004-06-04 15:47:51.887340408 +0000
@@ -18,6 +18,11 @@
02111-1307 USA. */

#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <string.h>


static inline int
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/sys/epoll.h glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/sys/epoll.h
--- glibc-2.3.2/sysdeps/unix/sysv/linux/sys/epoll.h 2002-12-16 23:24:21.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/sys/epoll.h 2004-06-04 17:59:29.871664288 +0000
@@ -19,6 +19,7 @@
#ifndef _SYS_EPOLL_H
#define _SYS_EPOLL_H 1

+#include <stdint.h>
#include <sys/types.h>


@@ -44,6 +45,8 @@
#define EPOLLERR EPOLLERR
EPOLLHUP = 0x010
#define EPOLLHUP EPOLLHUP
+ EPOLLET = (1<<31)
+#define EPOLLET EPOLLET
};


패치가 끝났으면 이제 glibc를 만들어 보자. 물론 한번에 될 거라곤 생각 않는다. 나도 이 예제를 무려 세 번이나 다시 빌드해서 성공했다. gcc와 glibc의 버전에 따른 문제에 기인했던 것 같다. 문제가 발생하면 찾아보고 모르겠으면 다시 또 인터넷을 뒤져보자! 아 주의할 사항은 prefix를 /usr로 줘야 한다는 것이다. glibc가 /usr인 prefix는 특별하게 다룬다고 한다.

$ CFLAGS="-O2 -g -finline-limit=10000 -fno-unit-at-a-time" ../../glibc-??/configure --prefix=/usr --build=i686-linux --host=mipsel-linux --enable-add-ons
$ make
$ make install install_root=/opt/host/mipsel-linux/glibc
이렇게 하면 glibc에 인스톨이 된다.
glibc/lib/* 과 glibc/usr/lib/*을 /opt/host/mipsel-linux/mipsel-linux/lib에 복사한다. 또한 glibc/usr/include/*를 /opt/host/mipsel-linux/mipsel-linux/include로 복사한다. 나머지 glibc의 기타 등등은 옵션으로 각각에 맞게 /opt/host/mipsel-linux/mipsel-linux에다가 복사해 넣으면 된다. 이때 복사를 하면서 lib/*이하에 소프트링크가 깨진 것들이 있는데 걍 놔둬두 무방한것도 있고 필요에 따라 수정해 주면 된다. glibc이하는 삭제해도 좋다.

4 gcc 다시 만들기
이제 완전한 버전의 GCC를 다시 만들기만 하면 된다. 해당 작업디렉토리로 가서 깔끔하게 이전에 static으로 만들었던 것을 싹 지우고 다시 만든다.
$ cd $(WORK)/target/gcc
$ rm -rf *
$ $(WORK)/gcc-??/configure --prefix=/opt/host/mipsel-linux
--target=mipsel-linux --enable-languages=c,c++
$ make
$ sudo make install

자 이제 모든 것이 끝났다.

그러나 본인이 여러분에게 권하는 것은 이미 만들어져 널리 쓰이는 툴을 이용하라는 겁니다.

이런짓은 반드시 꼬옥~ 해야 할때만 해야 하는 것이고 나처럼 널널한 사람만 재미로 해보는 것일 뿐입니다.

DDK가 온다면 DDK것을 그대로 이용하시면 되고 그렇지 않더라도 가장 비슷한 것을 찾아서 이용하면 됩니다. 이런 것 만들줄 몰라도 남이 만든걸 이용해서 더 멋진 것을 만든다면 그걸로도 굉장히 큰 행운이라고 생각합니다.

요청이 있으면 예제로 만든 CCK를 자료실에 올리겠습니다만..

압축해도 100메가 넘을것 같습니다만 ㅡ,ㅡ;;;;
KELP - Korea Embedded Linux Project

신고

context switching animation(x86) - ucos

Posted 2005.02.28 12:17

...
신고
(출처: www.kelp.or.kr)

유영창 (2001년 11월 21일 오전 11:07)
StrongARM은 RISC 형식입니다.

즉 1 클럭에 1 명령이 실행되는 구조 입니다.

Intel에서 제공되고 있는 Developer's Manual 의 4장을 보면
각 명령당 소모하는 클럭수가 나옵니다.

특별한 명령을 제외하면 대부분 1클럭만을 소모합니다.

한가지 조심하여야 할것은

캐쉬가 있을때와
캐쉬가 없을때인데

캐쉬가 있을때는 예측이 조금 힘들고요..

캐쉬가 없을때에는 메모리에서 데이타를 패치하는 것은
메모리의 설정상황에 따라 달라집니다.


궁금이 wrote..
: strongarm의 명령 한라인 수행하는데 걸리는 클럭과 계산 하는 방법을 알고 싶습니다 ..  
[ 이글에 답장 | 본문에 답장 ]  

유영창 (2001년 11월 21일 오전 11:51)
정말 제가 잘 모르는 것에 대해서
끝까지 물어 보시는 군요...

일단 정확하지는 않지만 줏어 들은 이야기와 제 상상을 말씀드리지요

님이 원하시는 것은 아마도 타이밍에 대한 것일 겁니다.

하지만 이 것에 대한 명확한 답은 제가 말씀 드리기 힘들겠네요..
대신 StrongARM에서 내부적으로 처리하는 것에 대한
제가 알고 있는 것을 말씀드리겠읍니다.

일단 하나의 명령을 수행할때의 과정을 살펴 봅시다.

1. 명령을 메모리에서 인스트럭션 레지스터에 로드한다.
2. 해당 명령을 수행한다.
3. 만약 해당 명령이 데이타의 읽기나 쓰기가 필요하다면
메모리에 접근한다.

일단 위의 과정중 2 번이 1명령 수행 시간이 됩니다.
RISC 에서는 1 Clock 만 사용된다는 것입니다.

1 Clock은 PLL 셋팅에 다르죠 외부 크리스탈을 3.686에 설정했고 StrongARM1110이라면
200M 이상이 나옵니다.
이 1 클럭이 한 명령을 수행합니다.

이렇게만 따진다면 200회의 수행이 가능하다는 것입니다.
그런데 실제 1번과 3번 행위가 있죠?
그렇다면 이야기는 달라집니다.

ROM의 억세스 타이밍과 RAM 억세스 타이밍이 매우 다른데
보통 짧게는 4클럭에서 많게는 10클럭까지 먹을수 있읍니다.

그럼 실제 수행 시간은 더욱 느려지겠죠...

그래서 명령 캐쉬를 쓰는 것이고 파이프라인 방식을 사용합니다.
이에 대한 자세한 것은 저도 매뉴얼을 좀더 봐야 하겠네요...

여기까지가 제가 알고 있는 내용입니다.

일단 매뉴얼에는 한번 자세하게 찾아본후 다시 말씀드리지요...

질문에는 무조건 항복합니다.  
신고
글쓴이 : 유영창 (2001년 11월 23일 오후 12:23) 읽은수: 802 [ 임베디드강좌/유영창  ]  
통신 프로그램을 작성하다보면
생기는 오류중에서

struct의 크기 때문에 고생하게 된다.

왜?

struct A
{
char a;
};

이것의 크기는 4로 잡히기 때문이다.

크기를 1로 잡으려면

이렇게 하면 된다.

#pragma pack(1)
struct A
{
char a;
};
#pragma pack()

하지만 arm-linux-gcc에서는 이것이 먹지 않는다.

어떻게 해야 할까?

이렇게 하면 된다.

struct A
{
char a;
} __attribute__ ((packed));


PS : 이지보드에 bootp를 구현하다가.....

신고

가상 메모리

Posted 2004.06.07 00:17
www.ahnz.netMMU
신고

커널 디버깅 기능 활성화과정

Posted 2004.06.06 01:15
커널 디버깅 기능 활성화과정  (출처: http://www.kelp.or.kr 유영창)

커널 디버깅 기능 활성화과정
===========================

1. 개요

   이 문서는 커널의 압축 해제 루틴 이후부터의 커널 패치를
   하는 과정에 대하여 시간순으로 기술한 문서이다.
  
   이 문서에서는 커널의 디버깅 옵션을 활성화 하는
   방법에 대하여 기술한 문서이다.
  
2. 문서

   참조 문서 없음
      
3. 커널 디버깅 옵션

   디버그 포트에 대한  처리이다.
  
   커널 디버깅시에 시리얼로 데이타를 표출하면서 보는 것이 가장 편리하므로
   이 작업에 대한 처리를 우선적으로 해야 할것으로 보인다.
  
   우선 커널 컴파일 옵션에서 다음을 활성화 한다.
  
    Kernel hacking  --->
       [*] Kernel debugging
           [*]   Kernel low-level debugging functions
          
     이렇게 하면 두가지 옵션 변수가 활성화 된다.      
  
     CONFIG_DEBUG_KERNEL  
     CONFIG_DEBUG_LL
    
    이중 CONFIG_DEBUG_LL 이 초기에 커널을 디버깅 하기위한  좋은 툴인 것이다.
    
    이 옵션 변수를 참조하는 것을 살펴보면
    
    arch/arm/kernel/Makefile:obj-$(CONFIG_DEBUG_LL)  += debug-$(PROCESSOR).o
    arch/arm/kernel/head-armv.S:#ifdef CONFIG_DEBUG_LL

    이렇게 존재한다.
    
    우선 첫번째 문장에 의해서 참조되는 것은
    
    arch/arm/kernel/debug-armv.S 이다.
    
    두번째로 참조 되는 것은
    
    arch/arm/kernel/head-armv.S 안에서 CONFIG_DEBUG_LL 에 의해서 활성화 되는 구문이다.
    
    이 옵션만 활성화한 상태에서 커널을 컴파일 하면 다음과 같은 에러가 발생한다.

    
=================================================================================================
===    
        debug-armv.S:389: #error Unknown architecture
        make[1]: *** [debug-armv.o] Error 1
        make[1]: Leaving directory `/var/data/project/ez-m28/kernel_patch/linux-m28-
pre/arch/arm/kernel'
        make: *** [_dir_arch/arm/kernel] Error 2
    
=================================================================================================
===    

    이것은 해당 아키텍쳐에 관련된 디버깅 루틴이 없다는 표시이기도 하다.
    즉 S3C2410의 커널은 이 부분에 대한 처리를 하지 않았다.
    
    우리는 작업의 편리성과 가난함(? - 고가의 에뮬레이터가 없다)으로 인하여
    이 부분을 만들어 가는 것이 편리하다.
    
    물론 다른 아케텍쳐에서 한 루틴을 훔쳐 보고 비슷하게 만들면 별문제가 없다.
    손보아야 할 화일은 다음과 같다.
    
    arch/arm/kernel/debug-armv.S
    
    우리가 추가해야 할 위치는 388 라인쯤에 발견할수 있는
    
    #else
    #error Unknown architecture
    #endif

    구문 바로 전에 만들어야 한다.
    
  
     CONFIG_ARCH_S3C2410    
        
    이 디버깅 루틴은 매크로를 선언하게 되어 있는데
    
    다음과 같은 매크로들은 만들어 주어야 한다.
    
    1) .macro        addruart,rx
        -> rx 로 넘어온 레지스터에 UART 주소를 넘긴다.
        
    2) .macro        senduart,rd,rx  
        -> rd 로 넘어온 데이타를 rx 레지스터에 써 넣는다.
           즉 시리얼 포트에 데이타를 써 넣는다.
    
    3) .macro        waituart,rd,rx
        -> UART에 데이타를 쓸수 있으때 까지 기다린다.
    
    4) .macro        busyuart,rd,rx
        -> UART에 써 넣어진 데이타가 처리 된것을 기다린다.
    
    다음과 같이 만들었다.
    
    
=================================================================================================
===    
        #elif defined(CONFIG_ARCH_S3C2410)
        
                        .macro        addruart,rx
                        mrc        p15, 0, rx, c1, c0
                        tst        rx, #1                        @ MMU enabled?
                        moveq        rx, #0x10000000        @ physical base address
                        movne        rx, #0xD0000000        @ virtual address
                        add        rx, rx, #0x00170000        @ UART0
                        .endm
        
                        .macro        senduart,rd,rx
                        str        rd, [rx, #0x20]        @ UTXH0
                        .endm
        
                        .macro        waituart,rd,rx
        1001:                ldr        rd, [rx, #18]                @
                        tst        rd, #1 << 9                @ UARTFLGUTXFF - 1 when full
                        bne        1001b
                        .endm
        
                        .macro        busyuart,rd,rx
                        .endm
    
=================================================================================================
===    

    참고) 디버깅 할때 체크 포인트 찍는 LED루틴은 다음과 같이 사용했다.            
            
                        mov     r1,     #0x10000000   @C
                        add     r1, r1, #0x00100000   @C
                        add     r1, r1, #0x0000001c   @C
                        mov     r0, #0x7              @C
        dled0:          str     r0,[r1]               @C
                        b       dled0                 @C


    위 LED 보다 아무래도 디버거의 루틴을 이용하는 것이 좋은데
    일단
    
    arch/arm/kernel/head-armv.S 화일에서
    
                    mov        r0, #F_BIT | I_BIT | MODE_SVC        @ make sure svc mode
                msr        cpsr_c, r0                        @ and all irqs disabled
                bl        __lookup_processor_type

                다음에 아래 루틴을 추가해 보았다.
                    
                    moveq        r0, #'X'                        @C
                beq        __error                         @C
            
    시리얼로 이렇게 나온다.
    
        Copy Kernel Image .....
        Copy Ramdisk Image .....
        Starting kernel ...
        Uncompressing Linux............................................. done, booting t
        he kernel.
        
        Error: X    

    큭큭큭 일단 뭔가 나온다.
    
    FIFO 처리가 제대로 될지는 모르겠지만 일단 12 문자까지는 무조건 나올 것이다.
    
    커널 디버깅 기능이 제대로 활성화 된것을 확인 한 것이다.      
    
    커밋한 CVS :  include/asm-arm/arch-s3c2410/s3c2410.h
                       -> UART 선언에 VA_IO_BASE1로 선언되어 있어서 VA_IO_BASE0으로 바꿈
                  arch/arm/kernel/debug-armv.S



2003-07-26 18:23:22

신고
유영창 (http://kelp.or.kr)  
압축 해제 이후 커널 패치 과정(1).txt  

압축 해제 이후 커널 패치 과정
=============================

1. 개요

   이 문서는 커널의 압축 해제 루틴 이후부터의 커널 패치를
   하는 과정에 대하여 시간순으로 기술한 문서이다.
  
2. 문서

   이 문서를 작성하기 위하여 권수호씨가 작성한 문서를 참고 하였다.
      http://kelp.or.kr/korweblog/upload/12/20010725160834/045-LinuxKernel-
chapter38_SA1100_Booting_head_S.doc
      
3. 패치 과정

   head.S 의 함수를 추적하기 위한 방법은
  
   돈이 있다면 가장 좋은 것은 에뮬레이터를 이용하는 것이다.
   하지만 돈이 없다면...
  
   결국 몸으로 때우는 수밖에 없다...
  
   여기서는 몸으로 때우는 방법을 검토해 보자.
  
   보통 루틴 추적 방법은 확인하고자 하는 위치에 도달했는가 하는 것과
   도달 했다면 검사하고자 하는 값을 보아야 하는데..
  
   일단 위치잡는 최악의 방법은 LED를 점멸 시키는 방버이다.
   하지만 이것의 문제는 값을 보기가 힘들다는 점
  
   두번째는 시리얼을 이용하는 방법이다.
  
   일단 부팅 메세지가 나오므로
   우리는 시리얼을 이용하는 방법을 찾아 보자.
  
   이 시리얼 메세지를 보는 방법은
   head.S 를 추적할 때 쓰는 나의 방법이다.
  
   물론 이것은 원칙적으로 arch_decomp_setup() 함수가 호출된 이후에
   동작되지만 EZ-M28 에서는 특별히 하는일이 없으므로 그냥 쓴다.
  
   그리고 어셈블러가 조금 약한 나는 그냥
  
   misc.에 출력 함수를 쓰고
  
   이를 어셈블러에서 호출하는 방식을 쓴다.
  
   여기서 알아야 할것은
  
   arm 에서 한두개의 파라메터를 전달하고자 한다면
  
   r0,r1,r2 이 정도만 사용하면 된다.
  
   우리는 이에 대한 루틴을 만들어 보자..
  
   우선 misc.c 에 다음 함수를 추가 한다.
   이 함수는 나중에 지우는 것이 좋다. (^^)
  
   void CheckMsg2( int a )
   {
        char buff[2];
        
        a = a & 0xF;
        
        if( a >= 10 ) buff[0] = a - 10 + 'A' ;
        else          buff[0] = a + '0' ;
        
        buff[1] = 0;
        
        puts( buff  );
   }
   void CheckMsg( int a )
   {
        
        puts("Check1[");
        
        CheckMsg2( a >> 28 );
        CheckMsg2( a >> 24 );
        CheckMsg2( a >> 20 );
        CheckMsg2( a >> 16 );
        CheckMsg2( a >> 12 );
        CheckMsg2( a >>  8 );
        CheckMsg2( a >>  4 );
        CheckMsg2( a       );
                
        puts("]n");
        
        while(1); // 무한 루프를 돈다.
        
   }

   어셈블러에서 호출할대는
  
   bl CheckMsg
  
   라고 하면 되고
   r0 에 파라메터 a에 해당하는 값을 넣으면 된다.

   체크 포인트를 찍는 방법중에 또 다른 하나는 강제 리셋이다.

   어셈블러에서 다음 코드가 강제로 리셋 시키는 것이다.
    
                ldr     r1, =0x10000010
                mov     r0, #1
                str     r0,[r1]
                
   그리고 가장 일반적인 방법은 붙어 있는 led에 빛나게 하는 것이다.
   아래 코드는 EZ-M28 일 경우이다.
  
                ldr     r1, =0x1010001c
                ldr     r0, =0x7          <== 키고 싶은 LED 상태
dled0:          str     r0,[r1]
                b       dled0

  
   커널의 압축 해제를 수행하는 함수는
  
     arch/arm/boot/compressed/head.S 화일의

   bl        decompress_kernel 를 호출하는 부분이다.
  
   이렇게 호출하는 부분은 두가지가 있는데
  
   EZ-M28에서 호출되는 위치는
  
   243 라인이다.
  

   압축이 해제된 이후에
  
   커널의 압축이 풀린 후 풀린 압축 데이타와 실제 커널의 위치가 다르므로
   이를 맞추는 작업을 수행한다.
  
   현재 수행되는 코드를 압축된 뒤로  옳긴 후 커널을 재배치 하게 된다.
  
   아래의 루틴이 그것이다. ^^  
   ==[247 - 269]=====================================================================  
        /*
         * r0     = decompressed kernel length
         * r1-r3  = unused
         * r4     = kernel execution address
         * r5     = decompressed kernel start
         * r6     = processor ID
         * r7     = architecture ID
         * r8-r14 = unused
         */
        
                        add        r1, r5, r0                @ end of decompressed kernel
                        adr        r2, reloc_start
                        ldr        r3, LC1
                        add        r3, r2, r3
        1:                ldmia        r2!, {r8 - r13}                @ copy relocation code
                        stmia        r1!, {r8 - r13}
                        ldmia        r2!, {r8 - r13}
                        stmia        r1!, {r8 - r13}
                        cmp        r2, r3
                        blo        1b
        
                        bl        cache_clean_flush
                        add        pc, r5, r0                @ call relocation code
   ==================================================================================  

   이후 제어는 reloc_start 가 수행된다.
  
   현재 점검 결과 해당 루틴으로 즉 reloc_start 로 진행되지 않는 것으로 보인다.
  
   하나씩 점검 해봐야 할듯
  
                   add        r1, r5, r0                @ end of decompressed kernel
                mov     r0, r1                                       
                
    다음 문장을 수행한 후에
    
       add        r1, r5, r0                @ end of decompressed kernel            

    r1에 담겨진 주소는  0x0820A894 이다.
    
    즉 커널이미지 압축이 풀린 이미지의 끝 위치가 0820A894 의미이다.
    
    다음 문장을 수행한 후에  
    
       adr        r2, reloc_start
       ldr        r3, LC1
       add        r3, r2, r3
    
    r3에 담겨진 주소는 0x0820A894 이다.
    
    이건 좀 이상하다. ?
    
    왜 이런 현상이 생길까?
    
    좀더 조사해 보니
    
    r2 는 0x08008260 이다.  
    r3 는   000001B4 이다.
            
    더하면 0x08008414 이다.    
    
    어? 내가 뭘 잘못했나?
    
    다시 찍어 보니 0x08008414 가 나왔다.
    
    정리해 보면 r1 0x0820A894 은 압축이 풀린 커널 이미지의 끝 위치
                  
                    
                r2 0x08008260 는 재 배치 코드의 시작 위치 즉 reloc_start
                    
                    
                r3 0x08008414 는 재 배치 코드의 끝 위치 즉   reloc_end 값이 들어 가 있다.
                    
    
    다음 문장은    
    
        1:                ldmia        r2!, {r8 - r13}                @ copy relocation code
                        stmia        r1!, {r8 - r13}
                        ldmia        r2!, {r8 - r13}
                        stmia        r1!, {r8 - r13}
                        cmp        r2, r3
                        blo        1b
    
    재 배치 코드의 영역을 압축이 풀린 커널 이미지의 끝 쪽에 이동시키는 것이다.
    
    재 배치 코드는 압축이 풀린 커널 이미지를 실제로 위치할 곳으로 이동시켜주는
    코드 이다.
    
    이와 같이 뒤쪽에 위치해서 수행되어야  이미지 복사중에도 문제가 없기 때문이다.
    
    일단 이 루틴 까지 진행이 제대로 되는지 검증하기로 하자..
    
    그런데 스택은 어떻게 되어 있을 까 ?
    
    그래서 스택 포인터 값을 찍어 보기로 했다.
    
    압축 풀기 직전에 스택 위치는  0x080ABF94 이다.

   위 문자을 수행하기 이전의 스택 포인터는 080ABF98 이다.
  
   별로 변한것이 없다.
  
   그런 왜 위 문장을 수행한 이후에 처리가 되지 않는 것일까?
  
   위 문장 바로 위에서의 PC값은 얼마일까?
  
    PC => 0x080080FC 이다.
    
    정리
    
    r1 : 0x0820A894 커널 이미지 끝
    r2 : 0x08008260 reloc_start
    r3 : 0x08008414 reloc_end
    sp : 0x080ABF98    
    pc : 0x080080FC
    
    위 루틴이 하는 것은
    
        0x08008260 에서 0x08008414 의 영역을
        0x0820A894 로 옮기는 것이다.
        
     그런데 이것을 수행한 이후에는 시리얼 출력이 제대로
     수행되지 않는다?
    
     이유가 무엇일까?
    
   실제 시스템 패닉이 나는 부분은
  
     1:                ldmia        r2!, {r8 - r13}                @ copy relocation code
                stmia        r1!, {r8 - r13}
                ldmia        r2!, {r8 - r13}
                stmia        r1!, {r8 - r13}

    이다..
    
    이 부분을 다음과 같이 수정하였다.
    
    1:                ldmia        r2!, {r8 - r11}                @ copy relocation code
                stmia        r1!, {r8 - r11}
                ldmia        r2!, {r8 - r11}                @ copy relocation code
                stmia        r1!, {r8 - r11}
                ldmia        r2!, {r8 - r11}                @ copy relocation code
                stmia        r1!, {r8 - r11}

    정상적으로 동작했다.
    
    현재 추정은 SDRAM 과 메모리 컨트롤러의 버스트 모드의 문제로
    보인다.
    
    정확한 이유는 모르겠다. ㅜㅜ
    
    다음은
    
    bl        cache_clean_flush 인데
    
    이것은 캐쉬 데이타를 없애주는 역활을 한다.
    
    이것은 조금 더 분석해야 할듯...
    
    일단 재배치 위치에서 동작하여야 하는데 다음 문장
    
       add        pc, r5, r0                @ call relocation code
    
    으로 인해서
    
    
    옮겨진 reloc_start 의 위치로 점프한다.
    
   ==================================================================================  
        reloc_start:        add        r8, r5, r0
                        debug_reloc_start
                        mov        r1, r4
        
        1:
                        .rept        4
                        ldmia        r5!, {r0, r2, r3, r9 - r13}        @ relocate kernel
                        stmia        r1!, {r0, r2, r3, r9 - r13}
                        .endr
        
                        cmp        r5, r8
                        blo        1b
                        debug_reloc_end
        
        call_kernel:        bl        cache_clean_flush
                        bl        cache_off
                        mov        r0, #0
                        mov        r1, r7                        @ restore architecture number
                        mov        pc, r4                        @ call kernel
   ==================================================================================  

   이 루틴은 풀린 커널 이미지를 실제의 위치로 배 배치한다.
  
   재 배치 주소는 r4 에 가지고 있고 배치도리 커널 이미지의 위치는 r5 에 가지고 있게 된다.
  
   그래서 복사하게 된다.
  
   그리고 r4로 점프한다.
  
   이 루틴까지는 정상적으로 동작한다.
  
   여기서 잠깐 검토해 보아야 할 것이
  
   cache_clean_flush 함수이다.

   이 함수는 다음과 같은 형태를 띄고 있다.
      
   cache_clean_flush:
                mov        r3, #16
                b        call_cache_fn

   call_cache_fn 은 부른다.
  
   이 루틴은 다음과 같은 형태를 띄고 있다.
  
        call_cache_fn:        adr        r12, proc_types
                        mrc        p15, 0, r6, c0, c0        @ get processor ID
        1:                ldr        r1, [r12, #0]                @ get value
                        ldr        r2, [r12, #4]                @ get mask
                        eor        r1, r1, r6                @ (real ^ match)
                        tst        r1, r2                        @       & mask
                        addeq        pc, r12, r3                @ call cache function
                        add        r12, r12, #4*5
                        b        1b

   이 루틴은
  
   mrc        p15, 0, r6, c0, c0        @ get processor ID
  
   을 통하여 r6 레지스터에 프로세서 ID를 가져 온다.
  
   이후 proc_types 에 등록된 프로세스 타입을 검색해서
   일치하는 프로세스 타입을 만나면 r3 에 등록된 오프셋에
   해당하는 루틴을 수행하게 된다.
  
   위 루틴을 통해서 ARM920T 의 armv4_cache_flush을 수행하게 도니다.
  
                   .word        0x41129200                @ ARM920T
                .word        0xff00fff0
                b        __armv4_cache_on
                b        __armv4_cache_off
                b        __armv4_cache_flush

   일단 r6에 어떤값이 생기는지 보자
  
    정확하게 0x41129200  이 읽힌다.
    
   이제 마지막으로 r7 에 담겨져 있는 architecture ID 를
   조사해 보자
  
   체크해 보니 0x0000012F 즉 303 이 나오고 있다.
   당연하다 부트로더에서 303이라는 값으로 설정하고 있기 때문이다.

   S3C2410 은 어떻게 되어 있을까?
        
   아키텍쳐 ID는 다음의 위치에 기록되어 있다.
  
   arch/arm/tools/mach-types 란 파일이다.
  
   s3c2410                        ARCH_S3C2410                S3C2410                
        182
  
   이다.
  
   이것은 CPU에 따른 하드웨어의 특성을 커널에 반영하기 위한
   자료 구조에 사용되는 매크로 화일의 번호값이기도 하다.
  
   원래 이런식으로 하면 조금 곤란하다.
   보드별로 따로 받아야 한다.
  
   하지만 진행을 위해서 이 부분의 수정은 하지 않기로 하였다.
  
   최종적인 EZ-M28을 위해서 따로 만들어야 할 것이다.  
  
   이 값은 현재 arch/arm/boot/compressed/head-s3c2410.S
   에서 선언해 주고 있는데
  
   우리는 이전에 무시하게 했었다.
  
   하지만 이부분만 살리기로 한다.
  
   다음과 같은 부분이다.
  
        #if defined(CONFIG_ARCH_S3C2410)
                mov        r7, #MACH_TYPE_S3C2410
                mov        r8, #0
        #endif
  
   이것은
  
   #if 0  // 무시시작
  
   라는 명령문으로 만든 바로 위에 복사해 넣는다.
  
   나중에는 제거할 것이다.
   즉 부트로더에서 직접 주게 할것이다.
  
   다시 r7 에 담겨져 있는 architecture ID 를 조사해 보면
  
     0x000000B6 이 나온다.
    
  즉 arch/arm/tools/mach-types 에 적혀 있던 대로 182 란 값이
  나온다.
  
  이제 정말 실제 커널로 점프했는지를 조사해야 한다.
  
  그래야 압축이 정확하게 풀린 것이니까...
  
  클클
  
  진짜(?) 커널의 시작 위치는
  
  arch/arm/kernel/head-armv.S 이다.
  
  그리고 가장 처음 시작되는 위치는 다음이다.
  
   ==================================================================================  
        /*
         *  Kernel startup entry point.
         *
         * The rules are:
         *  r0      - should be 0
         *  r1      - unique architecture number
         *  MMU     - off
         *  I-cache - on or off
         *  D-cache - off
         *
         * See linux/arch/arm/tools/mach-types for the complete list of numbers
         * for r1.
         */
                        .section ".text.init",#alloc,#execinstr
                        .type        stext, #function
        ENTRY(stext)
                mov        r12, r0

   ==================================================================================  
    
   아직까지 MMU가 활성화 되어 있지 않으므로 당분간 위에서 사용한
   디버깅 방법을 사용할수 있다.
  
   물론 다른 디버깅 방법도 강구해야 하지만
  
   일단 LED로 이 지점에 도착했나를 체크해 보자
  
   여기서 도착 유무는 led로 해 보기로 했다.
  
   다음과 같은 루틴을
  
   ==================================================================================  
                        mov     r1,   #0x10000000    @C  
                        add     r1, r1, #0x100000    @C
                        add     r1, r1,     #0x1C    @C
                        mov     r0, #0x7             @C
        dled0:          str     r0,[r1]              @C
                        b       dled0                @C
   ==================================================================================  

    mov        r12, r0 다음에 삽입하였다.
    
    테스트 결과 통과 !!! 큭큭... 뭔가 되어 가는 것 같다.
    
    자 이제
    
    디버깅을 위해서 제공된 커널 디버깅 옵션을 활성화 하는 것에 대하여
    연구해 보자.
    
    클클...

    커밋한 CVS :  arch/arm/boot/compressed/head.S
                  arch/arm/boot/compressed/head-s3c2410.S



2003-07-26 18:20:43

신고

[Q] relocation of bss and data

Posted 2003.12.10 18:12
구글 검색:
구글 뉴스그룹 홈으로 이동하기
뉴스그룹 
뉴스그룹 고급 검색    환경설정     
 
View with frames관련별  날짜별로
전체 목록 보기 "[Q] relocation of bss and data"
  
목록안의 메시지 1
글쓴이:Kim, Jeong-Hwan (frog@lgic.co.kr)
제목:[Q] relocation of bss and data
 
View this article only
뉴스그룹:comp.sys.powerpc.tech
날짜:2001-04-03 18:42:04 PST
This is a general question about relocation of data and bss section.

When code is linked with linker script allocating all sections including
.bss and .data located in flash area
and all the sections are copied by itself into RAM, how are the data and bss
section relocated?
In the case of text, I know, PIC can run text in different memory area from
that assigned by linker.
However, what happens to .bss and .data ?
For example, gloable variable "a" is defined and assigned its address
0xFFF00200 (flash area) by linker
and map file tells its address 0xFFF00200.
When the area in which global variable "a" is located is copied into RAM and
the location of "a" is changed to 0x00000200 (RAM area),
does the code using "a" such as "a = a+1;"operate normally?
If the address of "a" is still 0xFFF00200 after code is copied, "a = a+1"
will not operate normally becausea is located in flash and will not be
updated.
How can the address of "a" be changed to 0x00000200 ?

Kim
목록안의 메시지 2
글쓴이:Andrew S (andrewsa@com.mmot.com)
제목:Re: [Q] relocation of bss and data
 
View this article only
뉴스그룹:comp.sys.powerpc.tech
날짜:2001-04-03 19:32:05 PST
"Kim, Jeong-Hwan" wrote:
> 
> This is a general question about relocation of data and bss section.
> 
> When code is linked with linker script allocating all sections including
> .bss and .data located in flash area
> and all the sections are copied by itself into RAM, how are the data and bss
> section relocated?
> In the case of text, I know, PIC can run text in different memory area from
> that assigned by linker.
> However, what happens to .bss and .data ?
> For example, gloable variable "a" is defined and assigned its address
> 0xFFF00200 (flash area) by linker
> and map file tells its address 0xFFF00200.
> When the area in which global variable "a" is located is copied into RAM and
> the location of "a" is changed to 0x00000200 (RAM area),
> does the code using "a" such as "a = a+1;"operate normally?
> If the address of "a" is still 0xFFF00200 after code is copied, "a = a+1"
> will not operate normally becausea is located in flash and will not be
> updated.
> How can the address of "a" be changed to 0x00000200 ?
> 
> Kim

Only initialized data needs to be copied (.data).

I believe that references to .data and .bss variables are
made relative to some register (base address). Change the
contents of the register, and you've relocated your data.

-- 
CU
Andrew S.   andrewsa@com.mmot.com   {anti-spam: invert '.m'}
목록안의 메시지 3
글쓴이:Tom Evans (tom@nospam.invalid)
제목:Re: [Q] relocation of bss and data
 
View this article only
뉴스그룹:comp.sys.powerpc.tech
날짜:2001-04-04 02:31:17 PST
Andrew S wrote:
> 
> "Kim, Jeong-Hwan" wrote:
> >
> > This is a general question about relocation of data and bss section.
>
> Only initialized data needs to be copied (.data).
> 
> I believe that references to .data and .bss variables are
> made relative to some register (base address). Change the
> contents of the register, and you've relocated your data.

This depends on your compiler and linker, but with Metaware you have
the options of SMALL Data and BSS segments which use R2 and R13.

By default these are not used. You need to specially select that
your data segments are linked as sbss and sdata and SDA_BASE
and SDA2_BASE to make this work.

Read your linker manual. It should tell you how to do all this.

The crudest way to do this is to link your data "in the right place"
and then run an AWK script over your HEX file and change all the
lines with the address in the data area to "just after the
code segment" and then copy the data back where it belongs when
your code starts.

Tom Evans
InitialSurnameAt
tennyson.com.au
목록안의 메시지 4
글쓴이:vanbaren_gerald (vanbaren@falcon.si.com)
제목:Re: [Q] relocation of bss and data
 
View this article only
뉴스그룹:comp.sys.powerpc.tech
날짜:2001-04-04 11:32:05 PST
Andrew S <andrewsa@com.mmot.com> writes:

>"Kim, Jeong-Hwan" wrote:
>> 
>> This is a general question about relocation of data and bss section.
>> 
>> When code is linked with linker script allocating all sections including
>> .bss and .data located in flash area
>> and all the sections are copied by itself into RAM, how are the data and bss
>> section relocated?
>> In the case of text, I know, PIC can run text in different memory area from
>> that assigned by linker.
>> However, what happens to .bss and .data ?
>> For example, gloable variable "a" is defined and assigned its address
>> 0xFFF00200 (flash area) by linker
>> and map file tells its address 0xFFF00200.
>> When the area in which global variable "a" is located is copied into RAM and
>> the location of "a" is changed to 0x00000200 (RAM area),
>> does the code using "a" such as "a = a+1;"operate normally?
>> If the address of "a" is still 0xFFF00200 after code is copied, "a = a+1"
>> will not operate normally becausea is located in flash and will not be
>> updated.
>> How can the address of "a" be changed to 0x00000200 ?
>> 
>> Kim 
>Only initialized data needs to be copied (.data). 
>I believe that references to .data and .bss variables are
>made relative to some register (base address). Change the
>contents of the register, and you've relocated your data. 
>-- 
>CU
>Andrew S.   andrewsa@com.mmot.com   {anti-spam: invert '.m'}


As Andrew pointed out, .bss is simply zeroed so, as long as your system
zeros RAM on startup, you are OK there.

The PPC has a concept of register relative addressing with the .sdata
and .sdata2 sections, but most programs spill out of those areas and you
will still have a relocation problem.  Also, some compilers don't take
advantage of those conventions.

What is typically done is to link .data at the desired (RAM) address
and then use the object tools (if you are using gnu tools, objcopy,
etc.) to move the .data section to ROM (flash).  In your startup
code, _way early_ and before using any initialized .data values
(perhaps in crt0.s), copy your flash .data image into RAM.  This requires
you to know where the .data section starts and how long it is.  I'll let
you work out these details (check out the labels etext and edata --
I believe they are useful).

Disclaimer: if you are not using the gnu toolset, everything is likely
to be different but similar.  With the gnu toolset, I've inserted just
enough errors to make sure you understand the concepts rather than using
the instructions as boilerplate :-).

gvb

--
+---------------------------------------------------------------------------+
| Jerry Van Baren / vanbaren_gerald@si.com / Grand Rapids Mi / 616-241-7973 |
|   My employer is a company.  Companies are artifacts of a legal system.   |
|________________Artifacts are incapable of having opinions.________________|
목록안의 메시지 5
글쓴이:Andrew Klossner (andrew@cesa.opbu.xerox.com)
제목:Re: [Q] relocation of bss and data
 
View this article only
뉴스그룹:comp.sys.powerpc.tech
날짜:2001-04-04 08:40:08 PST
> When code is linked with linker script allocating all sections
> including .bss and .data located in flash area and all the sections
> are copied by itself into RAM, how are the data and bss section
> relocated?

Other contributors have addressed the case in which code must work in
either place, using PIC and small data segment registers.

If your .data and .bss are not used until after they are copied to
RAM, then you instruct the loader to resolve all references to them
using their RAM addresses.  The GNU loader I use lets me specify this
in the command file.  For example, to place the .data section in ROM
but resolve references as though it begins in RAM at address 0x1000, I
use:

 .data BLOCK(0x1000) : AT 0x1000 {
  *(.data)
 }

  -=- Andrew Klossner (andrew@cesa.opbu.xerox.com)
목록안의 메시지 6
글쓴이:Martin Usher (martinusher@earthlink.net)
제목:[Q] relocation of bss and data
 
View this article only
뉴스그룹:comp.sys.powerpc.tech
날짜:2001-04-30 19:31:07 PST
"Kim, Jeong-Hwan" <frog@lgic.co.kr> wrote in message
news:UYuy6.305$2b5.9359@news2.bora.net...
> This is a general question about relocation of data and bss section.
>
> When code is linked with linker script allocating all sections including
> .bss and .data located in flash area
> and all the sections are copied by itself into RAM, how are the data and bss
> section relocated?

There's a simple trick to this. If you look at the linker control file
syntax you'll find a way of specifying sections that are to be placed at one
address even though they are to be linked at another. In GNU's ld program
its something like.....

.data SECTION (link address): AT (where you want to put it address)

Since the linker also knows how to work variables and has built-in functions
such as ADDR and SIZEOF its possible to place the sections without having to
compute absolute addresses.

The following is a typical GNU control file for a simple ROM montior that's
starts in ROM but then copies itself to RAM after doing the basic
initializing of the processor. (You may recognize the file names as those
from the 8260 sample startup files.) The bulk of the image starts at offset
0x3000 into the ROM, the RAM image starts at 0x700000 and copied with the
image are data sections. The bss, being unitialized, is not loaded. The
startup code will do a long word copy from end_entry to stext for (edata -
stext) / 4 long words. It will then zero out the bss section by zeroing
everything from edata to ebss. (Those labels can be seen by the code -- you
just reference them like any other external symbol.)

Its worth trying to look this stuff up in the manual.

SECTIONS
    {
    s1 0xFF800000 :
        {
        config.o(.text)
        }

    s2 0xFF800100 :
        {
        vect_tbl.o(.text)
        }

    s3 0xFF803000 :
        {

문서 전부 보기... (29줄 이상)

  


©2003 Google
신고

Glabl변수의 초기화 및 영역

Posted 2003.12.01 00:56
Glabl변수의 초기화 및 영역 - Welcome

출처:www.ezdoum.com

version1: 
int myarray[1000]={1,2,3,4}; 
void main(int argc,char *argv[]) 
{ 
  myarray[0]=3; 
} 
 
version2: 
int myarray[1000]; 
void main(int argc,char * argv[]) 
{ 
  myarray[0]=3; 
} 
 
 실행 화일의 크기 비교 
 version 1: 17657 byte 
 version 2: 13629 byte 
 
왜 이렇게 차이가 나는 걸까요? 
두 프로그램 다 integer형의 배열이 1000개 만큼 잡히는 데요. 
고수님들의 답변 기대합니다. 
 
좋은 호기심입니다... 
  
 우선.. 이 현상을 이해 할려면,, elf 바이너리의 특성을 알아야 합니다.  
 
 여기 가시면 elf 바이너리 스팩이 있습니다. 
 http://www.ezdoum.com/stories.php?story=02/04/08/1870532 
  
 간략히 말하면  
 int myarray[1000]={1,2,3,4}와 
 int myarray[1000] 는 바이너리에서 자리 잡는 곳이 틀립니다. 
  
 int myarray[1000]={1,2,3,4}는 
 14 .data         00000fc0  08049400  08049400  00000400  2**5 
                  CONTENTS, ALLOC, LOAD, DATA 
 란 섹션에 자리를 잡게 되지요.. 즉.. 실행파일안에.. 
 Contents of section .data: 
 8049400 00000000 d0a30408 00000000 00000000  ................ 
 8049410 00000000 00000000 00000000 00000000  ................ 
 8049420 01000000 02000000 03000000 04000000  ................ 
 8049430 00000000 00000000 00000000 00000000  ................ 
 8049440 00000000 00000000 00000000 00000000  ................ 
 8049450 00000000 00000000 00000000 00000000  ................ 
 8049460 00000000 00000000 00000000 00000000  ................ 
 8049470 00000000 00000000 00000000 00000000  ................ 
 8049480 00000000 00000000 00000000 00000000  ................ 
 8049490 00000000 00000000 00000000 00000000  ................ 
 이런식으로 초기화된 값들이 들어있습니다. 
  
 하지만  int myarray[1000] 이녀석 같은 경우엔 
 초기화 되지 않았기 때문에 bbs 영역에 들어가게 되지요 
 20 .bss          00000018  0804a490  0804a490  00001490  2**2 
                  ALLOC 
  
 bss 영역은 실행 파일에 포함되지 않고 단지 섹션헤더에 
 자신의 사이즈 정보를 가지고 있어서,,, 바이너리가 
 로딩될때 공간만 확보를 하게 되지요.. 
  
  
 이것은 test1의 영역정보 요약입니다.  
 (int myarray[1000]={1,2,3,4}) 
  
 13 .rodata       00000008  080483f8  080483f8  000003f8  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
 14 .data         00000fc0  08049400  08049400  00000400  2**5 
                  CONTENTS, ALLOC, LOAD, DATA 
 -> 보시면  data영역이  뒤에볼 test2보다 크게 잡혀있는게 보입니다. 
 15 .eh_frame     00000004  0804a3c0  0804a3c0  000013c0  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 
 19 .dynamic      000000a0  0804a3f0  0804a3f0  000013f0  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 20 .bss          00000018  0804a490  0804a490  00001490  2**2 
                  ALLOC 
 -> 00001490이게 파일에서 옵셋포인터 인데, 다음 섹션인 stab의 
 옵셋이 00001490 으로 같은것을 볼수 있습니다. 바이너리가 
 로딩되었을때 사이즈만 가지고 있고 실제 파일에서는 아무것도 
 없는거죠..  
 21 .stab         00000750  00000000  00000000  00001490  2**2 
                  CONTENTS, READONLY, DEBUGGING 
 
 
 13 .rodata       00000008  080483f8  080483f8  000003f8  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
 14 .data         0000000c  08049400  08049400  00000400  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 ->  test1과는 달리 초기화된 데이터가 아니라  
   int myarray[1000]; 선언을 했기 때문에 여기 사이즈가 작습니다. 
 15 .eh_frame     00000004  0804940c  0804940c  0000040c  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 
 19 .dynamic      000000a0  0804943c  0804943c  0000043c  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 20 .bss          00000fc0  080494e0  080494e0  000004e0  2**5 
                  ALLOC                   
 21 .stab         00000750  00000000  00000000  000004e0  2**2 
                  CONTENTS, READONLY, DEBUGGING 
 
 
 
                
test1:     file format elf32-i386 
 
Sections: 
Idx Name          Size      VMA       LMA       File off  Algn 
  0 .interp       00000013  080480f4  080480f4  000000f4  2**0 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  1 .note.ABI-tag 00000020  08048108  08048108  00000108  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  2 .hash         0000002c  08048128  08048128  00000128  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  3 .dynsym       00000060  08048154  08048154  00000154  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  4 .dynstr       00000073  080481b4  080481b4  000001b4  2**0 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  5 .gnu.version  0000000c  08048228  08048228  00000228  2**1 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  6 .gnu.version_r 00000020  08048234  08048234  00000234  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  7 .rel.got      00000008  08048254  08048254  00000254  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  8 .rel.plt      00000018  0804825c  0804825c  0000025c  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  9 .init         0000002f  08048274  08048274  00000274  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
 10 .plt          00000040  080482a4  080482a4  000002a4  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
 11 .text         000000ec  080482f0  080482f0  000002f0  2**4 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
 12 .fini         0000001a  080483dc  080483dc  000003dc  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
 13 .rodata       00000008  080483f8  080483f8  000003f8  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
 14 .data         00000fc0  08049400  08049400  00000400  2**5 
                  CONTENTS, ALLOC, LOAD, DATA 
 15 .eh_frame     00000004  0804a3c0  0804a3c0  000013c0  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 16 .ctors        00000008  0804a3c4  0804a3c4  000013c4  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 17 .dtors        00000008  0804a3cc  0804a3cc  000013cc  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 18 .got          0000001c  0804a3d4  0804a3d4  000013d4  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 19 .dynamic      000000a0  0804a3f0  0804a3f0  000013f0  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 20 .bss          00000018  0804a490  0804a490  00001490  2**2 
                  ALLOC 
 21 .stab         00000750  00000000  00000000  00001490  2**2 
                  CONTENTS, READONLY, DEBUGGING 
 22 .stabstr      0000134f  00000000  00000000  00001be0  2**0 
                  CONTENTS, READONLY, DEBUGGING 
 23 .comment      0000016e  00000000  00000000  00002f2f  2**0 
                  CONTENTS, READONLY 
 24 .note         00000078  0804a4a8  0804a4a8  0000309d  2**0 
                  CONTENTS, READONLY                   
                   
test2:     file format elf32-i386 
 
Sections: 
Idx Name          Size      VMA       LMA       File off  Algn 
  0 .interp       00000013  080480f4  080480f4  000000f4  2**0 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  1 .note.ABI-tag 00000020  08048108  08048108  00000108  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  2 .hash         0000002c  08048128  08048128  00000128  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  3 .dynsym       00000060  08048154  08048154  00000154  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  4 .dynstr       00000073  080481b4  080481b4  000001b4  2**0 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  5 .gnu.version  0000000c  08048228  08048228  00000228  2**1 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  6 .gnu.version_r 00000020  08048234  08048234  00000234  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  7 .rel.got      00000008  08048254  08048254  00000254  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  8 .rel.plt      00000018  0804825c  0804825c  0000025c  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
  9 .init         0000002f  08048274  08048274  00000274  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
 10 .plt          00000040  080482a4  080482a4  000002a4  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
 11 .text         000000ec  080482f0  080482f0  000002f0  2**4 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
 12 .fini         0000001a  080483dc  080483dc  000003dc  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
 13 .rodata       00000008  080483f8  080483f8  000003f8  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, DATA 
 14 .data         0000000c  08049400  08049400  00000400  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 15 .eh_frame     00000004  0804940c  0804940c  0000040c  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 16 .ctors        00000008  08049410  08049410  00000410  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 17 .dtors        00000008  08049418  08049418  00000418  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 18 .got          0000001c  08049420  08049420  00000420  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 19 .dynamic      000000a0  0804943c  0804943c  0000043c  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
 20 .bss          00000fc0  080494e0  080494e0  000004e0  2**5 
                  ALLOC 
 21 .stab         00000750  00000000  00000000  000004e0  2**2 
                  CONTENTS, READONLY, DEBUGGING 
 22 .stabstr      0000134f  00000000  00000000  00000c30  2**0 
                  CONTENTS, READONLY, DEBUGGING 
 23 .comment      0000016e  00000000  00000000  00001f7f  2**0 
                  CONTENTS, READONLY 
 24 .note         00000078  0804a4a0  0804a4a0  000020ed  2**0 
                  CONTENTS, READONLY 
 
ps. 더 자세히 공부하고 싶은 분은 아래의 책을 참고하세요 ^^ 
Linkers and Loaders  
John R. Levine  
http://www.wowbook.com/generic/book/info/book_detail.asp?isbn=ISBN1-55860-496-0 
 

신고
출처 : http://linuxkernel.net 게시판


--------------------------------------------------------------------------------

2002/09/19 (16:35) from 211.38.3.65' of 211.38.3.65'  Article Number : 5920  
  정지호  Access : 18 , Lines : 31  
커널에서 double형의 연산이 가능한가요?  
혹시 시도해 보신분 안계세요?
커널 소스에서 double형을 사용한곳을 찾아 보니깐..
드라이버 쪽에서 몇개가 나오고 나머지는 없더군요...
아래 코드의 수행 결과가 이상합니다.

=============================================
double dd = 100.0;
double dd2 = 33.3;
int ii;

if (dd <= 0.0)
printk("dd is zeron");
else
printk("dd is not zeron");

ii = dd/dd2;

printk("res=%dn", ii);
===============================================
수행결가
===============================================
dd is zero  
res=0      


결과를 보면 double형 연산이 안됩니다.

혹시 아시는분 좀 알려 주세요...

감사합니다.




--------------------------------------------------------------------------------

2002/09/19 (16:40) from 211.38.3.65' of 211.38.3.65'  Article Number : 5921  
  정지호  Access : 26 , Lines : 7  
[내용추가]  커널에서 double형의 연산이 가능한가요?  
Makefile에 아래의 내용을 넣어야 컴파일이 되더군요..

LIBGCC := $(shell $(CROSS_COMPILE)gcc --print-libgcc-file-name)

$(LIBGCC)를 적당한 위치에 추가하면 됩니다.




--------------------------------------------------------------------------------

2002/09/20 (02:44) from 63.220.67.67' of 63.220.67.67'  Article Number : 5923  
  이호 (flyduck@linuxkernel.net)  Access : 38 , Lines : 53  
Re: 커널에서 double형의 연산이 가능한가요?  

원칙적으로 커널에서 floating point 연산을 할 수 없습니다. 이것은
규칙입니다. 요새는 모든 CPU에 실수연산을 담당하는 FPU가 있고,
floating point 연산은 이 FPU를 이용합니다. 그리고 이런 연산이
일어날 때마다 FPU register를 조작하게 됩니다. 문제는 커널에서
mode switching이 일어날 때 이 레지스터를 저장하지 않습니다.

따라서 user process에서 실수 연산을 하는 도중에 시스템 콜이나
인터럽트 등으로 커널 모드에 진입을 하고, 커널에서 FPU 레지스터를
바꾼후 그냥 사용자 모드로 되돌아왔다면 사용자 프로그램은 엉뚱한
결과를 낳을 수 있습니다. 눈으로 확인하기는 쉽지 않겠지만요.
그래서 실수 연산과 관련해서는...

- init_module() 처럼 전혀 위험이 없는 곳에 사용하거나 (insmod
프로그램이 실수 연산을 사용하지 않으므로)
- 실수연산후 FPU 레지스터의 값을 복구하거나
- software emulation (FPU를 사용하지 않고 소프트웨어적인 실수계산)

을 해야 합니다. MMX 명령어도 마찬가지죠.



--------------------------------------------------------------------------------

2002/09/23 (17:48) from 211.38.3.65' of 211.38.3.65'  Article Number : 5931  
  정지호  Access : 30 , Lines : 93  
해결...했습니다.  
답변감사합니다.

질문의 코드는 커널 컴파일 할때 -msoft-float 옵션을 켜고
컴파일 할때의 결과 입니다.
그리고 CPU가 FPU가 없는 임베디드 CPU(IBM405GP) 였습니다.
(정보가 정확하지 않았죠 ^^)

원인을 추적하던중 gcc 컴파일러의 컴파일러 소스에 버그인지 아닌지 모르겠는
문제의 코드가 있어 수정을 했습니다.

문제의 코드는 libgcc.a를 만드는 소스(soft-float emulation 코드)
floatlib.c파일의 double형의 equal(not equal)연산을 하는 코드

int
__eqdf2 (double a1, double a2)
{
   //return *(long long *) &a1 == *(long long *) &a2;
   return (__cmpdf2 ((float) a1, (float) a2) != 0);
}

였습니다.

막힌 부분이 원래 코드 입니다.

수정하고 나니...
원래의 코드가 다른 CPU에서는 동작하는지 궁금한데..
여유가 없어서 테스트를 못해본 상태 입니다.
(이상타....혹시 i386계열에서는 문제가 없는거 아닌지..
.. 아~~~ 인텔은 위의 코드를 사용안한다.. 왜~~ FPU가 있으니깐... ^^)
여튼 이렇게 처리하니 문제가 없더군요...

수고하세요..

신고