리눅스/커널2014. 4. 3. 13:39

MACH_TYPE_XXX 와 machine 이름을 overwrite하기 위해서는 아래 매크로를 활용하면 된다.

linux/arch/arm/include/asm/mach/arch.h

  79 * Set of macros to define architecture features.  This is built into
  80 * a table by the linker.
  81 */
  82#define MACHINE_START(_type,_name)                      \
  83static const struct machine_desc __mach_desc_##_type    \
  84 __used                                                 \
  85 __attribute__((__section__(".arch.info.init"))) = {    \
  86        .nr             = MACH_TYPE_##_type,            \
  87        .name           = _name,
  88
  89#define MACHINE_END                             \
  90};


'리눅스 > 커널' 카테고리의 다른 글

Memory 정보 출력되는 곳  (0) 2014.04.07
driver 초기화 시에 쓰이는 module_init  (0) 2014.04.04
Machine 이름 알아내기  (0) 2014.04.03
early_param에 대해  (0) 2014.03.31
/dev/tty 와 /dev/console의 차이점  (0) 2014.02.05
Posted by code cat
리눅스/커널2014. 4. 3. 09:30

start_kernel()-->setup_arch()-->setup_machine_tags()

arch/arm/kernel/setup.c에서setup_arch()함수 내에서 머신이름을 설정한다.

machine_arch_type은 include/generated/mach-types.h에서 정의되어 있는데 이는 gen-mach-types 툴을 이용해서 생성된다.
예)
define MACH_TYPE_CODECAT             1

ifdef CONFIG_CODECAT
define machine_arch_type                   MACH_TYPE_CODECAT

machine_arch_type은 setup_machine_tags의 인자로 넘어가고, setup_machine_tags()내의
for_each_machine_desc는 __arch_info_begin 에서 __arch_info_end 를 순환하면서 machine_desc구조체의 nr(architecture number를 인자로 받아온 machine_arch_type과 비교하여 같은 경우, archiecture name을 찍어준다.

'리눅스 > 커널' 카테고리의 다른 글

driver 초기화 시에 쓰이는 module_init  (0) 2014.04.04
Machine 이름 바꾸기  (0) 2014.04.03
early_param에 대해  (0) 2014.03.31
/dev/tty 와 /dev/console의 차이점  (0) 2014.02.05
FrameBuffer size 구하기  (0) 2013.12.11
Posted by code cat
리눅스/커널2014. 3. 31. 10:14

early_param("HI_MEM", HI_MEM_Init) 

  --> __setup_param(str, fn, fn, 1) 으로 정의되어 있는데 이를 자세히 보면,

static const char __setup_str_##unique_id[] __initcost \
__aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \
  __used __section(.init.setup)
  __attribute__((aligned((sizeof(long))))) \
  = { __setup_str_##unique_id, fn, early }


long 사이즈로 align된 .init.setp섹션에 obs_kernel_param 구조체 형태의 __setup_##unique_id 안에 { __setup_str_##unique_id, fn, early } 형태로 초기화 시킨다. 


obs_kernel_param 구조체는 

const char *str
int (*setup_func)(char *);
int early;

로 구성되어 있다.

이렇게 설정된 early_param의 내용은 init/main.c에서 parse_early_options() --> parse_args("early options", cmdline, NULL, 0, do_early_param) --> parse_one()안에서
return handle_unknown에서 do_early_param이 실행된다.

do_early_param을 실행시킬 때, 그동안 쌓인 obs_kernel_param 리스트(?)들을 순회하면서 실행 시킨다.(섹션에 구조체가 리스트로 들어가기 보다는 각각의 구조체가 엔트리로 들어가는 거 같은데 좀 더 확인이 필요하다.)


__setup_start[] 와 __setup_end[]는 include/asm-generic/vmlinux.lds.h 에서 다음과 같이 정의되어 있다.


#define INIT_SETUP(initsetup_align) \ . = ALIGN(initsetup_align); \ VMLINUX_SYMBOL(__setup_start) = .; \ *(.init.setup) \ VMLINUX_SYMBOL(__setup_end) = .;

또한 INIT_SETUP은 arch/arm/kernel/vmlinux.lds.S에서 16byte(?)으로 align되어 있다.

.init.data : { #ifndef CONFIG_XIP_KERNEL INIT_DATA #endif INIT_SETUP(16) INIT_CALLS CON_INITCALL SECURITY_INITCALL INIT_RAM_FS }


좀 더 자세히 봐야 하는데, 결국 맨 위, "HI_MEM"이라는 parameter에 대한 처리를 HI_MEM_init에서 처리할 수 있게 된다.


'리눅스 > 커널' 카테고리의 다른 글

Machine 이름 바꾸기  (0) 2014.04.03
Machine 이름 알아내기  (0) 2014.04.03
/dev/tty 와 /dev/console의 차이점  (0) 2014.02.05
FrameBuffer size 구하기  (0) 2013.12.11
[커널] FB 문서  (0) 2013.12.09
Posted by code cat
리눅스/커널2013. 8. 9. 17:06

출처: http://dtbaker.net/random-bits/android-unknown-symbol-_global_offset_table_/

 

커널 올리는 중에 에러가 나길래 찾아본 결과, 아래와 같은 글이 있었다.  결론적으로 이 방법이 솔루션이 되지는 못했지만, 참고 사항으로 올린다.

 

 

Android: Unknown symbol _GLOBAL_OFFSET_TABLE_

[ 1525.047424] bcm4329: Unknown symbol _GLOBAL_OFFSET_TABLE_ (err 0)

I received this error after compiling a custom Android kernel and modules using the arm-linux-androideabi-4.4.3 prebuilt toolchain.

I used arm-linux-androideabi-4.4.3 instead of arm-eabi-4.4.0 because arm-eabi-4.4.0 did not work for me on 64bit ubuntu ( * shrug * )

To fix this and to get my kernel modules loading I opened the Makefile within my kernel source folder and changed this:

MODFLAGS        = -DMODULE -march=armv7-a -mfpu=vfpv3 -ftree-vectorize

to this:

MODFLAGS        = -DMODULE -march=armv7-a -mfpu=vfpv3 -ftree-vectorize -fno-pic

Then re-built the kernel modules:

make clean
make modules

and copied my new module back over to android, away she goes!

————————-

if you cannot find MODFLAGS in the Makefile then look for:

CFLAGS_MODULE   =

and change it to

CFLAGS_MODULE   = -fno-pic

 

 

아 그리고  -fno-pic이 도대체 뭔 옵션인지 궁금해서 찾아보았다.

정말 더럽게 안 나온다.

gcc 메뉴얼을 찾아보니, -fpic에 대해 다음과 같이 설명하고 있다.

 

"타겟 머신에서 지원하는 경우, 공유 라이브러리를 위한 position-independent 코드 (PIC)을 생성한다.  이러한 코드는 global offset table(GOT)를 통해 모든 상수 주소에 대한 접근을 시도한다.  dynamic loader는 프로그램 실행의 시작시에 GOT 엔트리들을 처리한다.(참고로 dynamic loader는 GCC의 일부가 아니며 operating system의 일부이다).  ...

Position-indenpendent code 는 특정 머신의 지원이 필요하다...

이 플래그가 설정 된 경우, "__pic__""__PIC__" 는 1로 정의된다."

 

따라서 -fno-pic의 경우 position-independent 코드를 생성하지 말라는 것으로 보인다.

'리눅스 > 커널' 카테고리의 다른 글

FrameBuffer size 구하기  (0) 2013.12.11
[커널] FB 문서  (0) 2013.12.09
Kernel Oops의 Taint 종류  (0) 2013.07.25
[OS] priority inversion 해결방법  (0) 2013.01.13
monolithic vs microkernel  (0) 2013.01.13
Posted by code cat
리눅스/커널2011. 5. 1. 01:24
커널의 선점조건
예전에는 커널은 비선점형이었으나 2.6 버젼부터 선점형으로 바뀌었다. 그러기 위해서 각 프로세스 스택의 thread_info에 preempt_count 라는 변수를 추가하였고, 이 값은 락의 숫자가 증가함에 따라 증가하고 감소하면 같이 감소한다. preemt_count 값이 0일 때에 비로서 선점이 가능하다. 락이 해제될 시 preemt_count 값이 0 이면 락을 푸는 코드는 need_resched() 를 통하여 스케쥴이 필요한지 체크한다. 한편 커널은 태스크가 커널 블록내에 있거나 단도직입적으로 schedule() 를 호출시에도 선점 가능하다.

'리눅스 > 커널' 카테고리의 다른 글

Documentation/arm/booting  (0) 2011.09.25
Linux 3.0 Kernel  (0) 2011.07.31
커널 스레드  (0) 2011.05.01
커널 초기화  (0) 2011.04.20
시스템콜 (미완성)  (0) 2011.04.18
Posted by code cat
리눅스/커널2011. 5. 1. 01:23
커널 스레드와 일반 프로세스와 다른 점 중 가장 두드러진 부분은 커널 스레드는 어드레스 스페이스가 없다는 것이다(mm 포인터 = NULL)

커널 스레드는 커널 스페이스에서만 실행되며 유저공간으로 컨텍스트 스위칭 하지 않는다. 하지만 일반 프로세스와 같이 스케쥴되고 선점 가능하다.

대표적인 커널 스레드로는 flush 와 ksoftirqd가 있으며 ps -ef 로 커널 스레드 리스트를 확인할 수 있다. 커널 스레드는 오직 다른 커널 스레드만이 생성 할 수 있다


iPhone 에서 작성된 글입니다.

'리눅스 > 커널' 카테고리의 다른 글

Linux 3.0 Kernel  (0) 2011.07.31
커널선점  (0) 2011.05.01
커널 초기화  (0) 2011.04.20
시스템콜 (미완성)  (0) 2011.04.18
asmlinkage 에 대한 설명  (0) 2011.04.15
Posted by code cat
리눅스/커널2011. 4. 18. 08:54
시스템콜(종종 시스콜이라 불림)

asmlinkage long sys_getpid (void)
{
return current->tgid
}




프로세스 컨텍스트 내에선 커널은 휴면이 가능하며 선점될 수 있다.

휴면이 가능하다는 것은 인터럽트에 비해 훨씬 편리한 커널 프로그래밍을 가능하게 한다.(인터럽트는 휴면이 불가능 하므로 프로세스 컨텍스트에서 도는 시스콜보다 제한이 많다). 
선점이 가능하다는 것은 지금 테스크 역시 선점 가능하다는 소리이므로 다른 테스크에서 같은 시스콜을 호출 할 수 있기에 시스콜이 재진입 여부를 체크해야 한다.(이것은 SMP에서 고려해야 하는 상황과 같다)

시스콜이 리턴하면 컨트롤은 system_call() 계속되며 결국 유저 프로세스로 돌아간다

시스콜 추가 하는법
1. 시스템콜 테이블 끝에 새로운 엔트리를 추가한다. 지원할려는 아키텍쳐마다 추가해야 하며, 테이블에서의 위치-1이 시스템콜 넘버이다. 
Entry.S

ENTRY(sys_call_table)
.long sys_open
.long sys_read 


....


2. 각 지원되는 아키텍쳐마다 시스콜 넘버를에 정의한다. 

#define __NR_restart_sys_call
#define __NR_exit




3. 시스콜을 커널이미지에 컴파일 한다.(kernel/ 에 관련된 파일에 시스콜을 추가한다. 예)sys.c)

asmlinkage sys_foo (void)
{
...
}



'리눅스 > 커널' 카테고리의 다른 글

Linux 3.0 Kernel  (0) 2011.07.31
커널선점  (0) 2011.05.01
커널 스레드  (0) 2011.05.01
커널 초기화  (0) 2011.04.20
asmlinkage 에 대한 설명  (0) 2011.04.15
Posted by code cat