2009년 12월 30일 수요일

AT91SAM9263에서 Linux부팅 시간 단축하기

Faster boot: starting Linux directly from AT91bootstrap


ATMEL의 ARM9프로세서인 AT91SAM9263을 이용하여 개발한 임베디드 보드에 OS로 리눅스를 적용하였다. 임베디드 시스템의 특성상 전원이 투입되면 바로 동작되어야 하나, 리눅스의 부팅과정은 요구조건보다 시간을 많이 소요하여 전원 투입 후 한동안 기다려야 응용프로그램이 동작하기 시작한다. 따라서 부팅시간을 단축하는 것에 관심을 가지고 있던 차에 이에 맞는 유용한 정보를 발견하였다.


Reducing start-up time looks like one of the most discussed topics nowadays, for both embedded and desktop systems. Typically, the boot process consists of three steps:AT91SAM9263 CPU

  • First-stage bootloader
  • Second-stage bootloader
  • Linux kernel

The first-stage bootloader is often a tiny piece of code whose sole purpose is to bring the hardware in a state where it is able to execute more elaborate programs. On our testing board, a CALAO TNY-A9260, it’s a piece of code the CPU stores in internal SRAM and its size is limited to 4Kib, which is a very small amount of space indeed. The second-stage bootloader often provides more advanced features, like downloading the kernel from the network, looking at the contents of the memory, and so on. On our board, this second-stage bootloader is the famous U-Boot.

One way of achieving a faster boot is to simply bypass the second-stage bootloader, and directly boot Linux from the first-stage bootloader. This first-stage bootloader here is AT91bootstrap, which is an open-source bootloader developed by Atmel for their AT91 ARM-based SoCs. While this approach is somewhat static, it’s suitable for production use when the needs are simple (like simply loading a kernel from NAND flash and booting it), and allows to effectively reduce the boot time by not loading U-Boot at all. On our testing board, that saves about 2s.

As we have the source, it’s rather easy to modify AT91bootstrap to suit our needs. To make things easier, we’ll boot using an existing U-Boot uImage. The only requirement is that it should be an uncompressed uImage, like the one automatically generated by make uImage when building the kernel (there’s not much point using such compressed uImage files on ARM anyway, as it is possible to build self-extractible compressed kernels on this platform).

Looking at the (shortened) main.c, the code that actually boots the kernel looks like this:


int main(void)
{
	/* ======== 1st step: Hardware Initialization ============ */
	/* Performs the hardware initialization */
	hw_init();

	/* Load from Nandflash in RAM */
	load_nandflash(IMG_ADDRESS, IMG_SIZE, JUMP_ADDR);

	/* Jump to the Image Address */
	return JUMP_ADDR;
}


In the original source code, load_nandflash actually loads the second-stage bootloader, and then jumps directly to JUMP_ADDR (this value can be found in U-Boot as TEXT_BASE, in the board-specific file config.mk. This is the base address from which the program will be executed). Now, if we want to load the kernel directly instead of a second-level bootloader, we need to know a handful of values:

  • the kernel image address (we will reuse IMG_ADDRESS here, but one could
    imagine reading the actual image address from a fixed location in NAND)
  • the kernel size
  • the kernel load address
  • the kernel entry point

The last three values can be extracted from the uImage header. We will not hard-code the kernel size as it was previously the case (using IMG_SIZE), as this would lead to set a maximum size for the image and would force us to copy more data than necessary. All those values are stored as 32 bits bigendian in the header. Looking at the struct image_header declaration from image.h in the uboot-mkimage sources, we can see that the header structure is like this:


typedef struct image_header {
	uint32_t    ih_magic;    /* Image Header Magic Number    */
	uint32_t    ih_hcrc;    /* Image Header CRC Checksum    */
	uint32_t    ih_time;    /* Image Creation Timestamp    */
	uint32_t    ih_size;    /* Image Data Size        */
	uint32_t    ih_load;    /* Data     Load  Address        */
	uint32_t    ih_ep;        /* Entry Point Address        */
	uint32_t    ih_dcrc;    /* Image Data CRC Checksum    */
	uint8_t        ih_os;        /* Operating System        */
	uint8_t        ih_arch;    /* CPU architecture        */
	uint8_t        ih_type;    /* Image Type            */
	uint8_t        ih_comp;    /* Compression Type        */
	uint8_t        ih_name[IH_NMLEN];    /* Image Name        */
} image_header_t;


It’s quite easy to determine where the values we’re looking for actually are in the uImage header.

  • ih_size is the fourth member, hence we can find it at offset 12
  • ih_load and ih_ep are right after ih_size, and therefore can be found at offset 16 and 20.

A first call to load_nandflash is necessary to get those values. As the data we need are contained within the first 32 bytes, that’s all we need to load at first. However, some space is required in memory to actually store the data. The first-stage bootloader is running in internal SRAM, so we can pick any location we want in SDRAM. For the sake of simplicity, we’ll choose PHYS_SDRAM_BASE here, which we define to the base address of the on-board SDRAM in the CPU address space. Then, a second call will be necessary to load the entire kernel image at the right load address.

Then all we need to do is:


#define be32_to_cpu(a) ((a)[0] << 24 | (a)[1] << 16 | (a)[2] << 8 | (a)[3])
#define PHYS_SDRAM_BASE 0x20000000

int main(void)
{
	unsigned char *tmp;
	unsigned long jump_addr;
	unsigned long load_addr;
	unsigned long size;

	hw_init();

	load_nandflash(IMG_ADDRESS, 0x20, PHYS_SDRAM_BASE);

	/* Setup tmp so that we can read the kernel size */
	tmp = PHYS_SDRAM_BASE + 12;
	size = be32_to_cpu(tmp);

	/* Now, load address */
	tmp += 4;
	load_addr = be32_to_cpu(tmp);

	/* And finally, entry point */
	tmp += 4;
	jump_addr = be32_to_cpu(tmp);

	/* Load the actual kernel */
	load_nandflash(IMG_ADDRESS, size, load_addr - 0x40);

	return jump_addr;
}


Note that the second call to load_nandflash could in theory be replaced by:


load_nandflash(IMG_ADDRESS + 0x40, size + 0x40, load_addr);


However, this will not work. What happens is that load_nandflash starts reading at an address aligned on a page boundary, so even when passing IMG_ADDRESS+0x40 as a first argument, reading will start at IMG_ADDRESS, leading to a failure (writes have to aligned on a page boundary, so it is safe to assume that IMG_ADDRESS is actually correctly aligned).

The above piece of code will silently fail if anything goes wrong, and does no checking at all – indeed, the binary size is very limited and we can’t afford to put more code than what is strictly necessary to boot the kernel.


2009년 12월 29일 화요일

Free Embedded RTOS - ChibiOS/RT

STM32에서 사용 가능한 가벼운 RTOS를 찾는중 ChibiOS/RT라는 RTOS를 발견하였다. 간단한 소개는 다음과 같다.

  • 개요

ChibiOS/RT is designed for deeply embedded real time applications where execution efficiency and tiny code size are desiderable features.

The system is implemented as a library to be linked with the application code, the OS and the application code together form the image to be loaded on the target device.


  • 특징

The kernel provides a rich features set, it offers: preemptive multithreading, 128 priority levels, optional round-robin support, unified interrupts handling, support for preemptable interrupt handlers, virtual timers, semaphores, mutexes, condition variables,synchronous messages, mailboxes, event flags, Abstract Channels, I/O queues, heapand memory pools allocators.

Of course, the above mechanisms are not always required in most applications, it is possible to selectively exclude the unused subsystems reducing the total code size.


  • 코드 사이즈

The kernel is very compact, on a reference Cortex-M3 (STM32) platform the kernel size ranges from 1.2KiB minimum up to 5.2KiB maximum size. Size metrics are available for all platforms, as test reports, into the source distribution.


  • 성능

On a reference STM32 platform clocked at 72MHz the kernel is capable of context switching in1.41 microseconds, taking/releasing a semaphore takes 1.21 microseconds, spawning a thread (the whole create-execute-terminate cycle) takes 4.64 microseconds.

The timings are measured using the internal test suite, it is possible to inspect the benchmarking methodology and replicate the results by simply running the included demos. Performance metrics are available for all platforms, as test reports, into the source distribution.


  • 링크

http://chibios.sourceforge.net/

2009년 12월 18일 금요일

구글 크롬 설치후 플래시 플러그인 설치

구글 크롬 브라우져(http://www.google.com/chrome/?hl=ko) 설치 후 "필수 플러그인이 설치되지 않음"이라는 메시지가 포함된 노란 네모상자만 나타나고, 자동으로 플러그인 설치가 진행되지 않을 경우 수동으로 플러그인을 설치해 주어야 한다.

아래 주소에서 Flash Player를 다운받아 설치한 후, 크롬 웹브라우져를 재실행 한다.



2009년 12월 12일 토요일

Windows7에서 Mentor Graphics PADS 9.0.2 설치하기

MentorGraphics의 PCB Cad 프로그램인 PADS는 공식적으로는 아직 Windows 7과의 호환성을 제공하지 않고 있다. 따라서 Windows 7에서 PADS V9.0.2를 설치 하려면 호환성 모드에서 설치를 해야 한다. 물론 Windows XP에서는 문제 없이 잘 동작한다.

 

1. CD에 있는 autorun.exe 파일을 windows xp sp3와 호환되는 모드로 설정한다.
   autorun.exe를 오른쪽 마우스 버튼으로 클릭하여 [속성]으로 들어 간다.
   autorun 속성 다이얼로그에서 [호환성]탭으로 가서, 호환모드 박스의 "이 프로그램을실행할 호환 모드:"에서 "Windows XP(서비스 팩 3)"를 선택하고, 체크 버튼을 체크해준다. 확인 버튼을 클릭하고 빠져 나와서 autorun.exe를 실행한다.

 

2. 라이센스 파일의 위치를 묻는 창이 나타나면, 그냥 설치를 진행한다.

 

3. 설치를 완료한 후, Keygen.zip 압축을 풀어서 Overwrite all files with these 폴더에 있는 MGLS.DLL 파일을 다음 위치에 덮어 쓴다.

   c:\MentorGraphics\9.0.2PADS\SDD_HOME\Programs\MGLS.DLL

 

4. MakeLic.bat파일을 실행하면 licensefile.dat라는 파일이 생성된다.
   생성된 파일을 적당한 위치에 복사 한다.

 

5. 시스템 정보의 환경변수에 MGLS_LICENSE_FILE 를 조금전 복사한 licensefile.dat의 경로로 등록한다. 이로써 설치 완료된다.

 

Keygen.zip

Mentor Graphics PADS V9.0.2 Keygen.zip

2009년 12월 11일 금요일

Windows 7에서 OrCad 16.2 설치 방법

1. CD1의 setup.exe를 실행한 후 "License Manager"를 설치한다. 설치도중 License File의 위치를 물어오면 "CANCEL" 버튼을 눌러서 "License Manager"의 설치를 취소하고 아래 2번 단계로 진행한다.

 

2. CD1의 crack 폴더 안에 있는 cdslmd.exe 파일을 C:\Cadence\LicenseManager 폴더에 복사한다. 설치 위치가 다른 곳이면, 이에 맞는 폴더에 복사한다.

 

3. crack 폴더 안에 있는 license.dat 파일을 적당한 폴더에 복사 한다.

 

4. 시작-> Cadence -> License Manager -> License Server Configuration Utility 를 실행하여, 위에서 복사한 라이센스 파일의 위치를 지정해 준다.

 

5. 이제 설치 프로그램에서 "Product/Demo Installation"을 실행한다. 설치 도중 CONTROLEFILE.TXT 파일의 위치를 물어 오면 "Skip"버튼을 클릭한다.

 

6. CD1의 설치가 끝나면, CD2에서 data3.cab파일을 찾는 다이얼 로그가 나타난다. 이때 기본으로 설정되어 있는 디렉토리가 \Disk2로 되어 있는데, Disk2를 지워준다. data3.cab은 상위 폴더에 있으며, Disk2라는 폴더는 CD2에 존재 하지 않는다.

 

7. License Path를 묻는 창이 나타나면, 21000@localhost 를 입력해 주고 설치는 계속 진행한다.

 

8. 프로그램의 설치가 끝나고 나면 crack폴더에 있는 tbe-patcher.exe 파일을 c:\Cadence\OrCAD_16.2\ (프로그램을 설치한 위치)에 복사한 후 "Patch"를 실행한다. 몇분정도 시간이 소요되면 OrCAD 16.2의 설치가 완료된다.

Windows 7에서 한글 AutoCAD 2010 설치 방법

* 프로그램을 설치하기 전에 인터넷 연결을 차단한다.

* 가상CD와 같은 프로그램으로 CD 이미지를 마운트 해서 설치하지 말고, 하드디스크로 복사한 후 설치를 진행한다.

 

1. Autodesk Inventor를 설치 한다.

 

2. Serial Number : 400-45454545,
   Product Key : 527B1 ( Inventor Standard 2010을 설치하고자 할경우 )
               또는 462B1 ( Inventor Professional 2010을 설치하고자 할 경우 )
   시리얼 넘버와 Product Key는 복사해서 붙이기를 하지 말고, 키보드로 직접 타이핑해서 입력한다.
   product Key 에 따라 설치되는 제품의 종류가 달라진다.

 

3. 설치를 마무리 하고, 설치된 프로그램을 실행한다.

 

4. Activate를 선택한다.

 

5. "오늘 등록" 화면에서 키젠 프로그램을 관리자 권한으로 실행한다.
   설치한 프로그램이 32비트 이면 AAC2010_Keygen-32bits 를, 64비트이면 AAC2010_Keygen-64bits 를 실행한다.

 

6. 실행한 Keygen프로그램에서 Mem Patch를 클릭한다. 이때 "Successfully Patched!" 가 나타난다.

 

7. "오늘 등록"화면에서 요청코드를 복사하여 keygen 프로그램에 붙여 넣기하고, Generate 버튼을 클릭한다.

 

8. "오늘 등록"화면에서 "활성화 코드를 입력합니다"를 선택하고, 생성된 Activation 코드를 Activation 화면에 복사한 후 "다음"을 클릭 한다. 이로써 설치 완료 된다.

 

2009년 12월 7일 월요일

Windows 7에 Visual Studio 2008 설치하기

Windows7으로 갈아탄 후, 오피스와 같은 몇몇 유틸들을 설치하였다. 그 후 Visual Studio 2005를 설치하려 했더니, 설치 프로그램이 이유없이 계속 슬그머니 종료 된다.   Visual Studio 2008도 마찬가지 였다.

 

  원인을 알수 없는채로 몇시간 동안 여러가지 방법을 시도해 보다가, 혹시나 해서 가상CD 프로그램으로 마운팅해서 설치하던 방법을 포기하고 CD의 내용을 하드로 복사해서 설치를 시도 했더니 정상적인 설치가 진행되었다.

 

  참고로 현재 사용하고 있는 가상 CD 프로그램은 UltraISO라는 프로그램인데, 아직 Windows7과 호환성이 충분히 확보되지 않았나 보다. XP에서 사용 할때는 큰 문제를 느끼지 못했는데...