How linux porting is done? What are all the challenges?
build → make config
make dep
make
Change of memory map → Where?
Kernel Boot flow?
http://milindchoudhary.wordpress.com/2009/03/30/linux-boot-process
vmlinux image is compressed and zImage is created.
_zimage_start → ELF ENTRY → arch/powerpc/boot/zImage.lds.S
ordered as text, data, dtb(embedded Device tree blob), vmlinux, initrd, bss
To extract the kernel vmlinux, System.map, .config or initrd from the zImage binary:
objcopy -j .kernel:vmlinux -O binary zImage vmlinux.gz
objcopy -j .kernel:System.map -O binary zImage System.map.gz
objcopy -j .kernel:.config -O binary zImage config.gz
objcopy -j .kernel:initrd -O binary zImage.initrd initrd.gz
_zimage_start → arch/powerpc/boot/crt0.S
Initialized stack, bss and C environment
call platform_init
branch to start
platform_init → arch/powerpc/boot/redboot-8xx.c
initialize serial console
display clock-frequency
assign the command line to loader_info
start → arch/powerpc/boot/main.c
"\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r"
prepare kernel (prep_kernel())
unzip _vmlinux_start, _vmlinux_end
"Allocating 0x%lx bytes for kernel ...\n\r"
prepare ramdisk (prep_initrd())
"Attached initrd image at 0x%p-0x%p\n\r"
or
"Using loader supplied ramdisk at 0x%lx-0x%lx\n\r"
"Allocating 0x%lx bytes for initrd ...\n\r"
"Relocating initrd 0x%lx <- 0x%p (0x%lx bytes)\n\r"
/* Tell the kernel initrd address via device tree */
"linux,initrd-start" "linux,initrd-end"
prepare command line (prep_cmdline())
"bootargs" "\n\rLinux/PowerPC load: %s"
/* If possible, edit the command line */
/* Put the command line back into the devtree for the kernel */
"bootargs", cmdline
Function pointer _vmlinux_start((unsigned long)initrd.addr, initrd.size, loader_info.promptr);
(Find the initial symbol of vmlinux image. Find vmlinux.lds. Makefile at top of Linux source.)
ENTRY(_stext) → arch/powerpc/kernel/vmlinux.lds
ENTRY(_stext) → arch/powerpc/kernel/head_8xx.S
to map the first 8M 1:1
call initial_mmu
call turn_on_mmu
/* Decide what sort of machine this is and initialize the MMU */
bl machine_init
bl MMU_init
branch to start_kernel
start_kernel → init/main.c
tick_init();
boot_cpu_init();
print linux banner
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
setup_command_line(command_line);
printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
sched_init();
init_IRQ();
init_timers();
sched_clock_init();
calibrate_delay();
rest_init();
rest_init();
rcu_scheduler_starting();
/*
* We need to spawn init first so that it obtains pid 1, however
* the init task will end up wanting to create kthreads, which, if
* we schedule it before we create kthreadd, will OOPS.
*/
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
schedule();
/* Call into cpu_idle with preempt disabled */
preempt_disable();
cpu_idle();
kernel_init → init/main.c
wait for kthreadd to complete
smp_init();
sched_init_smp();
do_basic_setup();
init_post();
init_post() → init/main.c
/* shell specified in cmd prompt or defaults */
run_init_process("/sbin/init");
Howto list, load, unload modules?
What is use of mmap?
Howto allocate physical memory and virtual memory space?
Where is the assembly part of the scheduler?
what are the challenges you face when you port the kernel?
How will you debug kernel crash?
Now I give you a new CPU and board. How will you port Linux to it? What are all the steps you do to make the Linux to work on that?
Linux WiFi stack and Bluetooth stack names?
Howto debug Linux kernel in virtual memory mapping?
How uClinux is different from other flavor of Linux?
http://www.eetimes.com/electronics-news/4134390/How-uClinux-provides-MMU-less-processors-with-an-alternative
uClinux is for MCU with NO mmu.
Differences between uClinux and Linux
・little kernel and user space software is affected with NO mmu
・lack of both memory protection and of a virtual memory model
・One consequence of operating without memory protection is that an invalid
pointer reference by even an unprivileged process may trigger an address
error, and potentially corrupt or even shut down the system.
・three primary consequences of running Linux without virtual memory
1) processes which are loaded by the kernel must be able to run
independently of their position in memory. One way to achieve this is to
"fix up" address references in a program once it is loaded into RAM. The
other is to generate code that uses only relative addressing (referred to
as PIC, or Position Independent Code) - uClinux supports both of these
methods.
2) memory allocation and deallocation occurs within a flat memory model.
Very dynamic memory allocation can result in fragmentation which can
starve the system. One way to improve the robustness of applications
that perform dynamic memory allocation is to replace malloc() calls with
requests from a preallocated buffer pool.
3) swapping pages in and out of memory is not implemented, since it cannot
be guaranteed that the pages would be loaded to the same location in
RAM. In embedded systems it is also unlikely that it would be acceptable
to suspend an application in order to use more RAM than is physically
available.
・absence of the fork() and brk() system calls.
・Under Linux, fork() is implemented using copy-on-write pages. Without an
MMU, uClinux cannot completely and reliably clone a process, nor does it
have access to copy-on-write. uClinux implements vfork() in order to
compensate for the lack of fork(). When a parent process calls vfork() to
create a child, both processes share all their memory space including the
stack. vfork() then suspends the parent's execution until the child process
either calls exit() or execve(). Note that multitasking is not otherwise
affected. It does, however, mean that older-style network daemons that make
extensive use of fork() must be modified. Since child processes run in the
same address space as their parents, the behaviour of both processes may
require modification in particular situations.
・uClinux has neither an autogrow stack nor brk() and so user space programs
must use the mmap() command to allocate memory. For convenience, our C
library implements malloc() as a wrapper to mmap(). There is a compile-time
option to set the stack size of a program.
・Program loaders which support position independent code (PIC) were added.
A new binary object code format, named 'flat' was created, which supports PIC
and which has a very compact header. Other program loaders, such as that for
ELF, were modified to support other formats which, instead of using PIC, use
absolute references which it is the responsibility of the kernel to 'fix up'
at run time. Each method has advantages and disadvantages. Traditional PIC is
quick and compact but has a size restriction on some architectures. For
example, the 16-bit relative jump in Motorola 68k architectures limits PIC
programs to 32K. The runtime fix-up technique removes this size restriction,
but incurs overhead when the program is loaded by the kernel.
How a system call is processed?
Through Supervisor call, get into the Kernel space.
How does ping do not flood at user rights?
Code for Linux Semaphore, Spin lock, Interrupt Disabling, Kernel preemption disabling.
build → make config
make dep
make
Change of memory map → Where?
Kernel Boot flow?
http://milindchoudhary.wordpress.com/2009/03/30/linux-boot-process
vmlinux image is compressed and zImage is created.
_zimage_start → ELF ENTRY → arch/powerpc/boot/zImage.lds.S
ordered as text, data, dtb(embedded Device tree blob), vmlinux, initrd, bss
To extract the kernel vmlinux, System.map, .config or initrd from the zImage binary:
objcopy -j .kernel:vmlinux -O binary zImage vmlinux.gz
objcopy -j .kernel:System.map -O binary zImage System.map.gz
objcopy -j .kernel:.config -O binary zImage config.gz
objcopy -j .kernel:initrd -O binary zImage.initrd initrd.gz
_zimage_start → arch/powerpc/boot/crt0.S
Initialized stack, bss and C environment
call platform_init
branch to start
platform_init → arch/powerpc/boot/redboot-8xx.c
initialize serial console
display clock-frequency
assign the command line to loader_info
start → arch/powerpc/boot/main.c
"\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r"
prepare kernel (prep_kernel())
unzip _vmlinux_start, _vmlinux_end
"Allocating 0x%lx bytes for kernel ...\n\r"
"gunzipping (0x%p <- 0x%p:0x%p)...""done 0x%x bytes\n\r"
prepare ramdisk (prep_initrd())
"Attached initrd image at 0x%p-0x%p\n\r"
or
"Using loader supplied ramdisk at 0x%lx-0x%lx\n\r"
"Allocating 0x%lx bytes for initrd ...\n\r"
"Relocating initrd 0x%lx <- 0x%p (0x%lx bytes)\n\r"
/* Tell the kernel initrd address via device tree */
"linux,initrd-start" "linux,initrd-end"
prepare command line (prep_cmdline())
"bootargs" "\n\rLinux/PowerPC load: %s"
/* If possible, edit the command line */
/* Put the command line back into the devtree for the kernel */
"bootargs", cmdline
Function pointer _vmlinux_start((unsigned long)initrd.addr, initrd.size, loader_info.promptr);
(Find the initial symbol of vmlinux image. Find vmlinux.lds. Makefile at top of Linux source.)
ENTRY(_stext) → arch/powerpc/kernel/vmlinux.lds
ENTRY(_stext) → arch/powerpc/kernel/head_8xx.S
to map the first 8M 1:1
call initial_mmu
call turn_on_mmu
/* Decide what sort of machine this is and initialize the MMU */
bl machine_init
bl MMU_init
branch to start_kernel
start_kernel → init/main.c
tick_init();
boot_cpu_init();
print linux banner
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
setup_command_line(command_line);
printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
sched_init();
init_IRQ();
init_timers();
sched_clock_init();
calibrate_delay();
rest_init();
rest_init();
rcu_scheduler_starting();
/*
* We need to spawn init first so that it obtains pid 1, however
* the init task will end up wanting to create kthreads, which, if
* we schedule it before we create kthreadd, will OOPS.
*/
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
schedule();
/* Call into cpu_idle with preempt disabled */
preempt_disable();
cpu_idle();
kernel_init → init/main.c
wait for kthreadd to complete
smp_init();
sched_init_smp();
do_basic_setup();
init_post();
init_post() → init/main.c
/* shell specified in cmd prompt or defaults */
run_init_process("/sbin/init");
Howto list, load, unload modules?
What is use of mmap?
Howto allocate physical memory and virtual memory space?
Where is the assembly part of the scheduler?
what are the challenges you face when you port the kernel?
How will you debug kernel crash?
Now I give you a new CPU and board. How will you port Linux to it? What are all the steps you do to make the Linux to work on that?
Linux WiFi stack and Bluetooth stack names?
Howto debug Linux kernel in virtual memory mapping?
How uClinux is different from other flavor of Linux?
http://www.eetimes.com/electronics-news/4134390/How-uClinux-provides-MMU-less-processors-with-an-alternative
uClinux is for MCU with NO mmu.
Differences between uClinux and Linux
・little kernel and user space software is affected with NO mmu
・lack of both memory protection and of a virtual memory model
・One consequence of operating without memory protection is that an invalid
pointer reference by even an unprivileged process may trigger an address
error, and potentially corrupt or even shut down the system.
・three primary consequences of running Linux without virtual memory
1) processes which are loaded by the kernel must be able to run
independently of their position in memory. One way to achieve this is to
"fix up" address references in a program once it is loaded into RAM. The
other is to generate code that uses only relative addressing (referred to
as PIC, or Position Independent Code) - uClinux supports both of these
methods.
2) memory allocation and deallocation occurs within a flat memory model.
Very dynamic memory allocation can result in fragmentation which can
starve the system. One way to improve the robustness of applications
that perform dynamic memory allocation is to replace malloc() calls with
requests from a preallocated buffer pool.
3) swapping pages in and out of memory is not implemented, since it cannot
be guaranteed that the pages would be loaded to the same location in
RAM. In embedded systems it is also unlikely that it would be acceptable
to suspend an application in order to use more RAM than is physically
available.
・absence of the fork() and brk() system calls.
・Under Linux, fork() is implemented using copy-on-write pages. Without an
MMU, uClinux cannot completely and reliably clone a process, nor does it
have access to copy-on-write. uClinux implements vfork() in order to
compensate for the lack of fork(). When a parent process calls vfork() to
create a child, both processes share all their memory space including the
stack. vfork() then suspends the parent's execution until the child process
either calls exit() or execve(). Note that multitasking is not otherwise
affected. It does, however, mean that older-style network daemons that make
extensive use of fork() must be modified. Since child processes run in the
same address space as their parents, the behaviour of both processes may
require modification in particular situations.
・uClinux has neither an autogrow stack nor brk() and so user space programs
must use the mmap() command to allocate memory. For convenience, our C
library implements malloc() as a wrapper to mmap(). There is a compile-time
option to set the stack size of a program.
・Program loaders which support position independent code (PIC) were added.
A new binary object code format, named 'flat' was created, which supports PIC
and which has a very compact header. Other program loaders, such as that for
ELF, were modified to support other formats which, instead of using PIC, use
absolute references which it is the responsibility of the kernel to 'fix up'
at run time. Each method has advantages and disadvantages. Traditional PIC is
quick and compact but has a size restriction on some architectures. For
example, the 16-bit relative jump in Motorola 68k architectures limits PIC
programs to 32K. The runtime fix-up technique removes this size restriction,
but incurs overhead when the program is loaded by the kernel.
How a system call is processed?
Through Supervisor call, get into the Kernel space.
How does ping do not flood at user rights?
Code for Linux Semaphore, Spin lock, Interrupt Disabling, Kernel preemption disabling.
No comments:
Post a Comment