* 43주차
10차 ARM 리눅스 커널 스터디 43주차(2014.02.22) 후기입니다.
# 일시 : 2014.02.22 (43주차)
# 장소 : 토즈 타워점
# 참여인원 : 5명
# 스터디 진도 : start_kernel()-> setup_per_cpu_areas() -> pcpu_embed_first_chunk();
# 스터디 내용
mm_init_owner(&init_mm, &init_task);
// null function;
mm_init_cpumask(&init_mm);
// null function
setup_command_line(command_line);
// saved_command_line 및 static_command_line 할당
setup_nr_cpu_ids();
// nr_cpu_ids: 4 = (3 + 1)
setup_per_cpu_areas();
rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,PERCPU_DYNAMIC_RESERVE, PAGE_SIZE, NULL,pcpu_dfl_fc_alloc, pcpu_dfl_fc_free);
// 분석 중
# &init_mm, &init_task 는 어디서 정의했을까?
extern struct task_struct init_task;
extern struct mm_struct init_mm;
으로 컴파일에서 자료구조(init_task, init_mm)을 초기화했었다.
# mm_init_owner(&init_mm, &init_task);
// NULL 함수이다.
# mm_init_cpumask(&init_mm);
// NULL 함수이다.
# setup_command_line(command_line);
command_line 은 어디서 왔을까?
exynos5420-smdk.dts 에 보면 chosen에 bootargs가 있다.
<code>
chosen {
bootargs = "console=ttySAC2,115200 init=/linuxrc";
};
</code>
# static void __init setup_command_line(char *command_line) <code>
{
saved_command_line = alloc_bootmem(strlen (boot_command_line)+1); static_command_line = alloc_bootmem(strlen (command_line)+1);
strcpy (saved_command_line, boot_command_line);
strcpy (static_command_line, command_line);
}
</code>
saved_command_line은 고정할 것이고, static_command_line은 수정될 수도 있다
# setup_nr_cpu_ids(void)
void __init setup_nr_cpu_ids(void)
{
nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask), NR_CPUS) +1;
}
nr_cpu_ids : cpu_possible_mask[1]에서 지난 시간에 bit를 마킹하고 왔기
때문에 3이 되고 여기에 +1을 하면 nr_cpu_ids는 4가 된다.
만약 NR_CPU가 32보다 크다면 cpu_possible_mask[2] 이런식으로 될 수 있다.
# find_last_bit(cpumask_bits(cpu_possible_mask), NR_CPUS) +1
이 함수는 size만큼 0xFFFF를 shift한 후, &로 마스크를 씌워서 값을 추출한다.
즉 이 경우 cpu_possible_mask[1]의 bits값이 추출된다.
# setup_per_cpu_area();
이 함수는 CPU (core)마다 사용할 메모리를 할당하는 과정이다. 멀티 코어
시스템에서는 여러개의 core가 공동으로 사용될 메모리 영역과 각 core를 위한
메모리 공간이 필요하다. 각 core가 사용하는 데이터를 다른 core가 접근하지
못하도록 분리하여 lock과 같은 동기화를 하지 않아도 안전하고 빠르게 데이터를
접근하기 위한 방법이다.
setup_per_cpu_area()는 각 core가 사용할 메모리를.data.percpu 섹션으로
컴파일시 하나만 만들고, 커널의 초기화 과정에서 만들어 놓은 섹션을 core수
만큼 메모리에 복제하는 과정이다.
# pcpu_embed_first_chunk()
ai 구조체 계산하기
ai는 반드시 한개는 있어야만 하고, nr_group 크기만큼 ptr 이 이동한다.
우리는 nr_group이 1이므로 ptr은 44가 되지만,
만약 nr_group이 3이라면 prt은 68이 된다.
ptr 이후에 cpu_maps[0] ... cpu_maps[n]이 위치한다.
# git log
1460dc7..38f9803 master -> origin/master
Updating 1460dc7..38f9803
Fast-forward
Reference/exynos5420-smdk5420_dtb.txt | 804 ++++++++++++++++++++++++++++++++++
arch/arm/include/asm/bitops.h | 7 +-
arch/arm/include/asm/dma.h | 1 +
arch/arm/include/asm/memory.h | 9 +
arch/arm/kernel/devtree.c | 2 +-
include/linux/cpumask.h | 1 +
include/linux/err.h | 3 +
include/linux/kernel.h | 5 +
include/linux/kmemleak.h | 1 +
include/linux/mm_types.h | 3 +-
include/linux/of_fdt.h | 2 +-
include/linux/percpu.h | 14 +-
include/linux/pfn.h | 2 +
include/linux/sched.h | 3 +-
init/main.c | 21 +-
kernel/smp.c | 3 +
lib/find_last_bit.c | 7 +
mm/percpu.c | 152 ++++++-
18 files changed, 1029 insertions(+), 11 deletions(-)
create mode 100644 Reference/exynos5420-smdk5420_dtb.txt
# samsung exynos5 smdk