Guest User

FreeAgent Theater init main.c code

a guest
Apr 21st, 2011
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 26.42 KB | None | 0 0
  1. /*
  2.  *  linux/init/main.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *
  6.  *  GK 2/5/95  -  Changed to support mounting root fs via NFS
  7.  *  Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
  8.  *  Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
  9.  *  Simplified starting of init:  Michael A. Griffith <grif@acm.org>
  10.  */
  11.  
  12. #define __KERNEL_SYSCALLS__
  13.  
  14. #include <linux/config.h>
  15. #include <linux/types.h>
  16. #include <linux/module.h>
  17. #include <linux/proc_fs.h>
  18. #include <linux/devfs_fs_kernel.h>
  19. #include <linux/kernel.h>
  20. #include <linux/syscalls.h>
  21. #include <linux/string.h>
  22. #include <linux/ctype.h>
  23. #include <linux/delay.h>
  24. #include <linux/utsname.h>
  25. #include <linux/ioport.h>
  26. #include <linux/init.h>
  27. #include <linux/smp_lock.h>
  28. #include <linux/initrd.h>
  29. #include <linux/hdreg.h>
  30. #include <linux/bootmem.h>
  31. #include <linux/tty.h>
  32. #include <linux/gfp.h>
  33. #include <linux/percpu.h>
  34. #include <linux/kmod.h>
  35. #include <linux/kernel_stat.h>
  36. #include <linux/security.h>
  37. #include <linux/workqueue.h>
  38. #include <linux/profile.h>
  39. #include <linux/rcupdate.h>
  40. #include <linux/moduleparam.h>
  41. #include <linux/kallsyms.h>
  42. #include <linux/writeback.h>
  43. #include <linux/cpu.h>
  44. #include <linux/cpuset.h>
  45. #include <linux/efi.h>
  46. #include <linux/unistd.h>
  47. #include <linux/rmap.h>
  48. #include <linux/mempolicy.h>
  49. #include <linux/key.h>
  50. #include <mcp.h>
  51. #include <mcp/mcp.h>
  52. //#include <mcp/rsa.h>
  53. #include <linux/reboot.h>   // For machine_restart
  54. #if CONFIG_REALTEK_TEXT_DEBUG || CONFIG_REALTEK_MEMORY_DEBUG_MODE || CONFIG_REALTEK_USER_DEBUG
  55. #include <linux/interrupt.h>
  56.  
  57. #include <venus.h>
  58.  
  59. #if CONFIG_REALTEK_TEXT_DEBUG || CONFIG_REALTEK_MEMORY_DEBUG_MODE
  60. #define PREFETCH_BUFFER 0x400
  61.  
  62. extern unsigned int _etext;
  63. extern unsigned int _edata;
  64. extern unsigned int audio_addr;
  65. #endif
  66. #endif
  67.  
  68. #ifdef CONFIG_REALTEK_TEXT_DEBUG
  69. atomic_t text_count;
  70. #endif
  71.  
  72. #include <asm/io.h>
  73. #include <asm/bugs.h>
  74. #include <asm/setup.h>
  75.  
  76. #include <platform.h>
  77.  
  78. /*
  79.  * This is one of the first .c files built. Error out early
  80.  * if we have compiler trouble..
  81.  */
  82. #if __GNUC__ == 2 && __GNUC_MINOR__ == 96
  83. #ifdef CONFIG_FRAME_POINTER
  84. #error This compiler cannot compile correctly with frame pointers enabled
  85. #endif
  86. #endif
  87.  
  88. #ifdef CONFIG_X86_LOCAL_APIC
  89. #include <asm/smp.h>
  90. #endif
  91.  
  92. /*
  93.  * Versions of gcc older than that listed below may actually compile
  94.  * and link okay, but the end product can have subtle run time bugs.
  95.  * To avoid associated bogus bug reports, we flatly refuse to compile
  96.  * with a gcc that is known to be too old from the very beginning.
  97.  */
  98. #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)
  99. #error Sorry, your GCC is too old. It builds incorrect kernels.
  100. #endif
  101.  
  102. static int init(void *);
  103.  
  104. extern void init_IRQ(void);
  105. extern void sock_init(void);
  106. extern void fork_init(unsigned long);
  107. extern void mca_init(void);
  108. extern void sbus_init(void);
  109. extern void sysctl_init(void);
  110. extern void signals_init(void);
  111. extern void buffer_init(void);
  112. extern void pidhash_init(void);
  113. extern void pidmap_init(void);
  114. extern void prio_tree_init(void);
  115. extern void radix_tree_init(void);
  116. extern void free_initmem(void);
  117. extern void populate_rootfs(void);
  118. extern void driver_init(void);
  119. extern void prepare_namespace(void);
  120. #ifdef  CONFIG_ACPI
  121. extern void acpi_early_init(void);
  122. #else
  123. static inline void acpi_early_init(void) { }
  124. #endif
  125.  
  126. #ifdef CONFIG_TC
  127. extern void tc_init(void);
  128. #endif
  129.  
  130. #ifdef CONFIG_REALTEK_RESERVE_DVR
  131. #define SYNC_STRUCT_ADDR 0xa00000cc
  132.  
  133. extern int DVR_zone_disable(void);
  134. extern int DVR_zone_enable(void);
  135. #endif
  136.  
  137. enum system_states system_state;
  138. EXPORT_SYMBOL(system_state);
  139.  
  140. /*
  141.  * Boot command-line arguments
  142.  */
  143. #define MAX_INIT_ARGS CONFIG_INIT_ENV_ARG_LIMIT
  144. #define MAX_INIT_ENVS CONFIG_INIT_ENV_ARG_LIMIT
  145.  
  146. extern void time_init(void);
  147. /* Default late time init is NULL. archs can override this later. */
  148. void (*late_time_init)(void);
  149. extern void softirq_init(void);
  150.  
  151. /* Untouched command line (eg. for /proc) saved by arch-specific code. */
  152. char saved_command_line[COMMAND_LINE_SIZE];
  153.  
  154. static char *execute_command;
  155.  
  156. /* Setup configured maximum number of CPUs to activate */
  157. static unsigned int max_cpus = NR_CPUS;
  158.  
  159. #ifdef CONFIG_PRINTK
  160. void printk_setup(void);
  161. void printk_setup_tail(void);
  162. #endif
  163.  
  164. #if CONFIG_REALTEK_TEXT_DEBUG || CONFIG_REALTEK_MEMORY_DEBUG_MODE || CONFIG_REALTEK_USER_DEBUG
  165. irqreturn_t sb2_dbg_isr(int irq, void *dev_id, struct pt_regs *regs)
  166. {
  167.     int itr, epc;
  168. //  printk("sb2 dbg number %d...\n", irq);
  169.  
  170.     itr = readl((void *)0xb801a4e0);
  171.     if (itr & 0x410) {
  172.         int addr = readl((void *)0xb801a4c0), mask=0x3fffffff;
  173.  
  174.         // prevent the false alarm of prefetch in audio memory region...
  175.         if (!(addr&0x80000000) && ((addr&mask) >= audio_addr) && ((addr&mask) < audio_addr+PREFETCH_BUFFER)) {
  176.             outl(0x0000400, SB2_DGB_INT);
  177.             return IRQ_HANDLED;
  178.         }
  179.  
  180.         asm ("mfc0 %0, $14;": "=r"(epc));
  181.         printk("System got interrupt from SB2...\n");
  182.         printk("SB2_DBG_INT:  0x%08x \n", readl((void *)0xb801a4e0));
  183.         printk("SB2_DBG_ADDR: 0x%08x \n", readl((void *)0xb801a4c0));
  184.         printk("Access Address: 0x%x \n", epc);
  185.         show_regs(regs);
  186.         dump_stack();
  187.        
  188.         local_irq_disable();
  189.         while (1) ;
  190.     } else {
  191.             return IRQ_NONE;
  192.     }
  193.  
  194.     return IRQ_HANDLED;
  195. }
  196.  
  197. static struct irqaction sb2_dbg_action = {
  198.     .handler        = sb2_dbg_isr,
  199.     .flags          = SA_INTERRUPT | SA_SHIRQ,
  200.     .name           = "SB2_DBG",
  201. };
  202.  
  203. void __init sb2_dbg_init(void)
  204. {
  205.     if (is_venus_cpu()) {
  206.         printk("This is not Neptune platform. The SB2 Debug facility is disabled. \n");
  207.         return;
  208.     }
  209.    
  210.         setup_irq(VENUS_INT_SB2, &sb2_dbg_action);
  211. //  request_irq(5, sb2_dbg_isr, SA_SHIRQ | SA_INTERRUPT, "SB2_DBG", (void *)SB2_DBG_ID);
  212. /*
  213.     writel(0x2000000, 0xb801a458);
  214.     writel(0x4000000, 0xb801a478);
  215.     writel(0x00003ff, 0xb801a498);
  216.     writel(0x0000081, 0xb801a4e0);
  217. */
  218. #ifdef CONFIG_REALTEK_TEXT_DEBUG
  219.     printk("<<<<< Enable TEXT protector >>>>>\n");
  220.     printk("\tsrc: %x \n", (zone_table[ZONE_TEXT]->zone_start_pfn)*4096);
  221.     printk("\tdst: %x \n", (zone_table[ZONE_TEXT]->zone_start_pfn+zone_table[ZONE_TEXT]->spanned_pages)*4096-1);
  222.     outl((zone_table[ZONE_TEXT]->zone_start_pfn)*4096, SB2_DGB_START_REG7);
  223.     outl((zone_table[ZONE_TEXT]->zone_start_pfn+zone_table[ZONE_TEXT]->spanned_pages)*4096-1, SB2_DGB_END_REG7);
  224.     outl(0x0003fdf, SB2_DGB_CTRL_REG7);
  225.     // only enable the system interrupt
  226.     outl(0x0000081, SB2_DGB_INT);
  227. #endif
  228. #ifdef CONFIG_REALTEK_MEMORY_DEBUG_MODE
  229.     printk("<<<<< Enable memory protector >>>>>\n");
  230.     // tlb handler (avoid trashing by audio & video)
  231.     outl(0x00000000, SB2_DGB_START_REG5);
  232.     outl(0x0000007f, SB2_DGB_END_REG5);
  233.     outl(0x0003e93, SB2_DGB_CTRL_REG5);
  234.     // kernel data (avoid trashing by audio & video)
  235.     outl(0x00100000+PREFETCH_BUFFER, SB2_DGB_START_REG6);
  236.     outl((unsigned int)&_edata-1, SB2_DGB_END_REG6);
  237.     outl(0x0003e93, SB2_DGB_CTRL_REG6);
  238.     // kernel text (avoid trashing by ourself)
  239.     outl(0x00100000+PREFETCH_BUFFER, SB2_DGB_START_REG7);
  240.     outl((unsigned int)&_etext-1, SB2_DGB_END_REG7);
  241.     outl(0x00003d3, SB2_DGB_CTRL_REG7);
  242.  
  243.     // only enable the system interrupt
  244.     outl(0x0000081, SB2_DGB_INT);
  245. #endif
  246. }
  247. #endif
  248.  
  249. /*
  250.  * Setup routine for controlling SMP activation
  251.  *
  252.  * Command-line option of "nosmp" or "maxcpus=0" will disable SMP
  253.  * activation entirely (the MPS table probe still happens, though).
  254.  *
  255.  * Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
  256.  * greater than 0, limits the maximum number of CPUs activated in
  257.  * SMP mode to <NUM>.
  258.  */
  259. static int __init nosmp(char *str)
  260. {
  261.     max_cpus = 0;
  262.     return 1;
  263. }
  264.  
  265. __setup("nosmp", nosmp);
  266.  
  267. static int __init maxcpus(char *str)
  268. {
  269.     get_option(&str, &max_cpus);
  270.     return 1;
  271. }
  272.  
  273. __setup("maxcpus=", maxcpus);
  274.  
  275. static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
  276. char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
  277. static const char *panic_later, *panic_param;
  278.  
  279. extern struct obs_kernel_param __setup_start[], __setup_end[];
  280.  
  281. static int __init obsolete_checksetup(char *line)
  282. {
  283.     struct obs_kernel_param *p;
  284.  
  285.     p = __setup_start;
  286.     do {
  287.         int n = strlen(p->str);
  288.         if (!strncmp(line, p->str, n)) {
  289.             if (p->early) {
  290.                 /* Already done in parse_early_param?  (Needs
  291.                  * exact match on param part) */
  292.                 if (line[n] == '\0' || line[n] == '=')
  293.                     return 1;
  294.             } else if (!p->setup_func) {
  295.                 printk(KERN_WARNING "Parameter %s is obsolete,"
  296.                        " ignored\n", p->str);
  297.                 return 1;
  298.             } else if (p->setup_func(line + n))
  299.                 return 1;
  300.         }
  301.         p++;
  302.     } while (p < __setup_end);
  303.     return 0;
  304. }
  305.  
  306. /*
  307.  * This should be approx 2 Bo*oMips to start (note initial shift), and will
  308.  * still work even if initially too large, it will just take slightly longer
  309.  */
  310. unsigned long loops_per_jiffy = (1<<12);
  311.  
  312. EXPORT_SYMBOL(loops_per_jiffy);
  313.  
  314. static int __init debug_kernel(char *str)
  315. {
  316.     if (*str)
  317.         return 0;
  318.     console_loglevel = 10;
  319.     return 1;
  320. }
  321.  
  322. static int __init quiet_kernel(char *str)
  323. {
  324.     if (*str)
  325.         return 0;
  326.     console_loglevel = 4;
  327.     return 1;
  328. }
  329.  
  330. __setup("debug", debug_kernel);
  331. __setup("quiet", quiet_kernel);
  332.  
  333. static int __init loglevel(char *str)
  334. {
  335.     get_option(&str, &console_loglevel);
  336.     return 1;
  337. }
  338.  
  339. __setup("loglevel=", loglevel);
  340.  
  341. /*
  342.  * Unknown boot options get handed to init, unless they look like
  343.  * failed parameters
  344.  */
  345. static int __init unknown_bootoption(char *param, char *val)
  346. {
  347.     /* Change NUL term back to "=", to make "param" the whole string. */
  348.     if (val) {
  349.         /* param=val or param="val"? */
  350.         if (val == param+strlen(param)+1)
  351.             val[-1] = '=';
  352.         else if (val == param+strlen(param)+2) {
  353.             val[-2] = '=';
  354.             memmove(val-1, val, strlen(val)+1);
  355.             val--;
  356.         } else
  357.             BUG();
  358.     }
  359.  
  360.     /* Handle obsolete-style parameters */
  361.     if (obsolete_checksetup(param))
  362.         return 0;
  363.  
  364.     /*
  365.      * Preemptive maintenance for "why didn't my mispelled command
  366.      * line work?"
  367.      */
  368.     if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
  369.         printk(KERN_ERR "Unknown boot option `%s': ignoring\n", param);
  370.         return 0;
  371.     }
  372.  
  373.     if (panic_later)
  374.         return 0;
  375.  
  376.     if (val) {
  377.         /* Environment option */
  378.         unsigned int i;
  379.         for (i = 0; envp_init[i]; i++) {
  380.             if (i == MAX_INIT_ENVS) {
  381.                 panic_later = "Too many boot env vars at `%s'";
  382.                 panic_param = param;
  383.             }
  384.             if (!strncmp(param, envp_init[i], val - param))
  385.                 break;
  386.         }
  387.         envp_init[i] = param;
  388.     } else {
  389.         /* Command line option */
  390.         unsigned int i;
  391.         for (i = 0; argv_init[i]; i++) {
  392.             if (i == MAX_INIT_ARGS) {
  393.                 panic_later = "Too many boot init vars at `%s'";
  394.                 panic_param = param;
  395.             }
  396.         }
  397.         argv_init[i] = param;
  398.     }
  399.     return 0;
  400. }
  401.  
  402. static int __init init_setup(char *str)
  403. {
  404.     unsigned int i;
  405.  
  406.     execute_command = str;
  407.     /*
  408.      * In case LILO is going to boot us with default command line,
  409.      * it prepends "auto" before the whole cmdline which makes
  410.      * the shell think it should execute a script with such name.
  411.      * So we ignore all arguments entered _before_ init=... [MJ]
  412.      */
  413.     for (i = 1; i < MAX_INIT_ARGS; i++)
  414.         argv_init[i] = NULL;
  415.     return 1;
  416. }
  417. __setup("init=", init_setup);
  418.  
  419. /* Now we only support secure boot on partition /dev/mtdblock/1. If /dev/mtdblock/1 has been modified after installation, Linux kernel will know that and do reboot. */
  420. #ifdef CONFIG_REALTEK_SECURE_BOOT_PARTITION
  421. char partition_hash_value[28]="";   // For Secure Boot V2, this is a sha1 hash value.
  422. static int __init partition_hash(char *hash_str)
  423. {
  424.     char *hash_tmp_ptr, *endptr;
  425.     char strtol_tmp[3];
  426.     int i;
  427.  
  428.     if(strncmp(hash_str, "1:", 2))
  429.         return 0;
  430.     *(unsigned int*)(partition_hash_value+4)=simple_strtol(hash_str+2, &endptr, 10);
  431.     if(endptr == hash_str+2)
  432.         return 0;
  433.     if(*endptr != ':')
  434.         return 0;
  435.     hash_tmp_ptr = endptr+1;
  436.     if(strlen(hash_tmp_ptr)!=40)
  437.         return 0;
  438.     strtol_tmp[2]=0;
  439.     for(i=0;i<20;i++) {
  440.         strncpy(strtol_tmp, hash_tmp_ptr+2*i, 2);
  441.         *(unsigned char*)(partition_hash_value+8+i) = simple_strtol(strtol_tmp, &endptr, 16);
  442.         if(*endptr)
  443.             return 0;
  444.     }
  445.     partition_hash_value[0]='1';
  446.     platform_info.secure_boot=1;
  447.     return 1;
  448. }
  449.  
  450. __setup("partition_hash=", partition_hash);
  451. #endif
  452.  
  453. extern void setup_arch(char **);
  454.  
  455. #ifndef CONFIG_SMP
  456.  
  457. #ifdef CONFIG_X86_LOCAL_APIC
  458. static void __init smp_init(void)
  459. {
  460.     APIC_init_uniprocessor();
  461. }
  462. #else
  463. #define smp_init()  do { } while (0)
  464. #endif
  465.  
  466. static inline void setup_per_cpu_areas(void) { }
  467. static inline void smp_prepare_cpus(unsigned int maxcpus) { }
  468.  
  469. #else
  470.  
  471. #ifdef __GENERIC_PER_CPU
  472. unsigned long __per_cpu_offset[NR_CPUS];
  473.  
  474. EXPORT_SYMBOL(__per_cpu_offset);
  475.  
  476. static void __init setup_per_cpu_areas(void)
  477. {
  478.     unsigned long size, i;
  479.     char *ptr;
  480.     /* Created by linker magic */
  481.     extern char __per_cpu_start[], __per_cpu_end[];
  482.  
  483.     /* Copy section for each CPU (we discard the original) */
  484.     size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
  485. #ifdef CONFIG_MODULES
  486.     if (size < PERCPU_ENOUGH_ROOM)
  487.         size = PERCPU_ENOUGH_ROOM;
  488. #endif
  489.  
  490.     ptr = alloc_bootmem(size * NR_CPUS);
  491.  
  492.     for (i = 0; i < NR_CPUS; i++, ptr += size) {
  493.         __per_cpu_offset[i] = ptr - __per_cpu_start;
  494.         memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
  495.     }
  496. }
  497. #endif /* !__GENERIC_PER_CPU */
  498.  
  499. /* Called by boot processor to activate the rest. */
  500. static void __init smp_init(void)
  501. {
  502.     unsigned int i;
  503.  
  504.     /* FIXME: This should be done in userspace --RR */
  505.     for_each_present_cpu(i) {
  506.         if (num_online_cpus() >= max_cpus)
  507.             break;
  508.         if (!cpu_online(i))
  509.             cpu_up(i);
  510.     }
  511.  
  512.     /* Any cleanup work */
  513.     printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus());
  514.     smp_cpus_done(max_cpus);
  515. #if 0
  516.     /* Get other processors into their bootup holding patterns. */
  517.  
  518.     smp_commence();
  519. #endif
  520. }
  521.  
  522. #endif
  523.  
  524. /*
  525.  * We need to finalize in a non-__init function or else race conditions
  526.  * between the root thread and the init thread may cause start_kernel to
  527.  * be reaped by free_initmem before the root thread has proceeded to
  528.  * cpu_idle.
  529.  *
  530.  * gcc-3.4 accidentally inlines this function, so use noinline.
  531.  */
  532.  
  533. static void noinline rest_init(void)
  534.     __releases(kernel_lock)
  535. {
  536.     kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
  537.     numa_default_policy();
  538.     unlock_kernel();
  539.     preempt_enable_no_resched();
  540.     cpu_idle();
  541. }
  542.  
  543. /* Check for early params. */
  544. static int __init do_early_param(char *param, char *val)
  545. {
  546.     struct obs_kernel_param *p;
  547.  
  548.     for (p = __setup_start; p < __setup_end; p++) {
  549.         if (p->early && strcmp(param, p->str) == 0) {
  550.             if (p->setup_func(val) != 0)
  551.                 printk(KERN_WARNING
  552.                        "Malformed early option '%s'\n", param);
  553.         }
  554.     }
  555.     /* We accept everything at this stage. */
  556.     return 0;
  557. }
  558.  
  559. /* Arch code calls this early on, or if not, just before other parsing. */
  560. void __init parse_early_param(void)
  561. {
  562.     static __initdata int done = 0;
  563.     static __initdata char tmp_cmdline[COMMAND_LINE_SIZE];
  564.  
  565.     if (done)
  566.         return;
  567.  
  568.     /* All fall through to do_early_param. */
  569.     strlcpy(tmp_cmdline, saved_command_line, COMMAND_LINE_SIZE);
  570.     parse_args("early options", tmp_cmdline, NULL, 0, do_early_param);
  571.     done = 1;
  572. }
  573.  
  574. /*
  575.  *  Activate the first processor.
  576.  */
  577.  
  578. asmlinkage void __init start_kernel(void)
  579. {
  580.     char * command_line;
  581.     extern struct kernel_param __start___param[], __stop___param[];
  582. #ifdef CONFIG_REALTEK_RESERVE_DVR
  583.     char *ptr = (char *)ntohl(*(unsigned long *)SYNC_STRUCT_ADDR);
  584. #endif
  585. /*
  586.  * Interrupts are still disabled. Do necessary setups, then
  587.  * enable them
  588.  */
  589. #ifdef CONFIG_PRINTK
  590. #ifdef CONFIG_SHARED_PRINTK
  591.     *(volatile int *)0xb801a000=0;
  592. #endif
  593.     printk_setup();
  594. #endif
  595.     lock_kernel();
  596.     page_address_init();
  597.     printk(KERN_NOTICE);
  598.     printk(linux_banner);
  599.     setup_arch(&command_line);
  600.     setup_per_cpu_areas();
  601.  
  602.     /*
  603.      * Mark the boot cpu "online" so that it can call console drivers in
  604.      * printk() and can access its per-cpu storage.
  605.      */
  606.     smp_prepare_boot_cpu();
  607.  
  608.     /*
  609.      * Set up the scheduler prior starting any interrupts (such as the
  610.      * timer interrupt). Full topology setup happens at smp_init()
  611.      * time - but meanwhile we still have a functioning scheduler.
  612.      */
  613.     sched_init();
  614.     /*
  615.      * Disable preemption - early bootup scheduling is extremely
  616.      * fragile until we cpu_idle() for the first time.
  617.      */
  618.     preempt_disable();
  619.     build_all_zonelists();
  620.     page_alloc_init();
  621.     printk(KERN_NOTICE "Kernel command line: %s\n", saved_command_line);
  622.     parse_early_param();
  623.     parse_args("Booting kernel", command_line, __start___param,
  624.            __stop___param - __start___param,
  625.            &unknown_bootoption);
  626.     sort_main_extable();
  627.     trap_init();
  628.     rcu_init();
  629.     init_IRQ();
  630.     pidhash_init();
  631.     init_timers();
  632.     softirq_init();
  633.     time_init();
  634.  
  635. #if CONFIG_REALTEK_TEXT_DEBUG || CONFIG_REALTEK_MEMORY_DEBUG_MODE || CONFIG_REALTEK_USER_DEBUG
  636.     sb2_dbg_init();
  637. #endif
  638.     /*
  639.      * HACK ALERT! This is early. We're enabling the console before
  640.      * we've done PCI setups etc, and console_init() must be aware of
  641.      * this. But we do want output early, in case something goes wrong.
  642.      */
  643.     console_init();
  644.     if (panic_later)
  645.         panic(panic_later, panic_param);
  646.     profile_init();
  647.     local_irq_enable();
  648. #ifdef CONFIG_BLK_DEV_INITRD
  649.     if (initrd_start && !initrd_below_start_ok &&
  650.             initrd_start < min_low_pfn << PAGE_SHIFT) {
  651.         printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
  652.             "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
  653.         initrd_start = 0;
  654.     }
  655. #endif
  656.     vfs_caches_init_early();
  657.     mem_init();
  658. #ifdef CONFIG_REALTEK_RESERVE_DVR
  659.     /* reserve the DVR zone for boot-up audio & video */
  660. //  printk("### PTR1: %p \n", ptr);
  661.     if (ptr) {
  662.         if (DVR_zone_disable()) {
  663.             printk("*****reserve DVR zone...\n");
  664.         }
  665.     }
  666. #endif
  667.     kmem_cache_init();
  668.     numa_policy_init();
  669.     if (late_time_init)
  670.         late_time_init();
  671.     calibrate_delay();
  672.     pidmap_init();
  673.     pgtable_cache_init();
  674.     prio_tree_init();
  675.     anon_vma_init();
  676. #ifdef CONFIG_X86
  677.     if (efi_enabled)
  678.         efi_enter_virtual_mode();
  679. #endif
  680.     fork_init(num_physpages);
  681.     proc_caches_init();
  682.     buffer_init();
  683.     unnamed_dev_init();
  684.     key_init();
  685.     security_init();
  686.     vfs_caches_init(num_physpages);
  687.     radix_tree_init();
  688.     signals_init();
  689.     /* rootfs populating might need page-writeback */
  690.     page_writeback_init();
  691. #ifdef CONFIG_PROC_FS
  692.     proc_root_init();
  693. #endif
  694.     cpuset_init();
  695.  
  696.     check_bugs();
  697.  
  698.     acpi_early_init(); /* before LAPIC and SMP init */
  699.  
  700.     /* Do the rest non-__init'ed, we're now alive */
  701.     rest_init();
  702. }
  703.  
  704. static int __initdata initcall_debug;
  705.  
  706. static int __init initcall_debug_setup(char *str)
  707. {
  708.     initcall_debug = 1;
  709.     return 1;
  710. }
  711. __setup("initcall_debug", initcall_debug_setup);
  712.  
  713. struct task_struct *child_reaper = &init_task;
  714.  
  715. extern initcall_t __initcall_start[], __initcall_end[];
  716.  
  717. static void __init do_initcalls(void)
  718. {
  719.     initcall_t *call;
  720.     int count = preempt_count();
  721.  
  722.     for (call = __initcall_start; call < __initcall_end; call++) {
  723.         char *msg;
  724.  
  725.         if (initcall_debug) {
  726.             printk(KERN_DEBUG "Calling initcall 0x%p", *call);
  727.             print_fn_descriptor_symbol(": %s()", (unsigned long) *call);
  728.             printk("\n");
  729.         }
  730.  
  731.         (*call)();
  732.  
  733.         msg = NULL;
  734.         if (preempt_count() != count) {
  735.             msg = "preemption imbalance";
  736.             preempt_count() = count;
  737.         }
  738.         if (irqs_disabled()) {
  739.             msg = "disabled interrupts";
  740.             local_irq_enable();
  741.         }
  742.         if (msg) {
  743.             printk(KERN_WARNING "error in initcall at 0x%p: "
  744.                 "returned with %s\n", *call, msg);
  745.         }
  746.     }
  747.  
  748.     /* Make sure there is no pending stuff from the initcall sequence */
  749.     flush_scheduled_work();
  750. }
  751.  
  752. /*
  753.  * Ok, the machine is now initialized. None of the devices
  754.  * have been touched yet, but the CPU subsystem is up and
  755.  * running, and memory and process management works.
  756.  *
  757.  * Now we can finally start doing some real work..
  758.  */
  759. static void __init do_basic_setup(void)
  760. {
  761.     /* drivers will send hotplug events */
  762.     init_workqueues();
  763.     usermodehelper_init();
  764.     driver_init();
  765.  
  766. #ifdef CONFIG_SYSCTL
  767.     sysctl_init();
  768. #endif
  769.  
  770.     /* Networking initialization needs a process context */
  771.     sock_init();
  772.  
  773.     do_initcalls();
  774. }
  775.  
  776. static void do_pre_smp_initcalls(void)
  777. {
  778.     extern int spawn_ksoftirqd(void);
  779. #ifdef CONFIG_SMP
  780.     extern int migration_init(void);
  781.  
  782.     migration_init();
  783. #endif
  784.     spawn_ksoftirqd();
  785. }
  786.  
  787. static void run_init_process(char *init_filename)
  788. {
  789.     argv_init[0] = init_filename;
  790.     execve(init_filename, argv_init, envp_init);
  791. }
  792.  
  793. static inline void fixup_cpu_present_map(void)
  794. {
  795. #ifdef CONFIG_SMP
  796.     int i;
  797.  
  798.     /*
  799.      * If arch is not hotplug ready and did not populate
  800.      * cpu_present_map, just make cpu_present_map same as cpu_possible_map
  801.      * for other cpu bringup code to function as normal. e.g smp_init() etc.
  802.      */
  803.     if (cpus_empty(cpu_present_map)) {
  804.         for_each_cpu(i) {
  805.             cpu_set(i, cpu_present_map);
  806.         }
  807.     }
  808. #endif
  809. }
  810.  
  811. static int init(void * unused)
  812. {
  813. #ifdef CONFIG_REALTEK_RESERVE_DVR
  814.     int aflag = 0, vflag = 0;
  815.     char *ptr = (char *)ntohl(*(unsigned long *)SYNC_STRUCT_ADDR);
  816. #endif
  817.  
  818.     lock_kernel();
  819.     /*
  820.      * init can run on any cpu.
  821.      */
  822.     set_cpus_allowed(current, CPU_MASK_ALL);
  823.     /*
  824.      * Tell the world that we're going to be the grim
  825.      * reaper of innocent orphaned children.
  826.      *
  827.      * We don't want people to have to make incorrect
  828.      * assumptions about where in the task array this
  829.      * can be found.
  830.      */
  831.     child_reaper = current;
  832.  
  833.     /* Sets up cpus_possible() */
  834.     smp_prepare_cpus(max_cpus);
  835.  
  836.     do_pre_smp_initcalls();
  837.  
  838.     fixup_cpu_present_map();
  839.     smp_init();
  840.     sched_init_smp();
  841.  
  842.     cpuset_init_smp();
  843.  
  844.     /*
  845.      * Do this before initcalls, because some drivers want to access
  846.      * firmware files.
  847.      */
  848.     populate_rootfs();
  849.  
  850.     do_basic_setup();
  851.  
  852. #ifdef CONFIG_PRINTK
  853.     printk_setup_tail();
  854. #endif
  855.     /*
  856.      * check if there is an early userspace init.  If yes, let it do all
  857.      * the work
  858.      */
  859.     if (sys_access((const char __user *) "/init", 0) == 0)
  860.         execute_command = "/init";
  861.     else
  862.         prepare_namespace();
  863.  
  864.     /*
  865.      * Ok, we have completed the initial bootup, and
  866.      * we're essentially up and running. Get rid of the
  867.      * initmem segments and start the user-mode stuff..
  868.      */
  869.     free_initmem();
  870.     unlock_kernel();
  871.     system_state = SYSTEM_RUNNING;
  872.     numa_default_policy();
  873.  
  874.     if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
  875.         printk(KERN_WARNING "Warning: unable to open an initial console.\n");
  876.  
  877.     (void) sys_dup(0);
  878.     (void) sys_dup(0);
  879.    
  880. #ifdef CONFIG_REALTEK_RESERVE_DVR
  881. //      printk("### PTR2: %p \n", ptr);
  882.     if (ptr) {
  883.         while (1) {
  884.             if (!aflag) {
  885.                 // check audio flag...
  886.                 if (ptr[21]) {
  887.                     aflag = 1;
  888.                     printk("*****audio is ready...\n");
  889.                 }
  890.             }
  891.             if (!vflag) {
  892.                 // check video flag...
  893.                 if (ptr[20]) {
  894.                     vflag = 1;
  895.                     printk("*****video is ready...\n");
  896.                 }
  897.             }
  898.    
  899.             if (aflag && vflag)
  900.                 break;
  901.    
  902.             msleep(100);
  903.         }
  904.     DVR_zone_enable();
  905.     }
  906. #endif
  907.  
  908. /* Here we check the hash value of some partition, which is passed from bootloader, to make sure that partition is not modified.
  909.     The format of that bootloader variable is partition_hash="[partition num]:[partition size]:[hash value]". Exp: go 0x80100000 ... partition_hash="1:1234:12341234123412341234123412341234" */
  910. #ifdef CONFIG_REALTEK_SECURE_BOOT_PARTITION
  911.     if(partition_hash_value[0] == '1') {
  912.         int fd=sys_open("/dev/mtdblock/1", O_RDONLY, 0);
  913.         int partitionsize, imagesize, hashcount;
  914.         int i;
  915.         MCP_BUFF *pBuff;
  916.         MCP_MD_CTX ctx;
  917.         unsigned char hash[MCP_MAX_DIGEST_SIZE];
  918.         unsigned int HashLen;
  919.        
  920.         if(fd<0) {
  921.             printk(KERN_ALERT "Error! sys_open cannot open /dev/mtdblock/1.\n");
  922.             machine_restart("Secure boot error!");
  923.         }
  924.  
  925.         pBuff = alloc_mcpb(512*1024);
  926.         if(!pBuff) {
  927.             printk("alloc_mcpb error!\n");
  928.             BUG();
  929.         }
  930.                
  931.         MCP_MD_CTX_init(&ctx);
  932.         MCP_DigestInit(&ctx, MCP_mars_sha1());
  933.        
  934.         partitionsize = sys_lseek(fd, 0, 2);
  935.         sys_lseek(fd, 0, 0);
  936.         imagesize=*(unsigned int*)(partition_hash_value+4);
  937.         for(hashcount=0; imagesize>hashcount;) {
  938.             int singlecount;
  939.             int len;
  940.  
  941.             mcpb_purge(pBuff);
  942.  
  943.             if((imagesize-hashcount)>=512*1024)
  944.                 singlecount = 512*1024;
  945.             else
  946.                 singlecount = imagesize-hashcount;
  947.  
  948.             len = sys_read(fd, pBuff->data, singlecount);
  949.  
  950.             if(len != singlecount) {
  951.                 printk(KERN_ALERT "Error! sys_read didn't return the number of chars we expected. len=%d\n", len);
  952.                 sys_close(fd);
  953.                 machine_restart("Secure boot error!");
  954.             }
  955.                        
  956.             mcpb_put(pBuff, singlecount);
  957.  
  958.             /* For secure boot, only squashfs-root is supported, and it is scrambled before doing hash. */
  959.             /* Unscramble */
  960.             MCP_AES_ECB_Decryption(platform_info.AES_IMG_KEY, pBuff->data, pBuff->data, len);
  961.             /* Calculate hash value */
  962. //          MCP_AES_H_DataHash(hash_buffer, singlecount, hash_array, 512*1024, firstblock);
  963.             hashcount+=singlecount;
  964.            
  965.             MCP_DigestUpdate(&ctx, pBuff);
  966.         }
  967.        
  968.         MCP_DigestFinal(&ctx, hash, &HashLen);
  969.         MCP_MD_CTX_cleanup(&ctx);
  970. //      mcp_dump_data_with_text(hash, HashLen, "[MCP] SAH1 hash value : ");
  971. //      mcp_dump_data_with_text(partition_hash_value+8 , 20, "SAH1 hash value : ");
  972.  
  973. /*
  974. // RSA related stuff. Now bootloader will do RSA calculation for Linux kernel.
  975.         BI*           signature;
  976.         BI*           pub_exp;
  977.         BI*           modulous;
  978.         BI*           hash_ref;
  979.         signature = InPutFromStr(signature_str, HEX);
  980.         pub_exp   = move_p(65537);
  981.         modulous  = InPutFromStr(modulus_str, HEX);
  982.         hash_ref  = init_BI();
  983.         rsa_verify(signature, pub_exp, modulous, hash_ref);
  984.         dump_bi(hash_ref);*/
  985.  
  986.         if(memcmp(hash, partition_hash_value+8, 20)) {
  987.             printk(KERN_ALERT "Error! Hash value of partition /dev/mtdblock/1 is not matched. That partition data in Nand Flash may be modified or damaged.\n");
  988.             sys_close(fd);
  989.             machine_restart("Secure boot error!");
  990.         }
  991.  
  992.         while(partitionsize>hashcount) {
  993.             int len;
  994.             sys_lseek(fd, hashcount&(0-512*1024), 0);
  995.             len = sys_read(fd, pBuff->data, 512*1024);
  996.             for(i=(hashcount&(512*1024-1));i<len;i++) {
  997.                 if(pBuff->data[i] != 0xff) {
  998.                     printk(KERN_ALERT "Error! The byte\(%d\) behind partition /dev/mtdblock/1 should be 0xFF. That partition data in Nand Flash may be modified or damaged.\n", hashcount+i);
  999.                     sys_close(fd);
  1000.                     machine_restart("Secure boot error!");
  1001.                 }
  1002.             }
  1003.             hashcount+=(len-(hashcount&(512*1024-1)));
  1004.         }
  1005.            
  1006.         printk("Secure boot succeeded. The partition /dev/mtdblock/1 is secure.\n");
  1007.         free_mcpb(pBuff);
  1008.         sys_close(fd);
  1009.     }
  1010. #endif
  1011.  
  1012.     /*
  1013.      * We try each of these until one succeeds.
  1014.      *
  1015.      * The Bourne shell can be used instead of init if we are
  1016.      * trying to recover a really broken machine.
  1017.      */
  1018.  
  1019.     if (execute_command)
  1020.         run_init_process(execute_command);
  1021.  
  1022.     run_init_process("/sbin/init");
  1023.     run_init_process("/etc/init");
  1024.     run_init_process("/bin/init");
  1025.     run_init_process("/bin/sh");
  1026.  
  1027.     panic("No init found.  Try passing init= option to kernel.");
  1028. }
Add Comment
Please, Sign In to add comment