s5pc100 pwm timer 3번을 시간 측정용으로 쓰기.
u-boot.1.3.4 기준.
최신 u-boot 는 구조가 대폭적으로 바뀌었음.
/lib_arm/board.c
#include // 헤더 까서 timer 3 번 레지스터 정의가 없다면 데이터 시트 보고 때려넣을 것
다음 함수를 추가하자. 모양은 이쁘게 알아서 바꾸삼..;;
// _dawnsea_
// unsigned int my_max;
static int setup_timer3(void)
{
TCFG1_REG = (TCFG1_REG & ~((0xf)
// 해당 부위 찾아서 setup_timer3 펑션포인터 추가할 것.. 부팅하면서 알아서 순차 실행할 것임..
// setup_timer3 호출 순간 타이머 발싸! 그 이전은 알 수 없는 것임.. 사실은 더 있지만 일단 생략..
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
#if defined(CONFIG_SKIP_RELOCATE_UBOOT)
reloc_init, /* Set the relocation done flag, must
do this AFTER cpu_init(), but as soon
as possible */
#endif
setup_timer3,
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
print_timer3, // 이 함수 호출 될 때 시간 찍히니까 유심히 보도록..
...
display_banner 함수 찾아서 타이머 정확한 지 테스트 해보자.
#if 0 // dawnsea 타이머 정확도 측정용. 현재 정확함
for (i = 0; i
U-Boot에 뻘짓해 놓지 않았다면 1초마다 값이 출력될 것임.. 계산이 틀리면 보통 0.5초. 0.1초. 2초. 4초 이렇게 틀어짐..
이렇게 해서 U-Boot 안에서 시간을 볼 수 있고.. timer3는 커널에서 건들지 않응께.. 커널이 개시되도 시간은 흐른당..
이제 커널에서 시간을 찍어보자. 아 시각이 맞겠네 시각..
대충.. static noinline int init_post(void) 함수에 박아봅시다..
이제부터는 산수의 시간..
만약 해당 레지스터를 못 찾겠다면 관련 헤더를 잘 디벼봅시다.
데이터시트에 있는 레지스터 주소 값을 찾은 후.. 바로 쓰면 안 됨.. 가상주소로 사용하기 위해 특정 값을 더해서 쓰던가..
아예 가상주소를 이용해서 헤더파일이 존재할 것임..
....
(void) sys_dup(0);
(void) sys_dup(0);
current->signal->flags |= SIGNAL_UNKILLABLE;
if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
// 현재 카운터가 나타내는 시간이다.. S3C_VA_TIMER 값이 제대로 정의되어 있는지 확인 할 것..
// 모르겠으면 데이터 시트 디벼볼 것..
printk("CT1 = %ld\n", 1000000 - *(unsigned int *)(S3C_VA_TIMER + 0x38) / 2063L);
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
printk("CT2 = %ld\n", 1000000 - *(unsigned int *)(S3C_VA_TIMER + 0x38) / 2063L);
에휴.. 커널 압축 해제 시간 구해보자..
/arch/arm/boot/compressed/misc.c
// 부팅 극초반이라 printk가 동작하지 않음을 유의..
ulg
decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
int arch_id)
{
unsigned int mytime; // dawnsea
output_data = (uch *)output_start; /* Points to kernel start */
free_mem_ptr = free_mem_ptr_p;
free_mem_end_ptr = free_mem_ptr_end_p;
__machine_arch_type = arch_id;
arch_decomp_setup();
mytime = *(unsigned long *)(0xEA000038); // 타이머3번 카운터 값 레지스터의 버쳘 주소임..
putstr("tick = ");
put_i(mytime);
putstr(" ");
put_i(0xAABBCCDD); // 괜히 찍어본 이유는 엔디안 틀어지고 뒤죽박죽 됐을까봐 눈으로 확인..
putc('\n');
makecrc();
putstr("\nUncompressing Linux...");
gunzip();
putstr(" done, booting the kernel.\n");
mytime = *(unsigned long *)(0xEA000038);
putstr("tick = ");
put_i(mytime);
putstr(" ");
put_i(0xAABBCCDD);
putc('\n');
return output_ptr;
}
한 번 해봤으니 이제 부트차트나 좀 제대로 된 프로파일러를 써봅시다.. 이게 뭐냐고..
http://lxr.free-electrons.com/source/t ··· hart.txt
하지만 부팅 극초반을 다루진 않는 듯..