ARM ขั้นตอนการบูตลินุกซ์

นี้จะเป็นชุดของบทความที่อธิบายว่าลินุกซ์เคอร์เนลรองเท้าขึ้นบนสถาปัตยกรรม ARM นี้เป็นส่วนหนึ่ง

ขั้นตอนการบู๊ต ARM Linux :

เราจะอธิบายขั้นตอนการบู๊ตของระบบ AT91RM9200 – on – ชิปที่สร้างขึ้นจากหน่วยประมวลผล ARM920T ARM Thumb Kwickbyte สร้างบอร์ดฝังตัวที่เรียกว่า kb9202 ตาม AT91RM9200 เราจะใช้บอร์ดนี้เป็นตัวอย่างและวิธีการดูรองเท้า Linux ขึ้นไปบนบอร์ดนี้

ก่อนที่จะเริ่มการอ่านนี้คุณต้องอ่าน AT91RM9200 แผ่นข้อมูล(Specification)

นอกจากนี้คุณยังต้องอ่าน ARM Architecture Reference Manual สำหรับความเข้าใจที่ดีขึ้นขั้นตอนการบู๊ต

องค์ประกอบในขั้นตอนการบู๊ต Linux :

ขั้นตอนการบู๊ต Linux เกี่ยวข้องกับองค์ประกอบต่อไปนี้

bootloader
ภาพ kernel
Root Filesystem

ก่อนที่เราจะดูว่าการทำงานองค์ประกอบข้างต้นต่อไปนี้เป็นกระแสการเรียกร้องของลินุกซ์ขั้นตอนการบู๊ตโปรแกรมสำหรับสถาปัตยกรรมแขน นี้จะช่วยให้ภาพโดยรวมขั้นตอนการบูตลินุกซ์ เราใช้ U – bootbootloader
ขั้นตอนการบู๊ต ARM Linux : ภาพรวม
U – boot :

_start (cpu/arm920t/start.S)

start_code (cpu/arm920t/start.S)

start_armboot (lib_arm board.c)

board_init (board/kb9202/kb9202.c)

timer_init (cpu/arm920t/at91/timer.c)

serial_init (drivers/serial/at91rm9200_usart.c)

main_loop (lib_arm board.c)

ตอนนี้ U – boot ขึ้นอยู่และทำงานและอยู่ใน U – boot รวดเร็วและพร้อมที่จะยอมรับคำสั่ง สมมติภาพ kernel ที่โหลดลงใน RAM และออก bootmคำสั่ง

do_bootm (ทั่วไป / cmd_bootm.c)

bootm_start (ทั่วไป / cmd_bootm.c)

bootm_load_os (ทั่วไป / cmd_bootm.c)

do_bootm_linux (lib_arm / bootm.c)

stext (ลินุกซ์โค้ง / แขน / เคอร์เนล / / head.S)

Control คือให้ลินุกซ์

เคอร์เนลลินุกซ์ :

stext (โค้งแข​​น / เคอร์เนล / head.S / : 78)

__lookup_processor_type (โค้งแข​​น / เคอร์เนล / / หัว common.S : 160)

__lookup_machine_type (โค้งแข​​น / เคอร์เนล / / หัว common.S : 211)

__create_page_tables(โค้งแข​​น / เคอร์เนล / head.S / : 219)

__arm920_setup (arch/arm/mm/proc-arm920.S : 389)

__enable_mmu (โค้งแข​​น / เคอร์เนล / head.S / : 160)

__turn_mmu_on (โค้งแข​​น / เคอร์เนล / head.S / : 205)

__switch_data (โค้งแข​​น / เคอร์เนล / / หัว common.S : 20)

start_kernel (/ main.c init : 529)

start_kernel (/ main.c init : 529)

tick_init (เมล็ดในเวลา / / เห็บ – common.c : 413)

setup_arch (โค้งแข​​น / เคอร์เนล / / setup.c : 666)

setup_machine (โค้งแข​​น / เคอร์เนล / / setup.c : 369)

lookup_machine_type ()

setup_command_line (init / main.c : 408)

build_all_zonelists (มม. / page_alloc.c : 3031)

parse_args (/ params.c kernel : 129)

mm_init (init / main.c : 516)

mem_init (โค้งแข​​น / / mm / init.c : 528)

kmem_cache_init (มม. / slab.c, มม. / slob.c, มม. / slub.c)

sched_init (เคอร์เนล / sched.c)

init_IRQ (โค้งแข​​น / เคอร์เนล / / irq.c)

init_timers (/ timer.c kernel : 1713)

hrtimers_init (/ hrtimer.c kernel : 1741)

softirq_init (/ softirq.c kernel : 674)

console_init(คนขับ / ถ่าน / tty_io.c : 3084)

vfs_caches_init (FS / dcache.c : 2352)

mnt_init (FS / namespace.c : 2308)

init_rootfs ()

init_mount_tree (FS / namespace.c : 2285)

(FS / namespace.c : 1053) do_kern_mount

(FS / fs_struct.c : 29) set_fs_pwd

(FS / fs_struct.c : 12) set_fs_root

bdev_cache_init (FS / block_dev.c : 465)

chrdev_init (FS / char_dev.c : 566)

signals_init (/ signal.c kernel : 2737)

rest_init (init / main.c : 425)

kernel_thread (431,โค้ง / แขนเคอร์เนล / / process.c : 388)

kernel_thread () สร้างหัวข้อเมล็ดและการควบคุมที่มอบให้แก่ kernel_init ()

kernel_init (431, init / main.c : 856)

do_basic_setup (888 / init main.c : 787)

init_workqueues (789 เมล็ด / workqueue.c : 1204)

driver_init (793, ไดรเวอร์ฐาน / / init.c : 20)

do_initcalls (796 / init main.c : 769) / โทร * ทั้งหมด subsytems init * ฟังก์ชั่น /

prepare_namespace (906, init / do_mounts.c : 366)

initrd_load (399,107) : / / do_mounts_initrd.c init

rd_load_image (117 init / do_mounts_rd.c : 158) * / ถ้า initrd จะได้รับ * /

identify_ramdisk_image (179 / do_mounts_rd.c init : 53)

handle_initrd (119 init / do_mounts_initrd.c : 37) * / * ถ้า rd_load_image เป็นความสำเร็จ /

mount_block_root (45, / do_mounts.c init : 233)

do_mount_root (247 init, do_mounts / :. 218)

mount_root (417 init / do_mounts.c : 334) * / หากไม่ได้รับ initrd / *

mount_block_root (359 / do_mounts.c init : 233)

do_mount_root (247,218) : / / do_mounts.c init

init_post (915 / init main.c : 816)

run_init_process (847 init / main.c : 807)

kernel_execve (810 โค้ง, แขน / เคอร์เนล / / sys_arm.c : 81)

สเปซของผู้ใช้

init () userspace * / sbin / init * / /

bootloader :

bootloader เป็นโปรแกรมขนาดเล็กที่จะโหลดภาพ kernel ลงใน RAM และรองเท้าขึ้นภาพ kernel นี้เรียกว่ายังเป็นที่จะนำ bootstrap (ดึง) ขึ้นระบบโดยโหลดระบบปฏิบัติการ bootloader เริ่มต้นก่อนที่จะเริ่มต้นซอฟต์แวร์อื่น ๆและทำการเริ่มต้นประมวลผลและทำให้ซีพียูพร้อมที่จะรันโปรแกรมเช่นระบบปฏิบัติการ หน่วยประมวลผลส่วนใหญ่มีที่อยู่เริ่มต้นจากที่ไบต์แรกของรหัสจะเรียกเมื่อมีการใช้อำนาจหรือคณะกรรมการมีการรีเซ็ต ออกแบบฮาร์ดแวร์ใช้ข้อมูลนี้เพื่อเก็บรหัส bootloader ที่ว่าที่อยู่ใน ROM หรือแฟลช เพราะมันควรเริ่มต้น CPU และควรรันโปรแกรมซึ่งตั้งอยู่ที่ bootloaders สถาปัตยกรรมที่อยู่ที่เฉพาะเจาะจงเป็นอย่างมากโดยเฉพาะโปรเซสเซอร์และคณะกรรมการเฉพาะทุกคณะที่ฝังตัวมาพร้อมกับบูตสแตรปในการดาวโหลดภาพ kernel หรือการใช้แบบสแตนด์อโลนลงในกระดานและเริ่มดำเนินการภาพ kernel หรือโปรแกรมประยุกต์ bootloader จะถูกดำเนินการเมื่อมีไฟที่ใช้กับบอร์ดตัวประมวลผล โดยทั่วไปจะมีคุณสมบัติที่น้อยที่สุดที่จะโหลดภาพและบูตมันขึ้น

นอกจากนี้ยังสามารถในการควบคุมระบบการใช้อินเตอร์เฟซฮาร์ดแวร์แก้ปัญหาเช่น JTAG อินเตอร์เฟซนี้อาจจะถูกใช้ในการเขียนโปรแกรมบูตเข้าบูตไม่ระเหยหน่วยความจำ (เช่นแฟลช) โดยสั่งให้แกนประมวลผลเพื่อดำเนินการที่จำเป็นในการโปรแกรมหน่วยความจำไม่ระเหย ดำเนินการโดยทั่วไปเป็นครั้งแรกเพื่อดาวน์โหลด bootloader พื้นฐานและสำหรับกระบวนการกู้คืนบางส่วน JTAG เป็นอินเตอร์เฟซมาตรฐานและเป็นที่นิยมได้มาจากผู้ขายหลายบอร์ด บางหน่วยควบคุมเล็กให้อินเตอร์เฟซฮาร์ดแวร์พิเศษที่ไม่สามารถใช้เพื่อการควบคุมของระบบโดยพลการหรือเรียกใช้โค้ดโดยตรง แต่จะอนุญาตให้ใส่รหัสบูตเป็นบูตหน่วยความจำไม่ระเหย (เช่นหน่วยความจำแฟลช) ผ่านโปรโตคอลอย่างง่าย จากนั้นในขั้นตอนการผลิต, อินเตอร์เฟซดังกล่าวจะใช้ในการฉีดรหัสบูต (และอาจมีรหัสอื่น ๆ ) ในหน่วยความจำไม่ระเหย หลังจากรีเซ็ตระบบ, ควบคุมไมโครเริ่มรันโค้ดโปรแกรมในหน่วยความจำไม่ระเหยของมันเช่นเดียวกับหน่วยประมวลผลตามปกติจะใช้สำหรับการบูตรอม อินเตอร์เฟซในหลาย ๆ กรณีนั้นจะถูกดำเนินการโดยตรรกะเดินสาย ในกรณีอื่น ๆ อินเตอร์เฟซดังกล่าวอาจจะสร้างขึ้นโดยซอฟต์แวร์ที่ทำงานในแบบบูรณาROM บูตบนชิปจากพิน GPIO

มีบางอื่น ๆ bootloaders บุคคลที่สามใช้ได้ซึ่งจะมีชุดที่อุดมไปด้วยคุณสมบัติและส่วนติดต่อผู้ใช้ง่ายมี คุณสามารถดาวน์โหลด bootloaders บุคคลเหล่านี้ที่สามเป็นคณะกรรมการและสามารถทำให้พวกเขา bootloaders เริ่มต้นสำหรับคณะของคุณ bootloaders โดยทั่วไปได้มาจากผู้ผลิตบอร์ดจะถูกแทนที่ด้วย bootloader บุคคลที่สามเหล่านี้ มีไม่กี่ boolader บุคคลที่สามค่อนข้างใช้ได้และบางคนก็เป็นที่มาเปิด (หรือ bootloaders ฟรี) และบางส่วนในเชิงพาณิชย์ บางของพวกเขาเป็น Das U – Boot, boot แดง, GRUB (สำหรับเดสก์ท็), LILO, Loadlin,, loader – bootsect, SYSLINUX, EtherBoot, ELILO

เราจะดำเนินการบูต U – boot เป็นบูตโหลดเดอของเรา U – boot เป็นบูตโหลดใช้กันอย่างแพร่หลายในระบบฝังตัว เราจะอธิบายรหัสจาก U – บูต 2,010.03 แหล่งที่มา คุณสามารถดาวน์โหลด U – boot จากเว็บไซต์ดังต่อไปนี้ http://www.denx.de/wiki/U-Boot

วิธีการ U – boot สร้าง :

ตามการกำหนดค่าของ U – boot, ทุกไฟล์ประกอบ (. S) และไฟล์ C (. ค) เป็นเรียบเรียงโดยใช้คอมไพเลอร์ข้ามซึ่งเป็นที่สร้างขึ้นสำหรับสถาปัตยกรรมโดยเฉพาะและไฟล์วัตถุ (. o) จะมีการสร้าง ทั้งหมดนี้มีการเชื่อมโยงแฟ้มวัตถุโดย linker และแฟ้มที่ปฏิบัติการจะมีการสร้าง ไฟล์วัตถุหรือแฟ้มที่ปฏิบัติการได้คือชุดของ like.text ส่วน. ข้อมูล. BSS ฯลฯ วัตถุไฟล์และแฟ้มที่ปฏิบัติการได้มีรูปแบบไฟล์เช่นเอลฟ์ ทุกส่วนของไฟล์วัตถุจะถูกจัดเรียงอยู่ในแฟ้มที่ปฏิบัติการตามสคริปต์ที่เรียกว่าสคริปต์ linker สคริปต์นี้จะบอกที่ทั้งหมดส่วนใดที่จะโหลดในหน่วยความจำเมื่อทำงาน ทำความเข้าใจเกี่ยวกับสคริปต์นี้เป็นสิ่งสำคัญมากที่จะทราบวิธีการบูตและเมล็ดที่มีองค์ประกอบและวิธีการที่ส่วนต่างๆของบูตโหลดเดอหรือเมล็ดที่มีการโหลดในหน่วยความจำ

โดยทั่วไปเมื่อโปรแกรมถูกเรียกใช้ (รัน) โหลดอ่านแฟ้มที่ปฏิบัติการได้และโหลดส่วนต่างๆของแฟ้มที่ปฏิบัติการในสถานที่ตั้งของหน่วยความจำที่ระบุไว้และเริ่มดำเนินการทำงานเริ่มต้น (จุดเริ่มต้น) ที่ระบุไว้ในสคริปต์ linker แต่ถ้าคุณต้องการเรียก (โหลด) โหลดการบูตจะไม่มีโหลดใด ๆ ที่จะโหลด (โดยทั่วไปจะเข้าใจรูปแบบไฟล์) ส่วนต่างๆของแฟ้มที่ปฏิบัติการในหน่วยความจำ จากนั้นคุณจำเป็นต้องใช้เครื่องมือที่เรียกว่า objcopy ซึ่งจะใช้เวลาส่วนทั้งหมดออกจากแฟ้มที่ปฏิบัติการได้และสร้างแฟ้มไบนารีซึ่งไม่ได้มีรูปแบบไฟล์ใด ๆ นี้แฟ้มไบนารีสามารถโหลดเข้าสู่หน่วยความจำและรันหรือสามารถเขียนในรอมตามที่อยู่ที่เฉพาะเจาะจง (เฉพาะสถาปัตยกรรม) ซึ่งจะถูกดำเนินการโดย CPU เมื่ออำนาจนำมาใช้กับบอร์ด

สมมติว่าขึ้นอยู่กับการกำหนดค่า U – boot ไฟล์ทั้งหมดจะถูกรวบรวมและไฟล์ที่มีการสร้างวัตถุ U Makefile บูตใช้สคริปต์ linker ต่อไปนี้ (เฉพาะสถาปัตยกรรม) เพื่อสร้างแฟ้มที่ปฏิบัติการได้

ไฟล์ : cpu/arm920t/u-boot LDS.

32 OUTPUT_FORMAT ("elf32 – littlearm","elf32 – littlearm","elf32 littlearm -")

33 OUTPUT_ARCH (แขน)

34 รายการ (_start)

35 วรรค

36 {

37 = 0x00000000;

38

39 =จัดชิด (4);

40.text :

41 {

42 cpu/arm920t/start.o (. ข้อความ)

43 * (. ข้อความ)

44}

4546 align = (4);

47.rodata : {* (SORT_BY_ALIGNMENT (SORT_BY_NAME (rodata *)).)}

48

49 align = (4);

50.data : {* (. ข้อมูล)}

51

52 align = (4);

53.got : {* (. ได้)}

54

55 =. ;

56 __u_boot_cmd_start =. ;

57.u_boot_cmd : {* (. u_boot_cmd)}

58 __u_boot_cmd_end =. ;

59

60 align = (4);

61 __bss_start=. ;

62.bss (NOLOAD) : {* (BSS.) align = (4);}

63 _end =. ;

64}

OUTPUT_FORMAT ใน # 32 บรรทัดที่ระบุรูปแบบแฟ้มของแฟ้มที่ปฏิบัติการได้ ต่อไปนี้รูปแบบแฟ้มที่ปฏิบัติการได้เป็น elf32 และ endianness เป็น endian น้อย OUTPUT_ARCH ใน # 33 บรรทัดที่ระบุสถาปัตยกรรมที่รหัสนี้จะทำงาน รายการใน # 34 บรรทัดที่ระบุทำงานเริ่มต้น (จุดเริ่มต้น) ของโปรแกรม U – boot นี่คือจุดเริ่มต้นที่ _start

ส่วนใน # 35 บรรทัดที่กำหนดว่าส่วนที่แตกต่างกันในแมปแฟ้มที่ปฏิบัติการได้ Loader จะใช้ที่อยู่ที่ระบุไว้ในส่วนนี้เพื่อโหลดส่วนที่แตกต่างกันของโปรแกรมในหน่วยความจำ

'.' ใน # 37 บรรทัดที่ระบุที่อยู่เริ่มต้นที่ส่วนต่อไปนี้ควรได้รับการโหลด ในกรณีนี้ที่อยู่เริ่มต้นเป็น 0x00000000 หลังจากนี้ในบรรทัด # 39 หน่วยความจำจะจัดชิดโดย 4 ไบต์และส่วน the.text ดังต่อไปนี้ในบรรทัด # 40

40.text :

41 {

42 cpu/arm920t/start.o (. ข้อความ)

43 * (. ข้อความ)

44}

ที่'.' ตำแหน่ง(0x00000000) รหัสใน cpu/arm920t/start.o เป็นแมปและต่อไปนี้โค้ดที่จะมีส่วน in.text ของวัตถุอื่น ๆ (. o) ไฟล์ cpu/arm920t/start.o มี _start () ฟังก์ชั่น (ในภาษาประกอบ) ซึ่งเป็นจุดเริ่มต้นของโปรแกรมนี้

ตอนนี้'.' จะเป็นที่ 0x00000000 sizeof + (. ข้อความ) หน่วยความจำอีกครั้งจัดชิดโดย 4 ไบต์ส่วน and.rodata ดังต่อไปนี้ในบรรทัด # 47

. align = (4);

47.rodata : {* (SORT_BY_ALIGNMENT (SORT_BY_NAME (rodata *)).)}

ส่วน rodata.จากวัตถ​​ุทั้งหมดที่มีไฟล์แมปที่อยู่นี้ ดังต่อไปนี้ the.data ส่วน and.git

49 align = (4);

50.data : {* (. ข้อมูล)}

51

52 align = (4);

53.got : {* (. ได้)}

แต่ละคำสั่ง U – boot เป็นวัตถุของ'cmd_tbl_t'ชนิดที่มีชื่อคำสั่ง, สตริงช่วยและตัวชี้ฟังก์ชั่นให้รันเมื่อมีการเรียกใช้คำสั่งนี้ ทั้งหมดเหล่านี้วัตถุคำสั่งจะอยู่ในหน่วยความจำตามลำดับ ของวัตถุแต่ละคำสั่งนี้สร้างขึ้นใน U – boot ส่วนที่กำหนดไว้called.u_boot_cmd ในแฟ้มวัตถุ เหล่านี้ส่วน all.u_boot_cmd จะอยู่ในหน่วยความจำหลังส่วนบน (. and.git ข้อมูล)

. =. ;

56 __u_boot_cmd_start =. ;

57.u_boot_cmd : {* (. u_boot_cmd)}

58 __u_boot_cmd_end =. ;

__u_boot_cmd_start มีจุดเริ่มต้นของวัตถุคำสั่งและ __u_boot_cmd_end มีจุดสิ้นสุดของวัตถุคำสั่ง

และถัดไปดังต่อไปนี้ the.bss (ตัวแปรร่วม uninitialized) ส่วน

60 align = (4);

61 __bss_start=. ;

62.bss (NOLOAD) : {* (BSS.) align = (4);}

63 _end =. ;

จุด __bss_start เพื่อ the.bss ที่อยู่เริ่มต้นและจุดสิ้นสุดของ _end มีส่วนทั้งหมด

การใช้สคริปต์นี้ linker linker จะสร้างแฟ้มที่ปฏิบัติการได้เรียกว่า U – boot เครื่องมือ Objcopy จะใช้ในการสร้างแฟ้มไบนารีจาก U – boot แฟ้มที่ปฏิบัติการได้

boot.bin U – : U – boot

$ (OBJCOPY) $ {OBJCFLAGS} – O ไบนารี $

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: