¡¡¡¡uClinuxÕâ¸öÓ¢Îĵ¥´ÊÖÐu±íʾMicro£¬Ð¡µÄÒâ˼£¬C±íʾControl£¬¿ØÖƵÄÒâ˼£¬ËùÒÔuClinux¾ÍÊÇMicro-Control-Linux£¬×ÖÃæÉϵÄÀí½â¾ÍÊÇ"Õë¶Ô΢¿ØÖÆÁìÓò¶øÉè¼ÆµÄLinuxϵͳ"¡£
¡¡¡¡uclinuxÊÇÒ»¸öÔ´Â뿪·ÅµÄ²Ù×÷ϵͳ£¬ÃæÏòûÓÐMMU£¨Memory Management Unit£©µÄÓ²¼þƽ̨¡£ËüÊÇlinuxµÄÒ»¸ö±äÖÖ£¬Ö÷ÒªµÄÇø±ðÔÚÓÚÁ½ÕßµÄÄÚ´æ¹ÜÀí»úÖÆºÍ½ø³Ìµ÷¶È¹ÜÀí»úÖÆ£¬Í¬Ê±ÎªÁËÊÊӦǶÈëʽӦÓõÄÐèÇó£¬ËüµÄ²ÉÓÃÁËromfsÎļþϵͳ£¬²¢¶ÔlinuxÉϵÄcÓïÑÔ¿âglibc×öÁ˼ò»¯¡£
2. Ó²¼þÌåϵ½á¹¹¼ò½é
¡¡¡¡ÔËÐÐuClinuxµÄÓ²¼þƽ̨Ö÷Òª°üÀ¨Èçϼ¸¸ö²¿·Ö£ºcpu(ARMv4Ö¸Á¼æÈÝ)¡¢uart¡¢memory controller¡¢¶¨Ê±Æ÷¡¢flash´æ´¢Æ÷£¬sdram´æ´¢Æ÷£¬ÖжϿØÖÆÆ÷ºÍDMA¡£
3. ±àÒë»·¾³ºÍ±àÒ빤¾ß
¡¡¡¡uclinux²Ù×÷ϵͳԴÂë¾ø´ó²¿·ÖÊÇÓÃcÓïÑÔ¿ª·¢µÄ£¬ÓÐһЩÓëÓ²¼þÖ±½ÓÏà¹ØµÄ´úÂëÔòÓÃÌØ¶¨ÓÚijһCPUÌåϵ½á¹¹µÄ»ã±àÀ´ÊµÏÖ¡£ÕâЩԴÂëÖ»ÄÜÓÃGNUµÄgcc±àÒ빤¾ßÀ´½øÐбàÒë¡¢Á´½Ó¡£
¡¡¡¡GNU gcc¿ÉÒÔÔËÐÐÓÚLinux/Unix²Ù×÷ϵͳÉÏ¡£Èç¹ûÒªÔÚWindowsƽ̨ÉÏÔËÐÐgcc£¬Ôò±ØÐë°²×°Cygwin¡£Cygwin¿ÉÒÔÔÚWindowsÖа²×°Ò»¸ölinuxµÄÔËÐл·¾³£¬ÕâÑù¾Í¿ÉÒÔÔÚwindowsÏÂÔËÐÐÔ±¾Ö»ÄÜÔÚlinuxÏÂÔËÐеijÌÐò¡£
¡¡¡¡ÎªÁËÔÚPCÉϱàÒëµÃµ½ÔËÐÐÓÚÄ¿±êCPUÉϵIJÙ×÷ϵͳÄںˣ¬»¹±ØÐë°²×°Ò»¸öºÏÊʵĽ»²æ±àÒëÆ÷¡£Gcc ÌṩÁËÏֳɵÄÕë¶ÔMIPS¡¢ARM¡¢M68K¡¢Sharc¡¢PowerPCµÄ½»²æ±àÒëÆ÷¡£Èç¹ûûÓÐÏֳɵĽ»²æ±àÒëÆ÷£¬ÔòÐèÒª×ÔÐÐÉè¼Æ¡£GNUÍøÕ¾ÌṩÁËһЩÈçºÎ¿ª·¢ÐµĽ»²æ±àÒëÆ÷µÄÎÄÕ¡£¿ª·¢Ò»¸öеıàÒëÆ÷£¬Ò»°ãÐèÒªÈçϼ¸¸ö²½Ö裺
(1)¡¢±àд»úÆ÷ÃèÊö½Å±¾¡£²ÉÓÃgccµÄRTL(Register Tansfer Language)ÓïÑÔÃèÊöÕë¶ÔijһCPUÌåϵ½á¹¹µÄ»úÆ÷Ö¸ÁîÓëѰַ·½Ê½¡¢CPU¸¡µã´¦Àí·½Ê½¡¢endianess¡¢cÓïÑÔÖи÷ÖÖÊý¾ÝÀàÐ͵Äλ¿í¡¢¼Ä´æÆ÷µÄ¸öÊýºÍʹÓùæÔò¡¢¶ÑÕ»ºÍº¯Êýµ÷ÓùæÔòµÈÌåϵ½á¹¹µÄϸ½Ú¡£
(2)¡¢Éè¼Æ´úÂëÉú³ÉÆ÷¡£GccÔÚ¶ÔcÓïÑÔÔ´Îļþ½øÐÐÁË´Ê·¨ºÍÓï·¨·ÖÎöºó£¬½«²úÉúÒ»ÖÖÖмä¸ñʽÎļþ(intermediate representation)¡£ÎªÁ˰ÑÕâÖÖÖмä¸ñʽÎļþת»¯ÎªÕë¶Ô¾ßÌåCPUÌåϵ½á¹¹µÄ»úÆ÷Â룬ÐèÒª×ÔÐÐÉè¼ÆÒ»¸ö´úÂëÉú³ÉÆ÷¡£
(3)¡¢Éè¼Æ»ã±àÆ÷
(4)¡¢Éè¼ÆÁ´½ÓÆ÷
4. uClinuxÆô¶¯¹ý³Ì
uClinuxϵͳµÄÆô¶¯¿ÉÒÔ·ÖΪÁ½¸ö²½Ö裺
(1). ÔËÐÐbootloader³õʼ»¯³ÌÐò
¡¡¡¡SRAM¡¢SDRAMµÈ´æ´¢É豸ÊôÓÚ»Ó·¢ÐԵĴ洢Æ÷£¬µôµçÒÔºóÆäÖеÄÄÚÈݾͻáÈ«²¿¶ªÊ§£¬ËùÒÔ±ØÐë°Ñ²Ù×÷ϵͳµÄÄں˾µÏñ´æ·ÅÔÚFlashµÈ²»»Ó·¢ÐÔ´æ´¢½éÖÊÉÏ¡£µ«ÊDzÙ×÷ϵͳÔÚÔËÐÐʱ£¬ÐèÒª¶¯Ì¬µÄ´´½¨Ò»Ð©ÈçÊý¾Ý¶Î¡¢¶ÑÕ»¡¢Ò³±í£¨Õë¶ÔʹÓÃÐéÄâµØÖ·µÄ²Ù×÷ϵͳ£©µÈÄÚÈÝ£¬ËùÒÔÐèÒªÔÚRAMÖÐÔËÐвÙ×÷ϵͳ¡£Òò´Ë£¬¾ÍÐèÒªÒ»¸öÒýµ¼³ÌÐò°Ñ²Ù×÷ϵͳµÄÄں˾µÏñ´ÓFlash´æ´¢Æ÷¿½±´µ½RAMÖУ¬È»ºóÔÙ´ÓRAMÖÐÖ´ÐвÙ×÷ϵͳµÄÄںˡ£Bootloader¾ÍÊÇ¿ÉÒÔÍê³ÉÕâÑùÒ»ÖÖ¹¦ÄܵijÌÐò¡£
¡¡¡¡´Ó±¾ÖÊÉÏÀ´½²£¬bootloader²»ÊôÓÚ²Ù×÷ϵͳÄںˡ£Ëü²ÉÓûã±àÓïÑÔ±àд£¬Òò´ËÕë¶Ô²»Í¬µÄcpuÌåϵ½á¹¹£¬ÕâÒ»²¿·Ö´úÂë²»¾ßÓпÉÒÆÖ²ÐÔ¡£ÔÚÒÆÖ²²Ù×÷ϵͳʱ£¬Õⲿ·Ö´úÂë±ØÐë¼ÓÒÔ¸Äд¡£
¾ßÌåÀ´½²£¬bootloaderÔÚϵͳÆô¶¯Ê±Ö÷ÒªÍê³ÉÒÔϼ¸Ï×÷£º
? ½«²Ù×÷ϵͳÄں˴Óflash¿½±´µ½sdramÖУ¬Èç¹ûÊÇѹËõ¸ñʽµÄÄںˣ¬»¹Òª½«Ö®½âѹËõ¡£
? ¸ÄдϵͳµÄmemory map£¬ÔÏÈflashÆðʼµØÖ·Ó³ÉäΪ0µØÖ·£¬ÕâʱÐèÒª½«RAMµÄÆðʼµØÖ·Ó³ÉäΪ0¡£
? ÉèÖöÑÕ»Ö¸Õë²¢½«bss¶ÎÇåÁã¡£½«À´Ö´ÐÐcÓïÑÔ³ÌÐòºÍµ÷ÓÃ×Óº¯ÊýʱҪÓõ½¡£
? ¸Ä±äpcÖµ£¬Ê¹µÃcpu¿ªÊ¼Ö´ÐÐÕæÕýµÄ²Ù×÷ϵͳÄںˡ£
(2) ÔËÐвÙ×÷ϵͳÄÚºË
¡¡¡¡bootloader³ÌÐòÖ´ÐÐÍêÉÏÊöµÄ¸÷Ï×÷ºó£¬Í¨¹ýÒ»ÌõÌø×ªÖ¸Áת¶øÖ´ÐÐiniĿ¼ÏÂcÓïÑÔÔ´Îļþmain.cÖеĺ¯Êýstart_kernel()¡£ÒòΪÔÚ´Ë֮ǰbootloaderÒѾ´´½¨ºÃÒ»¸ö³õʼ»¯»·¾³£¬
¡¡¡¡cº¯Êý¿ÉÒÔ¿ªÊ¼Ö´ÐÐÁË¡£Õû¸ö²Ù×÷ϵͳÄں˵ijõʼ»¯¹¤×÷´ÓÕâÀï²ÅËãÊÇÕæÕý¿ªÊ¼¡£Õâ¸öº¯ÊýµÄ³¤¶È±È½Ï¶Ì£¬´úÂëÈçÏ£º
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ÒýÓÃ:asmlinkage void __init start_kernel(void)
{
char * command_line;
unsigned long mempages;
extern char saved_command_line[];
/*
* Interrupts are still disabled. Do necessary setups, then
* enable them
*/
lock_kernel();
printk(linux_banner);
setup_arch(&command_line);
printk("Kernel command line: %s\n", saved_command_line);
parse_options(command_line);
trap_init();
init_IRQ();
sched_init();
softirq_init();
time_init();
/*
* HACK ALERT! This is early. We're enabling the console before
* we've done PCI setups etc, and console_init() must be aware of
* this. But we do want output early, in case something goes wrong.
*/
console_init();
#ifdef CONFIG_MODULES
init_modules();
#endif
if (prof_shift) {
unsigned int size;
/* only text is profiled */
prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
prof_len >>= prof_shift;
size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1;
prof_buffer = (unsigned int *) alloc_bootmem(size);
}
kmem_cache_init();
sti();
calibrate_delay();
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && !initrd_below_start_ok &&
initrd_start < min_low_pfn << PAGE_SHIFT) {
printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
"disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
initrd_start = 0;
}
#endif
mem_init();
kmem_cache_sizes_init();
pgtable_cache_init();
mempages = num_physpages;
fork_init(mempages);
proc_caches_init();
vfs_caches_init(mempages);
buffer_init(mempages);
page_cache_init(mempages);
#if defined(CONFIG_ARCH_S390)
ccwcache_init();
#endif
signals_init();
#ifdef CONFIG_PROC_FS
proc_root_init();
#endif
#if defined(CONFIG_SYSVIPC)
ipc_init();
#endif
check_bugs();
printk("POSIX conformance testing by UNIFIX\n");
/*
* We count on the initial thread going ok
* Like idlers init is an unlocked kernel thread, which will
* make syscalls (and thus be locked).
*/
smp_init();
rest_init();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5. ϵͳԴÂëµÄÐÞ¸Ä
¡¡¡¡ÒÆÖ²Ò»¸ö²Ù×÷ϵͳµ½ÐµÄÓ²¼þƽ̨£¬±È½ÏºÃµÄ°ì·¨ÊÇѰÕÒÒ»¸ö¼Ü¹¹Ïà½ü²¢ÇÒÒѾ×öºÃ²Ù×÷ÏµÍ³ÒÆÖ²µÄÓ²¼þƽ̨¡£È»ºó£¬¶ÔÔÏȵIJÙ×÷ϵͳ×öÒ»¶¨Ð޸ġ£ÏµÍ³Ô´ÂëÐ޸ĵŤ×÷Á¿È¡¾öÓÚ×ÔÐÐÉè¼ÆµÄÓ²¼þƽ̨ÓëÏÖÓеÄÓ²¼þƽ̨֮¼ä²îÒì³Ì¶È¡£´ËÉè¼ÆÖеÄÓ²¼þƽ̨ÓëÈýÐÇ4510оƬ½ÏΪ½Ó½ü£¬²¢ÇÒÒ²¿ÉÒÔÏÂÔØµ½Õë¶Ô4510bµÄuclinuxϵͳԴÂë¡£ËùÒÔ¿ÉÒÔ´Ó´ËÔ´ÂëÈëÊÖ£¬¸ù¾ÝÎÒÃǵÄÓ²¼þƽ̨Óë4510bµÄ²»Í¬Ö®´¦£¬ÔÚÔ´ÂëÖÐÕÒµ½ÏàÓ¦µÄÎļþ²¢¼ÓÒÔÐ޸ġ£ÏÂÃæ½éÉÜÈçºÎÐÞ¸ÄϵͳԴÂë¡£
ÐèÒªÐ޸ĵÄϵͳԴÂëÖ÷ÒªÓÐÈçϼ¸´¦£º
(1) bootloaderÏà¹Ø´úÂë¡£´Ë´úÂëλÓÚ\uClinux\linux-2.4.x\arch\armnommu\boot\compressed\Ŀ¼ÏÂÃûΪhead.sµÄÎļþÖС£´Ë´¦³ÌÐòÓûã±àÓïÑÔʵÏÖ£¬ÐèÒªÐ޸ĵĵط½Ö÷ÒªÊÇÉèÖÃmemory mapµÄ´úÂ룬Óëmemory controllerµÄÓ²¼þʵÏÖÏà¹Ø¡£
(2) UARTÏà¹Ø´úÂë¡£UARTÏà¹Ø´úÂëλÓÚ\uClinux\linux-2.4.x\drivers\charĿ¼ÏµÄserial.c
(3) ¶¨Ê±Æ÷Ïà¹Ø´úÂë¡£uClinuxÖÐÓÐÈçϺ¯Êýµ÷ÓÃstar_kernel()->time_init()->setup_timer(),ÐèÒªÐÞ¸Äsetup_timer()º¯ÊýÖеÄÏà¹Ø´úÂë¡£
(4) ÖжϿØÖÆÆ÷Ïà¹Ø¡£\uClinux\linux-2.4.x\arch\armnommu\irq.c
¡¡¡¡³ýÁËÉÏÊöµÄ´úÂ룬»¹ÓÐÆäËû¶à´¦ÐèÒªÐ޸ġ£ÔÚÐÞ¸ÄÔ´´úÂëʱ£¬¿É°´ÕÕuclinuxÆô¶¯ºÍÖ´ÐÐ˳ÐòÒÀ´ÎÐÞ¸ÄÕû¸öƽ̨¡£ÊìϤlinuxÄÚºËÔ´Âë½á¹¹¶Ô²Ù×÷ÏµÍ³ÒÆÖ²Óкܴó°ïÖú¡£