ARM - Linux 커 널 이식 의 (1) - 커 널 시작 프로 세 스 분석.

커 널 버 전: 2.6.22  왜 이런 낮은 버 전 으로 이식 을 했 습 니까? 웨 이 둥 산 대 우 는 낮은 버 전 으로 배 울 수 있 고 높 은 버 전 으로 이식 해 야 할 작업량 이 적 을 수록 배 울 것 이 적다 고 말 했 기 때 문 입 니 다.
       커 널 시작 은 세 단계 로 나 뉘 는데 첫 번 째 는 head. S 파일 과 head - comon. S 를 실행 하 는 것 이 고 세 번 째 단 계 는 main. c 파일 을 실행 하 는 것 을 허용 하 는 것 입 니 다.
       ARM 프로세서 에 대해 커 널 에서 첫 번 째 로 시작 하 는 파일 은 arc / arm / kernel 아래 head. S 파일 입 니 다.물론 arc / arm / boot / copress 아래 에 도 이 파일 이 있 습 니 다. 이 파일 은 위의 파일 과 약간 다 릅 니 다. 압축 된 커 널 을 만 들 때 zImage 를 시작 할 때 후자 가 시작 되 고 후 자 는 전자 와 다 를 때 앞의 코드 는 자동 으로 압축 을 풀 고 뒤의 코드 는 모두 같 습 니 다.여기 서 arc / arm / kernel 아래 의 head. S 파일 을 분석 합 니 다.head. S 작업 이 완료 되면 init / 디 렉 터 리 가 떨 어 지 는 main. c 의 start 로 이동 합 니 다.kernel 함수 가 실 행 됩 니 다.
 
1 단계:
 
우선 일부 head. S 파일 을 캡 처 합 니 다.
ENTRY(stext)
       msr  cpsr_c,#PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
                                          @ andirqs disabled
       mrc  p15,0, r9, c0, c0           @ get processor id
       bl    __lookup_processor_type             @ r5=procinfo r9=cpuid
       movs       r10,r5                         @ invalidprocessor (r5=0)?
       beq  __error_p                     @ yes, error 'p'
       bl    __lookup_machine_type        @ r5=machinfo
       movs       r8,r5                           @ invalidmachine (r5=0)?
       beq  __error_a                     @ yes, error 'a'
       bl    __create_page_tables
 
       /*
        *The following calls CPU specific code in a position independent
        *manner.  See arch/arm/mm/proc-*.S fordetails.  r10 = base of
        *xxx_proc_info structure selected by __lookup_machine_type
        *above.  On return, the CPU will be readyfor the MMU to be
        *turned on, and r0 will hold the CPU control register value.
        */
       ldr   r13,__switch_data        @ address to jump toafter
                                          @ mmuhas been enabled
       adr   lr,__enable_mmu          @ return (PIC)address
 
 
첫 번 째 단 계 는lookup_processor_type, 이 함 수 는 프로세서 모델 을 검사 합 니 다. 회로 기 판 의 CPU 모델 을 읽 고 커 널 이 지원 하 는 프로세서 와 비교 합 니 다.이것 은 우리 가 그것 의 구체 적 인 실현 과정 에 관심 이 없다. 왜냐하면 현재 주류 프로세서 내 핵 이 모두 지원 을 제공 하고 있 기 때문이다.
       두 번 째 단 계 는lookup_machine_type, 이 함 수 는 기계 모델 을 검사 하 러 왔 습 니 다. bootloader 에서 들 어 오 는 기계 ID 와 그 가 처리 할 수 있 는 기계 ID 를 읽 어서 처리 할 수 있 는 지 비교 해 보 겠 습 니 다.커 널 의 ID 번 호 는 arc / arm / tool / mach 로 정의 합 니 다.types 파일 중 MACHTYPE_xxxx 매크로 정의.커 널 은 도대체 그것 이 지원 하 는 기계 인지 아 닌 지 를 어떻게 검사 합 니까?실제로 모든 기 계 는 / arc / arm / mach - xxxx / smdk - xxxx. c 파일 에 특정 기기 의 데이터 구 조 를 묘사 합 니 다. 다음 과 같 습 니 다.
 
01.MACHINE_START(S3C2440,"SMDK2440")  
02.       /* Maintainer: Ben Dooks<[email protected]> */  
03.       .phys_io  =S3C2410_PA_UART,  
04.       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,  
05.       .boot_params  = S3C2410_SDRAM_PA + 0x100,  
06.   
07.       .init_irq   =s3c24xx_init_irq,  
08.       .map_io          =smdk2440_map_io,  
09.       .init_machine  = smdk2440_machine_init,  
10.       .timer             =&s3c24xx_timer,  
11.MACHINE_END  
12.   

 
MACHINE_START 와 MACHINEEND 는 실제로 하나의 구조 체 로 전개 되 었 다.
#defineMACHINE_START(_type,_name)                 \
staticconst struct machine_desc __mach_desc_##_type       \
 __used                                             \
 __attribute__((__section__(".arch.info.init")))= {    \
       .nr          =MACH_TYPE_##_type,           \
       .name             =_name,
      
#defineMACHINE_END                          \
};

그래서 위의 데이터 구 조 는
01.staticconst struct machine_desc __mach_desc_S3C2440     \  
02. __used                                             \  
03. __attribute__((__section__(".arch.info.init")))= {    \  
04.       .nr          =MACH_TYPE_S3C2440,          \  
05.       .name             =”SMDK2440”,};  
06..phys_io  = S3C2410_PA_UART,  
07.       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,  
08.       .boot_params  = S3C2410_SDRAM_PA + 0x100,  
09.   
10.       .init_irq   =s3c24xx_init_irq,  
11.       .map_io          =smdk2440_map_io,  
12.       .init_machine  = smdk2440_machine_init,  
13.       .timer             =&s3c24xx_timer,  
14.   
15.} 

기계 마다 하나의 machinedesc__mach_desc 구조, 커 널 은 모든 machine 을 검사 합 니 다desc__mach_desc 의 nr 호 와 bootloader 가 올 린 ID 를 비교 합 니 다. 같 으 면 커 널 은 이 기 계 를 지원 한다 고 생각 하고 커 널 은 뒤의 작업 에서 이 기계 의 machine 을 호출 합 니 다.desc__mach_desc_구조 중의 방법 으로 초기 화 작업 을 진행 하 다.
       세 번 째 단계, 1 단계 페이지 표를 만 듭 니 다.
       네 번 째 단계, R13 에 저장switch_data 이 함수 의 주 소 는 네 번 째 단계 에서 mmu 를 완성 한 후에 이 함수 로 건 너 뛰 어 실 행 됩 니 다.
다섯 번 째 단 계 는enable_mmu, 그것 은 MMU 를 사용 할 수 있 습 니 다. 이 함 수 는 를 호출 했 습 니 다.turn_mmu_on 함수, 양보 후turn_mmu_on 은 마지막 에 세 번 째 단 계 를 R13 에 부여 한 값 을 PC 포인터 (mov) 에 전달 했다.    pc, r13), 그래서 커 널 이 로 뛰 기 시 작 했 습 니 다.switch_data 이 함수 가 실 행 됩 니 다.
 
arch / arm / kenel / head - common. S 이 파일 의 를 다시 보 겠 습 니 다.switch_데이터 함수
01.__switch_data:  
02.       .long       __mmap_switched  
03.       .long       __data_loc                    @ r4  
04.       .long       __data_start                  @ r5  
05.       .long       __bss_start                    @ r6  
06.       .long       _end                            @ r7  
07.       .long       processor_id                 @ r4  
08.       .long       __machine_arch_type           @ r5  
09.       .long       cr_alignment                 @ r6  
10.       .long       init_thread_union+ THREAD_START_SP @ sp  
11.   
12./*  
13. * The following fragment of code is executedwith the MMU on in MMU mode,  
14. * and uses absolute addresses; this is notposition independent.  
15. *  
16. *  r0  =cp#15 control register  
17. * r1  = machine ID  
18. * r9  = processor ID  
19. */  
20.       .type       __mmap_switched,%function  
21.__mmap_switched:  
22.       adr   r3,__switch_data + 4  
23.   
24.       ldmia      r3!,{r4, r5, r6, r7}  
25.       cmp r4,r5                           @ Copy datasegment if needed  
26.1:    cmpne     r5,r6  
27.       ldrne       fp,[r4], #4  
28.       strne       fp,[r5], #4  
29.       bne  1b  
30.   
31.       mov fp,#0                           @ Clear BSS(and zero fp)  
32.1:    cmp r6,r7  
33.       strcc fp,[r6],#4  
34.       bcc  1b  
35.   
36.       ldmia      r3,{r4, r5, r6, sp}  
37.       str    r9, [r4]                  @ Save processor ID  
38.       str    r1, [r5]                  @ Save machine type  
39.       bic   r4,r0, #CR_A               @ Clear 'A' bit  
40.       stmia       r6,{r0, r4}                   @ Save controlregister values  
41.       b     start_kernel  

이 함수 가 하 는 일 은 데이터 세그먼트 를 복사 하여 BBS 세그먼트 를 명확 하 게 하고 포인터 에 쌓 아 놓 은 다음 프로세서 커 널 과 기계 커 널 등 을 저장 하 는 작업 입 니 다. 마지막 으로 start 로 이동 합 니 다.kernel 함수.그 러 자 커 널 은 두 번 째 단 계 를 수행 하기 시작 했다.
 
2 단계:
 
       init / 디 렉 터 리 에 있 는 main. c 의 start 를 다시 보 겠 습 니 다.kernel 함수, 여 기 는 부분 만 캡 처 했 습 니 다.
01.asmlinkage void __init start_kernel(void)  
02.{  
03.       …………………….  
04.       ……………………..  
05.       printk(KERN_NOTICE);  
06.       printk(linux_banner);  
07.       setup_arch(&command_line);  
08.       setup_command_line(command_line);  
09.        
10.        
11.       parse_early_param();  
12.       parse_args("Booting kernel",static_command_line, __start___param,  
13.                __stop___param - __start___param,  
14.                &unknown_bootoption);  
15.……………………  
16.…………………………        
17.       init_IRQ();  
18.       pidhash_init();  
19.       init_timers();  
20.       hrtimers_init();  
21.       softirq_init();  
22.       timekeeping_init();  
23.       time_init();  
24.       profile_init();  
25.…………………………  
26.……………………………  
27.       console_init();  
28.………………………………  
29.………………………………  
30.       rest_init();  
31.}  

위 에서 보 이 는 startkernel 은 먼저 커 널 정 보 를 인쇄 한 다음 에 bootloader 가 들 어 오 는 매개 변 수 를 처리 한 다음 에 다양한 초기 화 를 실행 합 니 다. 그 중에서 콘 솔 을 초기 화 합 니 다.마지막 으로 rest 호출init();이 함 수 는 연결 루트 파일 시스템 을 시작 하고 init 프로 세 스 를 시작 합 니 다.
 
종합 적 으로 커 널 이 작 동 하 는 과정 은 크게 다음 과 같다.
1. CPU 와 기기 유형 검사
2. 스 택, MMU 등 다른 프로그램 에서 중요 한 것 을 초기 화 합 니 다.
3. 커 널 정보 인쇄
4. 각종 모듈 의 초기 화 실행
5. 연결 루트 파일 시스템
6. 첫 번 째 init 프로 세 스 시작

좋은 웹페이지 즐겨찾기