5.1 移植第一步

  前面已经分析过了 .config 的过程,可以知道移植需要用到的文件:

  • .config 文件
  • arch/arm/cpu 下的文件
  • board 目录

  .config 文件是根据后面两个文件生成的,所以我们重点需要配置后面两个目录

5.1.2 移植 board 目录

  JZ2440 是基于 S3C2440 的,为三星架构,我们可以从其他支持 2440 的 uboot 版本中进行移植。

  u-boot自v2014.10版本开始引入KBuild系统,所以我们在 2014.10之后不久的版本中查询版本,这样尽量减少移植时候的差异性

  下载 u-boot 2015.01 版本代码:git clone git://git.denx.de/u-boot.git u-boot

  切换版本:

  git status

  git tag

  git checkout v2015.01

  git diff v2017.01(对比源码,可以不做)

  拷贝board/samsung/smdk2410 到 下面的目录中去

 cp -R smdk2410/ ./uboot/board/samsung/jz2440

  修改文件:

  cd uboot/board/samsung/jz2440

  mv smdk2410.c jz2440.c

  修改 makefile:

 obj-y    := jz2440.o
obj-y += lowlevel_init.o

  jz2440.c 文件修改:

  

  注意:这里之所以把arch number 改为 S3C2440,是因为在 arch/arm/include/asm/mach-types.h 中给我们定义了一个s3c2440 的通用宏,而且在此文件中,已经给我们设置好了:

  

  

  Kconfig 修改:

 if TARGET_JZ2440

 config SYS_BOARD
default "jz2440" config SYS_VENDOR
default "samsung" config SYS_SOC
default "s3c24x0" config SYS_CONFIG_NAME
default "jz2440" endif

  当前目录修改完毕

5.1.3 arch/arm/cpu/arm920t 目录修改

(1)头文件

  ./arch/arm/include/asm/arch-s3c24x0/s3c24x0.h 这个文件是 s3c24x0 芯片的寄存器的 的定义

  ./arch/arm/include/asm/arch-s3c24x0:CPU的一些操作和定义

  jz2440.h 头文件:cp smdk2410.h ../../../uboot/include/configs/jz2440.h

  修改 jz2440.h 文件如下:

  

(2)arch/arm/Kconfig 中添加

  添加

 source "board/samsung/jz2440/Kconfig"

  

  在第 339 行,就是  menuconfig  中目标板的选择项,这这个选项中我们可以添加自己的板子,使其在 menuconfig 中可见

  

  569~573 行添加:

 config TARGET_JZ2440
bool "Samsung S3C24X0"
select CPU_ARM920T
help
The S3C24X0 is deperated,but I want to use it.

  

5.2 生成 .config 文件

  我们通过 make menuconfig 进行配置我们的开发板。或者可以用 uboot 2015 版本中的 smdk2410_defconfig进行配置,可以拷贝进去。

  cp smdk2410_defconfig ../../uboot/configs/jz2440_defconfig

  执行命令 make  jz2440_defconfig

  再执行 make menuconfig 查看配置。适量修改下,编译肯定会出错,出错后再进行修改。

  • ARM architecture:

    • ARM64 system support AArch32 execution state:此选项去掉
    • Use PSCI for reset and shutdown:此选项去掉
    • Target select:目标选择,选择我们定义的开发板 Samsung S3C24X0
  • General setup:
    • 64bit physical address support:去掉此选项
  • delay in seconds before automatically booting:设置为5
  • Device Tree Control:
    • Run-time configuration via Device Tree:关闭掉此项

  主Makefile 中指定一下交叉编译 工具链:

  

  执行 make  编译。

5.3 编译

5.3.1 .config:138:warning: symbol value '' invalid for SYS_TEXT_BASE

  在 .config 中我们没有配置代码段的基地址。先找找这个在原先的 uboot 中配置在哪里。在 include/configs/smdk2410.h 中

  拷贝这个文件进入我们的工程中:cp include/configs/smdk2410.h ../../uboot/include/configs/jz2440.h

  查找下包含文件,进行修改,然后查看 include/configs/jz2440.h 文件,进行 make menuconfig  配置

  将 CONFIG_SYS_TEXT_BASE 在menuconfig  中修改为 0x0

5.3.2 include/configs/jz2440.h:78:32: fatal error: config_cmd_default.h: No such file or directory

  没有这个文件了。注释掉编译

5.3.3 cmd/ubi.c:79:44: error: 'CONFIG_MTD_UBI_WL_THRESHOLD' undeclared (first use in this function); did you mean 'CONFIG_MTD_UBI_BEB_RESERVE'?

  make menuconfig 后,查找此配置宏:

  

  依赖于 MTD_UBI,这个我们是没有开的,这个宏的配置在 Device Drivers--> UBI support-->Enable UBI 下。Enable UBI 没有配置。看看是否有其他地方宏配置了。

  include/configs/jz2440.h 中配置了UBI文件系统,我们将文件系统的配置全部删除掉,保留 YAFFS2 即可。

  

5.3.3 重复定义项

  (1)include/configs/jz2440.h:84:0: warning: "CONFIG_CMD_ELF" redefined

  (2)include/configs/jz2440.h:91:0: warning: "CONFIG_CMDLINE_EDITING" redefined

  (3)include/configs/jz2440.h:110:0: warning: "CONFIG_SYS_LONGHELP" redefined

  (4)include/configs/jz2440.h:111:0: warning: "CONFIG_SYS_PROMPT" redefined

  (5)include/configs/jz2440.h:119:0: warning: "CONFIG_DISPLAY_CPUINFO" redefined

  (6)include/configs/jz2440.h:129:0: warning: "CONFIG_LZMA" redefined

  注释掉或删掉代码中的那几行即可

  不止这几项重复,所有的重复项定义都可以在 include/configs/jz2440.h 中删除,在执行 make menuconfig 的时候,其实都可以配置。

5.3.4 dts/Makefile:27: recipe for target 'arch/arm/dts/unset.dtb' failed

  未配置 DTS,所以是include/configs/jz2440.h 中添加的定义,删除掉

5.3.4 时钟函数未找到

  (1)arch/arm/cpu/arm920t/s3c24x0/cpu_info.c:15:2: error: ‘get_FCLK’ undeclared here (not in a function); did you mean ‘get_dacr’?

  (2)arch/arm/cpu/arm920t/s3c24x0/cpu_info.c:16:2: error: ‘get_HCLK’ undeclared here (not in a function); did you mean ‘get_FCLK’?

  (3)arch/arm/cpu/arm920t/s3c24x0/cpu_info.c:17:2: error: ‘get_PCLK’ undeclared here (not in a function); did you mean ‘get_HCLK’?

  通过文件对比可以知道,这三个函数被定义在 arch/arm/cpu/arm920t/s3c24x0/speed.c 中,但是当前工程版本中未包含这几个函数,在头文件中进行申明添加。

  505-510 行加入

 /* $(CPU)/speed.c */
int get_clocks (void);
ulong get_bus_freq (ulong);
int get_serial_clock(void);
5 #if defined(CONFIG_S3C24X0)
6 ulong get_FCLK(void);
7 ulong get_HCLK(void);
8 ulong get_PCLK(void);
9 ulong get_UCLK(void);
10 #endif

5.3.5 板子适配问题

  board/samsung/jz2440/jz2440.c:100:27: error: ‘MACH_TYPE_JZ2440’ undeclared (first use in this function)

  对比2015版本的代码可以知道是因为 machine_arch_type 没有定义,所以在arch/arm/include/asm/mach-types.h中定义此变量

  文件头加上如下代码:

 #ifndef __ASSEMBLY__
extern unsigned int __machine_arch_type;
#endif

  文件尾加上如下代码:

 #ifdef CONFIG_ARCH_JZ2440
# ifdef machine_arch_type
# undef machine_arch_type
# define machine_arch_type __machine_arch_type
# else
# define machine_arch_type MACH_TYPE_JZ2440
# endif
# define machine_is_jz2440() (machine_arch_type == MACH_TYPE_JZ2440)
#else
# define machine_is_jz2440() ()
#endif

  board/samsung/jz2440/jz2440.c 加上头文件:

#include <asm/mach-types.h>

5.3.6 无此文件和目录

  (1)cmd/reginfo.c:10:10: fatal error: asm/ppc.h: No such file or directory

    #include <asm/ppc.h>

    reginfo.c  是命令文件,打印寄存器的信息,可以在 menuconfig 中的 common line 选项中修改

    带源代码中查找 CONFIG_CMD_REGINFO:

    

    在menuconfig 中 CMD_REGINFO 依赖于 PPC=y,注释掉此项定义。

  (2)cmd/ubi.c: In function ‘display_ubi_info’:

      cmd/ubi.c:79:44: error: ‘CONFIG_MTD_UBI_WL_THRESHOLD’ undeclared (first use in this function)

      cmd/ubi.c:28:54: note: in definition of macro ‘ubi_msg’

      cmd/ubi.c:79:44: note: each undeclared identifier is reported only once for each function it appears in ubi_msg("wear-leveling threshold:    %d", CONFIG_MTD_UBI_WL_THRESHOLD);

      cmd/ubi.c:28:54: note: in definition of macro ‘ubi_msg’ #define ubi_msg(fmt, ...) printf("UBI: " fmt "\n", ##__VA_ARGS__)

    

    README 中的解释,默认值是4096

    

    menuconfig 中没有开 MTD_UBI 则此模块可以注释掉。

    include/configs/jz2440.h 中

    

  (3)cmd/built-in.o: In function `do_fat_fsinfo':

    cmd/fat.c:85: undefined reference to `fat_set_blk_dev'

    cmd/fat.c:90: undefined reference to `file_fat_detectfs'

    追踪代码可以知道 fat_set_blk_dev 和 file_fat_detectfs 都定义在 Fat.c (fs\fat) 中,fat 文件系统我们并没有支持。在 include/configs/jz2440.h 中关闭掉这个命令宏。

    代码第 185 行注释

  (4)drivers/mtd/nand/built-in.o: In function `nand_init_chip':

    drivers/mtd/nand/nand.c:94: undefined reference to `board_nand_init'

    对比代码可以知道,drivers/mtd/nand/s3c2410_nand.c 这个文件在 2018.03 版本中没有,复制进工程中。

    drivers/mtd/nand$ cp s3c2410_nand.c ../../../../../u-boot-2018.03/drivers/mtd/nand/s3c2440_nand.c

    将 s3c2440_nand.c 中的2410 字符串改为 2440

    drivers/mtd/nand/Makefile 中59行添加:

 obj-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o 

    drivers/mtd/nand/Kconfig 中添加:

 config NAND_S3C2440
bool "Support for S3c2440 Nand Controller"
depends on TARGET_JZ2440
imply CMD_NAND
help
This enables Nand driver support for Nand flash contoller
found on S3C2440 Soc.

    修改完成后 需要进入 menuconfig 中添加配置。

  (5)env/built-in.o: In function `env_flash_save':

    env/flash.c:268: undefined reference to `flash_sect_protect'

    env/flash.c:276: undefined reference to `flash_sect_erase'

    env/flash.c:280: undefined reference to `flash_write'

    env/flash.c:303: undefined reference to `flash_sect_protect'

    env/flash.c:298: undefined reference to `flash_perror'

    追踪代码可以知道 CONFIG_MTD_NOR_FLASH 宏未定义,开宏即可

    

5.3.7 规则问题

  (1)make[1]: *** No rule to make target 'arch/arm/dts/unset.dts', needed by 'arch/arm/dts/unset.dtb'.

    Makefile:879: recipe for target 'dts/dt.dtb' failed

    看一下顶层的  Makefile:

    

    这里编译进了 dts ,dts  我们不支持得干掉

    make menuconfig 中,

    Device Tree Control  干掉

    Path to dtc binary for use within mkimage  的值设为空

5.3.8 宏定义问题   

    Error: You must add new CONFIG options using Kconfig
    The following new ad-hoc CONFIG options were detected:
    CONFIG_JZ2440
    CONFIG_NAND_S3C2410
    CONFIG_RTC_S3C24X0
    CONFIG_S3C2410
    CONFIG_S3C24X0
    CONFIG_S3C24X0_SERIAL
    CONFIG_SMDK2410
    CONFIG_SYS_HUSH_PARSER
    CONFIG_SYS_S3C2410_NAND_HWECC
    CONFIG_USB_OHCI_S3C24XX
    CONFIG_ZERO_BOOTDELAY_CHECK

  注释掉顶层  Makefile 中下面几句:

  

  clean 之后编译。

  编译完成,生成了 u-boot.bin.

  

  或者将这些内容直接加入到 scripts/config_whitelist.txt  当中。

  

5.3.8 驱动问题

  (1)cmd/date.c:52:12: warning: implicit declaration of function ‘I2C_GET_BUS’;

  (2)cmd/date.c:53:2: warning: implicit declaration of function ‘I2C_SET_BUS’;

  (3)cmd/date.c:53:14: error: ‘CONFIG_SYS_RTC_BUS_NUM’ undeclared

   函数问题是因为 CONFIG_DM_I2C_COMPAT 未定义,即 I2C 模块未开启,若是开启了 CONFIG_SYS_I2C 或是 CONFIG_DM_RTC 则不会走那个分支

   我们直接关掉 CONFIG_DM_I2C 模块 

  (4)drivers/spi/built-in.o: In function `dev_read_u32_default'

    DM 模块问题,关掉 DM 模块。    

  (5)rivers/serial/serial.c:379: undefined reference to `default_serial_console'

    对比代码可以知道,缺少serial_s3c24x0.c文件,拷贝进去,并修改 Makefile

    drivers/serial$ cp serial_s3c24x0.c ../../../../u-boot-2018.03/drivers/serial/

    

    修改完成,已经可以编译出完整的 u-boot.bin 文件了。后续再做代码分析和移植的时候,有些东西还需要修改

    当前的 .bin 文件是过大的,接近350K

    

6. 第一次裁剪后的 jz2440.h 文件

/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
* Gary Jennejohn <garyj@denx.de>
* David Mueller <d.mueller@elsoft.ch>
*
* Configuation settings for the SAMSUNG SMDK2410 board.
*
* SPDX-License-Identifier: GPL-2.0+
*/ #ifndef __CONFIG_H
#define __CONFIG_H /*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_S3C24X0 /* This is a SAMSUNG S3C24x0-type SoC */
#define CONFIG_S3C2440 #define CONFIG_SYS_TEXT_BASE 0x0 #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH /* input clock of PLL (the SMDK2410 has 12MHz input clock) */
#define CONFIG_SYS_CLK_FREQ 12000000 #define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG /*
* Hardware drivers
*/
#define CONFIG_CS8900 /* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE 0x19000300
#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */ /*
* select serial console configuration
*/
#if 0
#define CONFIG_S3C24X0_SERIAL
#endif
#define CONFIG_SERIAL1 1 /* we use SERIAL 1 on SMDK2410 */ /************************************************************
* USB support (currently only works with D-cache off)
************************************************************/
#define CONFIG_USB_OHCI /************************************************************
* RTC
************************************************************/ #define CONFIG_BAUDRATE 115200 /*
* BOOTP options
*/
#define CONFIG_BOOTP_BOOTFILESIZE
#define CONFIG_BOOTP_BOOTPATH
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME /*
* Command line configuration.
*/ #define CONFIG_CMD_BSP
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_PING
#define CONFIG_CMD_REGINFO
#define CONFIG_CMDLINE_EDITING /* autoboot */
#define CONFIG_BOOT_RETRY_TIME -1
#define CONFIG_RESET_TO_RETRY
#if 0
#define CONFIG_ZERO_BOOTDELAY_CHECK
#endif #define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 10.0.0.110
#define CONFIG_SERVERIP 10.0.0.1 #if defined(CONFIG_CMD_KGDB)
#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
#endif /*
* Miscellaneous configurable options
*/
#define CONFIG_SYS_LONGHELP /* undef to save memory */
#define CONFIG_SYS_CBSIZE 256
/* Print Buffer Size */
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
sizeof(CONFIG_SYS_PROMPT)+)
#define CONFIG_SYS_MAXARGS 16
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE #define CONFIG_SYS_MEMTEST_START 0x30000000 /* memtest works on */
#define CONFIG_SYS_MEMTEST_END 0x33F00000 /* 63 MB in DRAM */ #define CONFIG_SYS_LOAD_ADDR 0x30800000 /* support additional compression methods */
#define CONFIG_BZIP2
#define CONFIG_LZO
#define CONFIG_LZMA /*-----------------------------------------------------------------------
* Physical Memory Map
*/
#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */ #define PHYS_FLASH_1 0x00000000 /* Flash Bank #0 */ #define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1 /*-----------------------------------------------------------------------
* FLASH and environment organization
*/ #define CONFIG_SYS_FLASH_CFI
#define CONFIG_FLASH_CFI_DRIVER
#define CONFIG_FLASH_CFI_LEGACY
#define CONFIG_SYS_FLASH_LEGACY_512Kx16
#define CONFIG_FLASH_SHOW_PROGRESS 45 #define CONFIG_SYS_MAX_FLASH_BANKS 1
#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
#define CONFIG_SYS_MAX_FLASH_SECT (19) #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000)
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE 0x10000
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE /*
* Size of malloc() pool
* BZIP2 / LZO / LZMA need a lot of RAM
*/
#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) #define CONFIG_SYS_MONITOR_LEN (448 * 1024)
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE /*
* NAND configuration
*/ /*
* File system
*/
#if 0
#define CONFIG_YAFFS2
#endif /* additions for new relocation code, must be added to all boards */
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - \
GENERATED_GBL_DATA_SIZE) #define CONFIG_BOARD_EARLY_INIT_F #endif /* __CONFIG_H */

    

      

  

  

  

  

  

  

四、移植 JZ2440 开发板的更多相关文章

  1. Linux学习 :移植U-boot_2016.09到JZ2440开发板

    一.下载源码:ftp://ftp.denx.de/pub/u-boot/ 二.初始化编译: ①新建一个单板: cd board/samsung/ cp smdk2410 smdk2440 -rf   ...

  2. Linux学习 :移植U-boot_2012.04.01到JZ2440开发板

    一.下载U-boot源码:ftp://ftp.denx.de/pub/u-boot/ 二.uboot的启动过程: 部分硬件初始化——>加载完整uboot到RAM——>跳转到第二阶段入口开始 ...

  3. 三星四核RP4412开发板的root问题

    问:荣品四核RP4412开发板的板子是root权限吗? 或者怎么root? 答:su . android 我们提供的是root用户 问:root以后的授权管理器没法运行. 我需要root,我要在and ...

  4. 基于JZ2440开发板编写bootloader总结(一)

    凡走过必留下痕迹,学点什么都会有用的. 本系列博文总结了自己在学习嵌入式Linux编程过程中的收获,若有错误,恳请指正,谢谢! --参考教材韦东山系列教材 bootloader 是一个用于启动linu ...

  5. Jz2440开发板熟悉

    title: Jz2440开发板熟悉 tags: ARM date: 2018-10-14 15:05:56 --- 概述 外部晶振为12M Nand Flash 256M,Nor Flash 2M, ...

  6. JZ2440开发板:UART(串口)使用(学习笔记)

    查看UART在硬件上的信息,阅读JZ2440原理图可以看到: JZ2440开发板的UART0是可以跟USB相接的,用于打印调试,UART1,UART2两个串口用来外接模块.所以本文仅对UART0进行操 ...

  7. JZ2440开发板:修改ARM芯片时钟(学习笔记)

    想要修改ARM芯片的时钟,需要去查询芯片手册和原理图,获取相关的信息(见下方图片) 首先来看时钟的结构图 根据结构图可以看出,时钟源有两种选择:1. XTIpll和XTOpll所连接的晶振 2. EX ...

  8. JZ2440开发板:用按键点亮LED灯(学习笔记)

    本文是对韦东山嵌入式第一期学习的记录之一,如有您需要查找的信息,可以继续往下阅读. 想要用按键点亮LED灯,就需要知道按键和LED灯的相关信息,这样才可以进行之后的操作.阅读JZ2440的原理图,可以 ...

  9. 【转】Vsftpd-3.0.2服务器arm-linux移植—mini2440开发板

    Vsftpd-3.0.2服务器arm-linux移植—mini2440开发板 开发板:mini2440(2011.04.21)环境:ubuntu9.10 为方便的将文件上传到开发板,采用vsftpd, ...

随机推荐

  1. php开发APP接口(总结一)

    一.什么是app接口:服务端与客户端的数据交互. 大部分APP接口是通过http协议通信的. http通信的三要素: URL:   通信的地址 Method:通信的方式(get | post | pu ...

  2. Oracle面试题(基础篇)

    1. Oracle跟SQL Server 2005的区别? 宏观上: 1). 最大的区别在于平台,oracle可以运行在不同的平台上,sql server只能运行在windows平台上,由于windo ...

  3. 黄金Corner

    春水初生 春林初盛 春风十里 你在哪里

  4. 好消息,Manjaro Linux 18 已正式发布!

    导读 Manjaro Linux 18 已正式发布!Xfce 版本仍然是旗舰,Manjaro 为其提供了优雅且领先的集成体验.这一版本搭载 Xfce 4.13. 这一版本主要专注于在桌面和窗口管理器上 ...

  5. linux-shell系列8 netstat用法

    1 查看TCP连接状态 netstat -n|awk '{print $6}'|sort|uniq -c|sort -rn netstat -n|awk '/^tcp/ {++S[$NF]};END{ ...

  6. BZOJ2006[NOI2010]超级钢琴——堆+主席树

    题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中 ...

  7. BZOJ3028 食物(生成函数)

    显然构造出生成函数:则有f(x)=(1+x2+x4+……)·(1+x)·(1+x+x2)·(x+x3+x5+……)·(1+x4+x8+……)·(1+x+x2+x3)·(1+x)·(1+x3+x6+…… ...

  8. ACG图片站\python爬虫\LAMP环境

    最近突然对web很感兴趣,碰巧看到阿里云服务器学生价十块钱一个月,果断买了一个自己搭建了一个网站. 网址 这里 LAMP环境就搭建了好久,linux+apache2+mysql+php,都是开源的软件 ...

  9. MVC WebApi 图片上传和显示

    1 MVC中显示 内存流 中的图片.(不是图片文件) 创建一个Index用来显示 Action: public ActionResult Index() { return View(); } csht ...

  10. hdu 6393 Traffic Network in Numazu (树链剖分+线段树 基环树)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6393 思路:n个点,n条边,也就是基环树..因为只有一个环,我们可以把这个环断开,建一个新的点n+1与之相 ...