We know that during uClinux initialization, there is no output until console_init is called, and their output is placed in the buffer of _ log_buf, when lele_init is called, the data in the buffer zone is output at one time. So what does eagle_init do? /** Initialize the console device. this is called * early *, so * We can't necessarily depend on lots of kernel help here. * Just do some early initializations, and do the complex setup * later. */void _ init lele_init (void) {initcall_t * call;/* setup the default tty line discipline. */(void) tty_register_ldisc (n_tty, & tty_ldisc_n_tty);/** set up the console device so that later boot sequenc Es can * inform about problems Etc .. */# ifdef config_early_printk disable_early_printk (); # endif call = _ con_initcall_start; while (call <_ con_initcall_end) {(* Call) (); Call ++ ;}} from this function, we can roughly guess that the initialization operations of the console and serial ports should be completed through function calls between _ con_initcall_start and _ con_initcall_end. So how do functions in this space come from? What functions can be stored in this space? Let's take a look at the definition of the two symbols in the LDF file: ___ con_initcall_start = .; input_sections ($ libraries_sml3_cm (. con_initcall.init) ___ con_initcall_end = .; it turns out that this space is stored. con_initcall.init. con_initcall.init. Search for initcall In the uClinux header file and find the following definition: # define console_initcall (FN) /static initcall_t _ initcall _ # FN/_ attribute_used _ attribute _ (_ Section __(". con_initcall.init ") = FN Let's see another line in drivers/serial/bfin_5xx.c: lele_initcall (bfin_serial_rs_console_init); here we can see that it declares a function pointer variable, this variable is placed in. in the data segment con_initcall.init, and the value of this pointer points to the bfin_serial_rs_console_init function. In this way, you can use this function pointer to call the bfin_serial_rs_console_init function in the lele_init function. The bf561 serial port Initialization is completed in the bfin_serial_rs_console_init function. This function also outputs data in the buffer zone from the serial port. When porting this part of the code, I encountered a problem. In bfin_5xx.c, there is a function bfin_serial_set_termios. Its function is to set the serial parameter, but before setting the parameter, it requires that the sending buffer be empty: do {LSR = uart_get_lsr (UART);} while (! (LSR & TEMT), that is, it indicates that the TEMT bit in the uart_lsr register is 1, but when it is actually running here, this bit is 0, so it enters an endless loop. Tracking found in head. in S, there is a piece of code to set UART:/* initialise UART */1_h = Hi (uart_lcr); 1_l = Lo (uart_lcr); R0 = 0x80 (z ); /* 0x0 (z) */W [P0] = r0.l before modification;/* to enable DLL writes */ssync; ready H = Hi (uart_dll ); export L = Lo (uart_dll); R0 = 0x0 (z); W [P0] = r0.l; ssync; export H = Hi (uart_dlh); export L = Lo (uart_dlh ); r0 = 0x00 (z); W [P0] = r0.l; ssync; running H = Hi (uart_gctl); running L = Lo (uart_gctl ); r0 = 0x0 (z); W [P0] = r0.l;/* To ena Ble UART clock */ssync; we know that when uart_dll and uart_dlh are set, the highest bit of uart_lcr must be set to 1, but not in the original code, in this case, the uart_dll setting fails. In this case, the TEMT flag of uart_lcr is set to 0, resulting in an endless loop. Modify the above red flag code to solve this problem. However, the strange thing is that this problem does not occur during GCC compilation in uClinux !! Why ?? When the program runs here, you can see the data in the previous output buffer through the serial port. Celebrate yourself first! Haha! Linux version 2.6.19.3-ADI-2007R1.1-svn (wmz@gtw.com) (vdsp 4.5) #2 Tue Sep 25 11:24:43 CST 2007 Blackfin support (c) 2004-2007 Analog Devices, Inc. compiled for ADSP-BF561 rev 0.3 Blackfin Linux support by http://blackfin.uclinux.org/Processor speed: 594 MHz core clock and 99 MHz system clockboard memory: 4 mbkernel managed memory: 4 mbmemory map: TEXT = 0x000-0x00020544 init = Invalid Data = Invalid stack = 0x00030000-0x00032000 BSS = 0x00032cc4-0x00032cc4 available = Invalid cache enabledhardware trace enabledbuilt 1 zonelists. total pages: 1016 kernel command line:
Note that the SDRAM is intentionally changed to 4 MB, not an error.